C에서 한 구조체를 다른 구조체에 할당
구조체 인스턴스(instance)를 다른 인스턴스(instance)에 다음과 같이 할당할 수 있는가?
struct Test t1;
struct Test t2;
t2 = t1;
간단한 구조에도 효과가 있는 걸 봤는데, 복잡한 구조에도 효과가 있을까?
컴파일러가 데이터 항목을 복사하는 방법(즉, 데이터 항목을 구분하는 방법)을 어떻게 알고 있는가?int
그리고 끈은?
구조가 같은 유형인 경우 그렇다.기억 복사라고 생각해.
예, 구조체에 대한 할당이 지원됨.그러나 다음과 같은 문제가 있다.
struct S {
char * p;
};
struct S s1, s2;
s1.p = malloc(100);
s2 = s1;
이제 두 구조체의 포인터는 동일한 메모리 블록을 가리키며, 컴파일러는 포인트가 데이터에 복사되지 않는다.어느 구조체 인스턴스가 데이터를 소유하고 있는지 아는 것은 이제 어렵다.이것이 C++가 사용자 정의 가능 할당 연산자의 개념을 발명한 이유다 - 당신은 이 사건을 다루기 위해 특정한 코드를 쓸 수 있다.
먼저 다음 예를 보십시오.
단순 C 프로그램의 C 코드는 다음과 같다.
struct Foo {
char a;
int b;
double c;
} foo1, foo2;
void foo_assign(void)
{
foo1 = foo2;
}
int main(/*char *argv[],int argc*/)
{
foo_assign();
return 0;
}
foo_assign()에 대한 등가 ASM 코드는
00401050 <_foo_assign>:
401050: 55 push %ebp
401051: 89 e5 mov %esp,%ebp
401053: a1 20 20 40 00 mov 0x402020,%eax
401058: a3 30 20 40 00 mov %eax,0x402030
40105d: a1 24 20 40 00 mov 0x402024,%eax
401062: a3 34 20 40 00 mov %eax,0x402034
401067: a1 28 20 40 00 mov 0x402028,%eax
40106c: a3 38 20 40 00 mov %eax,0x402038
401071: a1 2c 20 40 00 mov 0x40202c,%eax
401076: a3 3c 20 40 00 mov %eax,0x40203c
40107b: 5d pop %ebp
40107c: c3 ret
할당 작업이 단순히 조립의 "동영상" 명령으로 대체된다는 것을 알 수 있듯이, 할당 연산자는 단순히 데이터를 메모리 위치 간에 이동시키는 것을 의미한다.이 할당은 구조물의 직접 구성원에 대해서만 수행되며 구조물에 복합 데이터 유형이 있을 때 복사하지 못한다.여기서 COMPLEX는 목록을 가리키는 포인터 배열을 가질 수 없다는 것을 의미한다.
구조 내의 문자 배열은 그 자체로 대부분의 컴파일러에서 작동하지 않을 것이다. 이것은 할당제가 데이터 형식을 복잡한 유형으로 보지 않고 복사를 시도하기 때문이다.
이건 간단한 카피야, 네가 할 수 있는 것처럼.memcpy()
(1998년, 일부 컴파일러는 실제로 다음과 같은 전화를 한다.memcpy()
해당 코드에 대해).C에는 "끈"이 없고, 단지 한 자루 뭉치의 포인터일 뿐이다.소스 구조에 이러한 포인터가 포함되어 있으면 포인터가 복사되고, 문자 자체가 복사되지 않는다.
실제 부품과 가상 부품이 있는 복잡한 숫자로 "복잡함"을 말한 겁니까?그렇지 않다면, "복잡함"은 C 언어에 있어서 특별한 의미를 갖지 않기 때문에 예를 들어봐야 할 것이다.
당신은 구조의 직접 메모리 복사본을 얻을 것이다; 그것이 당신이 원하는 것인지 아닌지는 구조에 달려있다.예를 들어, 구조물에 포인터가 포함되어 있는 경우, 두 복사본은 동일한 데이터를 가리킨다.이것은 당신이 원하는 것일 수도 있고 아닐 수도 있다; 그것은 당신의 프로그램 설계에 달려있다.
'스마트' 카피(또는 '딥' 카피)를 수행하려면 카피를 수행하는 기능을 구현해야 한다.구조 자체가 포인터와 포인터, 그리고 어쩌면 그런 구조물에 대한 포인터(아마도 '복잡함'이라는 뜻일 것이다)를 포함하고 있고, 유지하기도 어려운 구조라면 이것은 달성하기가 매우 어려울 수 있다.간단한 해결책은 C++를 사용하고 각 구조나 계층에 대해 카피 생성자와 할당 연산자를 구현한 다음, 각자가 자신의 카피 의미론을 책임지게 되고, 할당 구문을 사용할 수 있으며, 보다 쉽게 유지된다.
예, 간단한 할당 문을 사용하여 구조체의 한 인스턴스를 다른 인스턴스에 할당할 수 있다.
구조체 멤버를 포함하는 비점퍼 또는 비점퍼의 경우, 할당이란 복사를 의미한다.
포인터 구조 구성원의 경우, 할당이란 포인터가 다른 포인터와 동일한 주소를 가리킨다는 것을 의미한다.
이것을 직접 봅시다:
#include <stdio.h>
struct Test{
int foo;
char *bar;
};
int main(){
struct Test t1;
struct Test t2;
t1.foo = 1;
t1.bar = malloc(100 * sizeof(char));
strcpy(t1.bar, "t1 bar value");
t2.foo = 2;
t2.bar = malloc(100 * sizeof(char));
strcpy(t2.bar, "t2 bar value");
printf("t2 foo and bar before copy: %d %s\n", t2.foo, t2.bar);
t2 = t1;// <---- ASSIGNMENT
printf("t2 foo and bar after copy: %d %s\n", t2.foo, t2.bar);
//The following 3 lines of code demonstrate that foo is deep copied and bar is shallow copied
strcpy(t1.bar, "t1 bar value changed");
t1.foo = 3;
printf("t2 foo and bar after t1 is altered: %d %s\n", t2.foo, t2.bar);
return 0;
}
참조URL: https://stackoverflow.com/questions/2302351/assign-one-struct-to-another-in-c
'IT이야기' 카테고리의 다른 글
공리를 부르는 곳.Vue.js 앱에서 사용되는 인터셉터.request.use? (0) | 2022.05.21 |
---|---|
Vue.js: 'prop' 변경에 따라 'data'를 다시 계산하고 다시 렌더링하십시오.이게 더 좋은 방법인가? (0) | 2022.05.21 |
스트림에서 Java 8의 옵션 사용::flatMap (0) | 2022.05.20 |
도넛 차트.js의 vue 성분 중첩 텍스트 (0) | 2022.05.20 |
v-if를 사용하여 vuex를 통해 단락을 숨기는 방법 (0) | 2022.05.20 |