programing

memcpy 또는 memmove가 dest와 다른 포인터를 반환할 수 있습니까?

linuxpc 2023. 8. 19. 09:55
반응형

memcpy 또는 memmove가 dest와 다른 포인터를 반환할 수 있습니까?

함수memmove다음과 같이 정의됩니다.

void *memmove(void *dest, const void *src, size_t n);

Linux 매뉴얼 페이지에는 다음과 같이 표시됩니다.

반환 값
memmove() 함수는 포인터를 dest로 반환합니다.

함수가 다음과 같이 정의되지 않는 이유는 무엇입니까?void memmove(…)항상 입력 매개 변수 중 하나를 반환할 때?반환 값이 다음과 다를 수 있습니까?dest?

또는 반환 값이 정말 항상입니까?dest그리고 그것은 단지 어떤 창의적인 방법으로 기능을 구성할 수 있는 것입니까?

memmove이외의 것은 절대 반환하지 않을 것입니다.dest.

돌아오는dest만드는 것과는 반대로memmovevoid는 첫 번째 인수가 계산식일 때 유용합니다. 동일한 값을 미리 계산하여 변수에 저장하는 것을 피할 수 있기 때문입니다.이를 통해 한 줄로 작업을 수행할 수 있습니다.

void *dest = memmove(&buf[offset] + copiedSoFar, src + offset, sizeof(buf)-offset-copiedSoFar);

두 줄에 대해 수행해야 하는 작업:

void *dest = &buf[offset] + copiedSoFar;
memmove(dest, src + offset, sizeof(buf)-offset-copiedSoFar);

에 따라C11§ 7.24.2.1 및 § 7.24.2.2장

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

[...] 그memcpy함수는 다음 값을 반환합니다.s1.

그리고.

void *memmove(void *s1, const void *s2, size_t n);

[...] 그memmove함수는 다음 값을 반환합니다.s1.

따라서 함수는 항상 포인터를 대상 버퍼로 반환합니다. 즉, 의도적으로 반환됩니다.

이제 왜 그런지 설명하자면, 많은 기능들이 함수 호출의 체인을 가능하게 하기 위해 이러한 방식으로 설계되었습니다.그렇게 하면, 당신은 전화를 걸 수 있습니다.memmove()복사된 값(즉, 에 대한 포인터)이 사용될 다른 함수에 대한 인수로 사용됩니다.

예를 들어, 당신은 더 짧은 것을 쓸 수 있습니다.

 puts(memmove(dest_buffer, src_buffer, welcome_message_size));

긴 것 대신에

 memmove(dest_buffer, src_buffer, welcome_message_size);
 puts(dest_buffer);

(포인터 유형의) 인수 중 하나의 정확한 값을 반환하는 관용구는 "연쇄된" 함수 호출을 지원하기 위해 존재합니다(참고).strcpy,strcat등). 이를 통해 반복 코드를 여러 개의 문으로 분할하는 대신 단일 식 문으로 작성할 수 있습니다.예를들면

char buffer[1024];
printf("%s\n", strcat(strcat(strcpy(buffer, "Hello"), " "), "World"));

struct UserData data_copy;
some_function(memcpy(&data_copy, &original_data, sizeof original_data));

이러한 유형의 구성 코드를 좋아하지 않고 여러 문을 통해 동일한 작업을 수행하는 것을 선호하더라도 [불필요] 포인터 값을 반환하는 오버헤드는 사실상 없습니다.

C99에서 복합 리터럴이 도입된 후 이 관용어의 가치가 다소 높아졌다고 말할 수 있을 정도입니다.복합적인 측면에서 이 관용구는 명명된 중간 변수를 도입하지 않고 동일한 코드를 작성할 수 있게 합니다.

printf("%s\n", strcat(strcat(strcpy((char [1024]) { 0 }, "Hello"), " "), "World!"));

some_function(memcpy(&(struct UserData) { 0 }, &original_data, sizeof original_data));

대부분의 경우 명명된 변수는 수명이 짧아야 하며 이후에는 필요하지 않고 네임스페이스만 혼란스럽게 만들기 때문에 의미가 있습니다.

언급URL : https://stackoverflow.com/questions/39999903/can-memcpy-or-memmove-return-a-different-pointer-than-dest

반응형