문제
C에서 "문자열"을 비교하는 올바른 방법은 사용하는 것입니다. strcmp
, 그러나 이제 나는 일부 캐릭터 배열을 ==
연산자, 이상한 결과를 얻었습니다.
다음 코드를 살펴보십시오.
int main()
{
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%d\n", s1 == s2); //1
printf("%d\n", s3 == s4); //0
printf("%d\n", s1 == s5); //0
}
첫번째 printf
올바르게 인쇄 a 1
, 그것은 그들이 같지 않다는 신호입니다. 그러나 누군가가 캐릭터 배열을 비교할 때 왜 ==
돌아오고 있습니다 0
?
누군가가 왜 처음으로 나에게 설명해 주시겠습니까? printf
돌아오고 있습니다 1
(즉, 그들은 동일합니다) 캐릭터 배열은 0
?
해결책
==는 메모리 주소를 비교하고 있습니다.
컴파일러가 S1과 S2가 공간을 절약하기 위해 동일한 정적 데이터를 가리키고있을 가능성이 높습니다.
즉. 첫 두 줄의 코드 라인의 "Andreas"는 실행 파일 데이터에 저장됩니다. C 표준은 이러한 문자열이 일정하다고 말하면서 동일한 스토리지를 가리키기 위해 두 포인터를 검토했습니다.
char [] 라인은 데이터를 변수로 복사하여 변수를 생성하며 실행 중에 스택의 다른 주소에 저장됩니다.
다른 팁
어 ... 언제 ==
1 인쇄, 그들은 의미합니다 ~이다 동일한. 문자열의 상대 순서를 반환하는 strcmp와 다릅니다.
당신은 줄이 아닌 주소를 비교하고 있습니다. 처음 두 개는 일정하며 한 번만 만들어집니다.
int main()
{
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%d\n", s1 == s2); //1
printf("%p == %p\n", s1, s2);
printf("%d\n", s3 == s4); //0
printf("%p != %p\n", s3, s4);
printf("%d\n", s1 == s5); //0
printf("%p != %p\n", s1, s5);
}
내 컴퓨터에서 출력하지만 아이디어를 얻을 수 있습니다.
1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0
잠깐만 기다려 ... 1은 true, 0은 거짓을 의미합니다. 따라서 귀하의 설명은 부분적으로 거꾸로됩니다. 처음 두 줄이 같은 것처럼 보이는 이유는 다음과 같습니다. 컴파일러는 해당 상수 문자열 (S1/2)을 한 번만 구축했습니다.
s1 == s2
수단 "(char*) == (char*)
"또는 주소가 동일하다.
같은 것 s3 == s4
. 그게 "배열은 포인터로 부패합니다" 직장에서.
그리고 당신은 비교 결과의 의미가 잘못되었습니다.
0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */
S1 ~ S5의 모든 값은 그렇지 않습니다 숯 그들 자신, 그들은 포인터입니다 에게 숯. 따라서 비교하는 것은 문자열 자체가 아닌 각 문자열의 메모리 주소입니다.
주소를 표시하면 비교 연산자가 실제로 무엇을하고 있는지 확인할 수 있습니다.
#include <stdio.h>
int main() {
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%p\n", s1); // 0x80484d0
printf("%p\n", s2); // 0x80484d0
printf("%p\n", s3); // 0xbfef9280
printf("%p\n", s4); // 0xbfef9278
printf("%p\n", s5); // 0x80484d8
}
문자열이 메모리에 할당되는 곳은 구현별로 구현됩니다. 이 경우 S1 및 S2는 동일한 정적 메모리 블록을 가리키고 있지만 해당 동작이 휴대 가능성을 기대하지는 않습니다.
문자열을 비교할 수는 없지만 포인터를 비교할 수 있습니다.