2014-03-05 2 views
5

우리가 말한다면 :왜 문자열 리터럴이 포인터와 비교됩니까?

우리가 "이름"으로

if(p=="name"){ 
printf("able"};//this if condition is true but why? 

을 할 수있는 방법을 다음

char *p="name"; 

여기에 문자열 리터럴과 p 그때 왜 문자열의 기본 주소를 보유하고 포인터이다 위의 진술은 잘 작동합니까? 리터럴 문자열의 첫 번째 문자에

 |n |a |m | e 
    /
    p 

p 포인트 :

+7

컴파일러 최적화입니다. 당신이 의지 할 수없는 하나. –

+0

@ YuHao가 지적하는 것과 매우 유사한 질문. 같은 교재? – crashmstr

답변

6

동일한 문자열 리터럴이 동일하게 간주되어 동일한 주소를 가질 수 있는지 여부는 지정되지 않은 동작입니다. 따라서 이것은 휴대용 동작이 아닙니다. 초안 C99 표준 섹션 6.4.5문자열 리터럴에서 :

는 이러한 배열은 자신의 요소가 적절한 값을 제공 별개의 여부를 지정합니다. [...]

두 문자열을 비교하려면 strcmp을 사용해야합니다.

1

문자열 리터럴은 char *p="name";이 작업을 수행 할 때 따라서, 그것은 아무것도 의미하지 않는다 아무것도 메모리 참조입니다. 이렇게하면 :

p=="name"someAddress==someAddress으로 평가됩니다. 그러나이 동작은 명시되지 않았습니다.

1

좋아,이게 무슨 일을하는지 보자.

p는 name\0에 대한 포인터입니다. 그래서 여기 p (포인터)와 "name" (또한 포인터)을 비교합니다. 글쎄, 이것이 사실 일 때의 유일한 방법은 어딘가에 p="name"이 있고 심지어 그 때라도 "name"이 어디서나 같은 장소를 가리 키지 않는다는 것입니다.

나는 당신이 실제로 찾고있는 것은 하나 strcmp가 전체 문자열을 비교하거나이

비교하려면 strcmp() == 0을 사용할 n 문자로 p 문자열의 첫 번째 문자를 비교하는 if (*p == 'n')을하고자 믿습니다 문자열이 단순한 == 대신에 사용됩니다. 이는 포인터가 동일한 지 비교합니다.

표현식 strcmp(p, "name") == 0은 두 문자열의 내용이 같은지 확인합니다.

2

C 표준을 사용하면 비교가 참일 수 있지만 false 일 수도 있습니다 (동작은 으로 지정되지 않음). 그것은 일반적인 문자열 병합을 수행하는 컴파일러에 달려 있습니다 (gcc는이를 켜거나 끌 수있는 옵션이 있습니다).

gcc 4.8.1 수동 : 동일한 상수 (문자열 상수 및 부동 소수점 상수) 컴파일 단위에서 병합

-fmerge-constants 시도합니다.

이 옵션은 어셈블러와 링커에서 지원하는 경우 최적화 된 컴파일의 기본값입니다. -fno-merge-constants을 사용하면이 동작을 금지 할 수 있습니다. 수준 -O, -O2, -O3, -Os에서 사용 가능합니다.

-fmerge-all-constants 동일한 상수와 동일한 변수를 병합하려고합니다.

그렇다면 두 개의 "name" 리터럴에 대해 문자열 병합을 수행하는 컴파일러가 있습니다.

관련 문제