문제

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는 동일한 정적 메모리 블록을 가리키고 있지만 해당 동작이 휴대 가능성을 기대하지는 않습니다.

문자열을 비교할 수는 없지만 포인터를 비교할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top