Сравнение Char-указателей

0

Я пытаюсь сравнить два указателя:

   char * x;
   char * y;

   x = "Hesham";
   y = "Hesham";

   printf("%d %d \n", &x, &y);

   if(x==y)
   {
     printf("=\n");
   }
   else
   {
     printf("!=\n");
   }

Результат выполнения:

2293368 2293360
=

1 - Почему два указателя имеют разные адресаты, а операция == возвращает true?

2 - Почему компилятор не сохранил строковый литерал Hesham только один раз и дважды использовал свой адрес для x и y?

  • 0
    Вы хотели использовать strncmp() ?
  • 0
    Нет, я не это имел в виду.
Показать ещё 6 комментариев
Теги:
pointers
char
equality

3 ответа

11
Лучший ответ

Почему два указателя имеют разные адреса, а операция == возвращает true?

&x и &y - это адреса переменных указателя, а не адреса строки. Поскольку x и y - разные переменные, у них разные адреса.

Затем вы сравниваете значения x и y которые бывают одинаковыми, поскольку компилятор заметил, что два строковых литерала имеют одинаковое значение и сохраняются только одна копия литерала.

Почему компилятор не сохранил строковый литерал "Hesham" только один раз и дважды использовал свой адрес для x и y?

Так оно и было. Поэтому x == y значение true.


Еще один момент заключается в том, что при печати указателей следует использовать спецификатор формата %p.

  • 0
    Извините, мне следовало напечатать: printf("%d %d \n", x, y); Не &x и &y . Чтобы увидеть данные, на которые они указывают. Спасибо :)
  • 0
    Исправление предыдущего комментария: чтобы увидеть адрес, на который они указывают
Показать ещё 2 комментария
2

Это зависит от параметра компилятора, будет ли компилятор хранить равные строковые литералы как отдельные литералы или как один литерал/Обычно по умолчанию компиляторы хранят равные строковые литералы как один строковый литерал, чтобы минимизировать использование памяти.

В этих заявлениях

   x = "Hesham";
   y = "Hesham";

вы присваиваете один и тот же адрес первого символа строкового литерала переменным x и y. Поскольку компилятор хранит эти два строковых литерала как один строковый литерал, то очевидно, что x == y которому присваивается одно и то же значение x и y.

Однако, если вы установили опцию компилятора, чтобы заставить компилятор хранить равные строковые литералы как отдельные литералы, тогда результат выражения x == y был бы равен false. Если вы хотите сравнить строковые литералы, вам нужно написать

if ( strcmp( x, y ) == 0 ) { /*...*/ }
  • 0
    Извините, мне следовало напечатать: printf("%d %d \n", x, y); Не &x и &y . Чтобы увидеть адрес, на который они указывают. Знаете ли вы, что параметры компилятора для ARM? Я много искал и не нашел.
1

В соответствии с C++ языком программирования Бьярном Страуструпом, он сказал

Whether two identical string literals are allocated as one array or as two is
implementation-defined.

Я думаю, что он также работает для C, учитывая, что C++ основан на C99. В вашем случае только один из них выделяется и используется дважды, что означает, что x и y указывают на идентичную строку.

  • 1
    В стандарте C99 не указано, является ли "foo" == "foo" более слабым, чем «определяемый реализацией». Я очень удивлен цитатой, которую вы нашли, и в любом случае, вероятно, ее не следует считать нормативной.
  • 1
    У меня лежал черновик стандарта C ++ от 2005 года, и он действительно говорит: «Все ли строковые литералы различны (то есть хранятся ли они в неперекрывающихся объектах), определяется реализацией» (2.13.4: 2). Соответствующее упоминание C99: «Строковые литералы и составные литералы с константными типами не должны обозначать отдельные объекты». Это не заставляет реализацию документировать свое поведение или делать его согласованным. (C99 6.5.2.5:8)
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню