2013-07-27 3 views
4

C 포인터 문학으로 C 기술을 연마 할 때이 코드를 발견했습니다. 이 문제에서는 출력을 정당화해야합니다. 나는 strcat()strcmp()의 일에 익숙하다. 나는 strcmp()이 두 문자열이 통과 할 때 0을 반환한다는 것을 알고 있습니다.strcmp() 및 strcat() 시퀀스

# include <stdio.h> 
# include <string.h> 
int main() 
{ 
    static char str1[]="Good"; 
    static char str2[20]; 
    static char str3[20] ="Day"; 

    int l;  

    l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good")); 

    printf("%d\n", l); 
    return 0; 
} 

제공된 대답은 0이며, 이는 계산 된 두 개의 문자열이 동일해야 함을 의미합니다. 저는 여러 단계로 문장을 풀려고했습니다.

먼저 strcat(str3, strcpy(str2, str1))을 시도했습니다. 'str2'가 'Good'으로 변경되면 strcat()str3을 'DayGood'로 변경합니다. 내 gcc 컴파일러는 지금까지 나와 동의합니다. STR3 이미 DayGood로 변경 되었기 때문에

strcat(str3, "good") 오는, strcatDayGoodgood-str3을 변경합니다.

다시 gcc가 나와 함께 agress.

int main() 
{ 
    static char str1[]="Good"; 
    static char str2[20]; 
    static char str3[20] ="Day"; 

    int l; 
    printf("%s\n", strcat(str3, strcpy(str2, str1))); 
    printf("%s\n", strcat(str3, "good"));  

    //l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good")); 

    //printf("%d\n", l); 
    return 0; 
} 

내가 다시 변화를 시도

DayGood 

DayGoodgood 

생산하고 있습니다.

int main() 
{ 
    static char str1[]="Good"; 
    static char str2[20]; 
    static char str3[20] ="Day"; 

    int l; 

    printf("%s\n", strcat(str3, "good")); 
    printf("%s\n", strcat(str3, strcpy(str2, str1))); 

    //l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good")); 

    //printf("%d\n", l); 
    return 0; 
} 

생성합니다.

Daygood 
DaygoodGood 

두 경우 모두 비교를 위해 두 개의 다른 문자열을 얻습니다. 왜 strcmp()은 0을 생성합니까?

+3

모든 종류의 미정도 및 지정되지 않은 모든 동작이 여기 저기에 있어도 안됩니다. –

+2

정의되지 않은 것이 있는지 확실하지 않습니다. 'str3'의 최종 내용은 불특정 평가 순서에 의존적 일 수 있습니다. 그러나 알 수없는 순서의 함수 호출은'x = x ++'만큼 나쁘지 않습니다. 가능한 순서 중 하나가 오버플로 될 것 같지 않습니다. 완충기. 중요한 사실은'str3'은 결국 그 자체와 동일하다는 것입니다. –

+0

@ WumpusQ.Wumbley'str3'의 내용은 시퀀스 포인트 사이에서 두 번 이상 수정됩니다. –

답변

3

모든 통화를 추적하지 않고 답변을 얻을 수있는 빠른 방법있다 다음 strcat에 두 인수는 첫 번째 인수 str3strcpy의에서 반환하고, strcpy은 첫 번째 인수를 반환하기 때문에, 즉 최종 호출이 strcmp(str3, str3) 의미는 아무리 이상한 조작이 이루어졌다하더라도 0이됩니다.

업데이트 된 질문에 대한 응답이 시도하고 당신이 깨달음을 얻을 수 있는지 : 컴파일러를 주문하든

#include <stdio.h> 
#include <string.h> 
int main(void) 
{ 
    static char str1[]="Good"; 
    static char str2[20]; 
    static char str3[20] ="Day"; 
    char *first, *second; 

    printf("str3 = %p => %s\n", (void *)str3, str3); 

    first = strcat(str3, strcpy(str2, str1)); 
    printf("first strcat returned %p => %s\n", (void *)first, first); 
    printf("and now str3 = %p => %s\n", (void *)str3, str3); 

    second = strcat(str3, "good"); 
    printf("second strcat returned %p => %s\n", (void *)second, second); 
    printf("and now first = %p => %s\n", (void *)first, first); 
    printf("and now str3 = %p => %s\n", (void *)str3, str3); 

    printf("Is it any surprise that strcmp(first,second) = %d?\n", 
     strcmp(first,second)); 
    return 0; 
} 
+0

그래서 마지막으로 str3, str3을 비교해 보겠습니다. 마지막으로 str3에 대한 모든 수정이 끝나면 str3은 메모리의 같은 위치를 가리 킵니다. strcmp ("DayGood", "DayGoodgood")가 아닌 strcmp (str3, str3)입니다. ? – Paras

+0

'str3'은 포인터가 아니므로 아무 것도 가리 키지 않습니다. 그것은 배열입니다. 그리고 C의 모든 객체와 마찬가지로 배열의 주소는 수명 동안 상수입니다. –

+0

확인. 나는 그것을 놓쳤다. – Paras

3

strcmp에 인수를 계산하기 위해 선택, strcat는 항상 첫 번째 인수를 반환합니다. 본질적으로 따라서

여기 무슨 일이야 :

strcat(str3, strcpy(str2, str1)) 

strcat(str3, "good") 

실제로 같은 일 반환 : 할당 된 메모리 주소를

... // execute strcat(str3, strcpy(str2, str1)) and strcat(str3, "good") 
l = strcmp(str3, str3); 
2

그것은 0을 반환 두 매개 변수 때문에 ~ str3. 따라서 strcmp는 변수 str3을 자체와 비교하기 때문에 0을 반환합니다.

0

strcat은 첫 번째 arg를 반환합니다.

+2

아니요,'strcat'는 포인터가 아니라 첫 번째 인수를 반환합니다. 'strcat'의 첫번째 인수는 포인터이고'strcat'는 그것을 반환합니다. –

+0

예, 죄송합니다. 나는 그것을 의미했다. – user2553780

1

strcat이 항상 전달 된 첫 번째 인수를 반환한다는 사실은 항상 사용자의 표현을 true로 만듭니다. 자체에 변수를 비교하여

strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good")); 
//   ^^^^        ^^^^ 

// become 

strcmp(str3, str3); 

그래서 strcmp 반환 0 : 여기 설명이다.

당신은

1

을 strcmp는 문자열 두 개의 포인터를 얻을 수 ... 그것은 코드가 덜 이해하게하고 빠르게 당신이 상상할 수있는 것보다 정의되지 않은 동작이 발생할 수 있기 때문에 표현의이 종류는 아주 좋은 아니라는 것을 알아야한다

l = strcmp(strcat(str3, strcpy(str2, str1)), strcat(str3, "good")); 

1 단계 : 다음에

여기
l = strcmp(str3, strcat(str3, "good")); 

STR3 점의 인수로 string DayGoodgoodGood.

2 단계 : 문자열 DayGoodgoodGoodgood에

l = strcmp(str3,str3); 

이제 STR3 점.

str3이 가리키는 것과 상관없이 0을 반환합니다. 주소가 같기 때문에 strcmp는 최적화를 위해 비교해서는 안됩니다. 그냥 0을 반환합니다.