한 구조물을 다른 구조물에 복사
구조 구성원을 회원별로 복사할 수 있다는 것을 알고 있으며, 대신 다음 작업을 수행할 수 있다.memcpy
구조물에 대해 어떻게 생각해?
그렇게 하는 것이 바람직한가?
내 구조에는 같은 구성원을 가진 다른 구조물에 복사해야 하는 끈도 있다.그걸 어떻게 하는 거죠?
평이한 임무에 의한 복사는 짧고 읽기 쉬우며 추상화 수준이 높기 때문에 가장 좋다.(코드의 인간 독자에게) "이 비트를 여기서 저기로 복사"하고, 독자가 크기 인수에 대해 사본에 대해 생각하도록 요구하는 대신, 당신은 그냥 평이한 과제("여기서 여기까지 이 값을 복사")를 하는 것이다.사이즈가 맞는지 아닌지 망설일 게 없다.
또한, 구조물이 심하게 패딩된 경우, 할당하면 컴파일러가 패딩을 복사하지 않아도 되기 때문에(그리고 패딩이 어디에 있는지 알고 있기 때문에) 컴파일러가 보다 효율적인 무언가를 방출할 수 있다.mempcy()
그렇게 하지 않기 때문에 복사하라고 하는 정확한 바이트 수를 항상 복사한다.
문자열이 실제 배열인 경우:
struct {
char string[32];
size_t len;
} a, b;
strcpy(a.string, "hello");
a.len = strlen(a.string);
그러면 일반 할당을 계속 사용할 수 있다.
b = a;
완전한 복사본을 얻기 위해서.그러나 이렇게 모델링된 가변 길이 데이터의 경우, 전체 배열이 항상 복사되기 때문에 복사를 수행하는 가장 효율적인 방법은 아니다.
그러나 힙할당 메모리에 포인터가 포함된 구조물을 복사하는 것은 약간 위험할 수 있으므로, 그렇게 함으로써 포인터를 앨리어싱하고 복사 작업 후 포인터를 소유한 사람이 모호해질 수 있으므로 주의하십시오.
이러한 상황에서 "딥 카피"만이 정말 유일한 선택이며, 그것은 기능적으로 이루어져야 한다.
C90부터는 다음을 간단히 사용할 수 있다.
dest_struct = source_struct;
문자열이 배열 내에서 기억되는 경우:
struct xxx {
char theString[100];
};
그렇지 않으면 포인터라면 손으로 베껴야 할 것이다.
struct xxx {
char* theString;
};
dest_struct = source_struct;
dest_struct.theString = malloc(strlen(source_struct.theString) + 1);
strcpy(dest_struct.theString, source_struct.theString);
구조물이 호환 가능한 유형인 경우, 예, 다음과 같은 것으로 할 수 있다.
memcpy (dest_struct, source_struct, sizeof (*dest_struct));
당신이 알아야 할 것은 이것이 얕은 사본이라는 것이다.다시 말해서, 만약 당신이 만약 당신이 그것을 가지고 있다면.char *
특정 문자열을 가리키면 두 구조물이 동일한 문자열을 가리킨다.
그리고 이러한 문자열 필드 중 하나(데이터)의 내용을 변경하십시오.char *
을 가리키지 않고 가리키다.char *
그 자체)는 다른 것도 변화시킬 것이다.
각 필드를 수동으로 수행할 필요 없이 공유되지 않는 문자열 복사본이 추가된 쉬운 복사본을 원할 경우strdup
:
memcpy (dest_struct, source_struct, sizeof (*dest_struct));
dest_struct->strptr = strdup (source_struct->strptr);
이렇게 하면 구조물의 전체 내용을 복사한 다음 문자열을 깊게 복사하여 각 구조물에 별도의 문자열을 효과적으로 부여할 수 있다.
그리고, C 구현에 다음이 없는 경우strdup
(ISO 표준의 일부가 아니므로 여기에서 하나를 가져오십시오.
넌 할 수 있다.memcpy
구조체 또는 다른 값과 마찬가지로 구조체를 지정할 수 있다.
struct {int a, b;} c, d;
c.a = c.b = 10;
d = c;
C에서 memcpy는 어리석게도 위험할 뿐이다.세 가지 매개변수를 모두 정확히 맞추기만 하면, 구조 구성원들 중 어느 것도 포인터가 되지 않고(또는 당신은 분명히 얕은 복사를 하려는 의도) memcpy가 루핑을 통해 시간을 낭비할(또는 성능은 중요하지 않음) 구조에는 큰 정렬 공백이 없으며, 그 다음에는 어떤 수단을 써서라도 memcpy가 된다.읽기 더 어렵고, 미래의 변화에 취약하며, 코드 리뷰에서 손으로 검증해야 하는 코드 외에는 아무것도 얻지 못하지만( 컴파일러가 할 수 없기 때문) 야, 그래 왜 안 되겠어.
C++에서는 터무니없이 위험한 것으로 발전한다.당신은 std::string과 같이 안전하게 기억될 수 없는 타입의 멤버가 있을 수 있는데, 이것은 당신의 수신 구조물을 위험한 무기가 되게 하며, 사용할 때마다 무작위로 기억을 손상시킨다.슬라이스 카피를 에뮬레이션할 때 가상 기능과 관련된 놀라운 결과를 얻을 수 있다.컴파일할 때 완전한 유형의 지식을 보장받기 때문에 놀라운 일을 할 수 있는 옵티마이저는 당신의 memcpy 호출에 대해 아무것도 할 수 없다.
C++에는 엄지손가락의 법칙이 있다. memcpy나 memset을 보면 뭔가 잘못되었다.이것이 사실이 아닌 경우는 드물지만, 구조체를 수반하지 않는 경우도 있다.당신은 바이트를 맹목적으로 복사할 이유가 있을 때에만 memcpy를 사용한다.
반면에 할당은 읽기 간단하고 컴파일 시간에 정확성을 점검한 다음 런타임에 지능적으로 값을 이동시킨다.단점이 없다.
다음 솔루션을 사용하여 목표를 달성할 수 있다.
struct student
{
char name[20];
char country[20];
};
void main()
{
struct student S={"Wolverine","America"};
struct student X;
X=S;
printf("%s%s",X.name,X.country);
}
구조체를 사용하여 파일에 쓰기를 읽을 수 있다.당신은 그것을 'char*'로 캐스팅할 필요가 없다.구조체 규모도 보존된다.(이 점은 주제에 가장 가까운 것이 아니라 추측한다: 하드 메모리에서 동작하는 것은 종종 RAM 1과 비슷하다.)
단일 문자열 필드를 이동(>에서)하려면
strncpy
및 과도 문자열 버퍼'\0'
종착의레코드 문자열 필드의 길이를 기억해야 하는 곳.다른 필드를 이동하려면 점 표기법을 사용하십시오(예:
NodeB->one=intvar;
floatvar2=(NodeA->insidebisnode_subvar).myfl;
struct mynode { int one; int two; char txt3[3]; struct{char txt2[6];}txt2fi; struct insidenode{ char txt[8]; long int myl; void * mypointer; size_t myst; long long myll; } insidenode_subvar; struct insidebisnode{ float myfl; } insidebisnode_subvar; } mynode_subvar; typedef struct mynode* Node; ...(main) Node NodeA=malloc... Node NodeB=malloc...
당신은 각각의 끈을 그것에 맞는 구조물에 삽입할 수 있고, 2번 지점을 피하고, 코볼처럼 행동할 수 있다.
NodeB->txt2fi=NodeA->txt2fi
...하지만 당신은 여전히 일시적인 끈과 하나가 필요할 것이다.strncpy
에 대해 2번 지점에서 언급한 바와 같이.scanf
,printf
그렇지 않으면 작업자가 긴 입력(입력)을 잘리지 않았을 것이다(공백 패딩).(NodeB->insidenode_subvar).mypointer=(NodeA->insidenode_subvar).mypointer
포인터 별칭을 만들 것이다.NodeB.txt3=NodeA.txt3
컴파일러가 다음을 거부하도록 한다.error: incompatible types when assigning to type ‘char[3]’ from type ‘char *’
포인트-4는 오직 이유 때문에 작동한다.
NodeB->txt2fi
&NodeA->txt2fi
동일에 속하다typedef
!!C에서 찾은 이 주제에 대한 정확하고 간단한 답변, 선언된 문자열에 문자열을 할당할 수 없는 이유"C에서는 (또한) 아람은 2등 시민이다"!!!
참조URL: https://stackoverflow.com/questions/4931123/copying-one-structure-to-another
'programing' 카테고리의 다른 글
vuex를 사용하여 데이터 업데이트 (0) | 2022.04.27 |
---|---|
C 매크로는 무엇에 유용한가? (0) | 2022.04.27 |
상속과 구성의 차이 (0) | 2022.04.27 |
C의 함수에서 여러 값을 반환하려면 어떻게 해야 하는가? (0) | 2022.04.27 |
프로그래밍 방식으로 생성된 vuejs 구성 요소 인스턴스에 슬롯을 전달하는 방법 (0) | 2022.04.27 |