Я пытаюсь сравнить два указателя:
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
?
Почему два указателя имеют разные адреса, а операция
==
возвращает true?
&x
и &y
- это адреса переменных указателя, а не адреса строки. Поскольку x
и y
- разные переменные, у них разные адреса.
Затем вы сравниваете значения x
и y
которые бывают одинаковыми, поскольку компилятор заметил, что два строковых литерала имеют одинаковое значение и сохраняются только одна копия литерала.
Почему компилятор не сохранил строковый литерал
"Hesham"
только один раз и дважды использовал свой адрес дляx
иy
?
Так оно и было. Поэтому x == y
значение true.
Еще один момент заключается в том, что при печати указателей следует использовать спецификатор формата %p
.
printf("%d %d \n", x, y);
Не &x
и &y
. Чтобы увидеть данные, на которые они указывают. Спасибо :)
Это зависит от параметра компилятора, будет ли компилятор хранить равные строковые литералы как отдельные литералы или как один литерал/Обычно по умолчанию компиляторы хранят равные строковые литералы как один строковый литерал, чтобы минимизировать использование памяти.
В этих заявлениях
x = "Hesham";
y = "Hesham";
вы присваиваете один и тот же адрес первого символа строкового литерала переменным x и y. Поскольку компилятор хранит эти два строковых литерала как один строковый литерал, то очевидно, что x == y
которому присваивается одно и то же значение x и y.
Однако, если вы установили опцию компилятора, чтобы заставить компилятор хранить равные строковые литералы как отдельные литералы, тогда результат выражения x == y
был бы равен false
. Если вы хотите сравнить строковые литералы, вам нужно написать
if ( strcmp( x, y ) == 0 ) { /*...*/ }
printf("%d %d \n", x, y);
Не &x
и &y
. Чтобы увидеть адрес, на который они указывают. Знаете ли вы, что параметры компилятора для ARM? Я много искал и не нашел.
В соответствии с C++ языком программирования Бьярном Страуструпом, он сказал
Whether two identical string literals are allocated as one array or as two is implementation-defined.
Я думаю, что он также работает для C, учитывая, что C++ основан на C99. В вашем случае только один из них выделяется и используется дважды, что означает, что x
и y
указывают на идентичную строку.
"foo" == "foo"
более слабым, чем «определяемый реализацией». Я очень удивлен цитатой, которую вы нашли, и в любом случае, вероятно, ее не следует считать нормативной.
strncmp()
?