void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
Почему вывод No, not equal
?
void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
Почему вывод No, not equal
?
То, что вы сравниваете, - это два адреса памяти для разных строк, которые хранятся в разных местах. Выполнение этого по существу выглядит следующим образом:
if(0x00403064 == 0x002D316A) // Two memory locations
{
printf("Yes, equal");
}
Используйте следующий код для сравнения двух строковых значений:
#include <string.h>
...
if(strcmp("a", "a") == 0)
{
// Equal
}
Кроме того, "a" == "a"
может действительно возвращать true, в зависимости от вашего компилятора, который может комбинировать равные строки во время компиляции в один для экономии места.
Когда вы сравниваете два символьных значения (которые не являются указателями), это числовое сравнение. Например:
'a' == 'a' // always true
Я немного опаздываю на вечеринку, но я все равно отвечу; технически одни и те же биты, но с немного другой точки зрения (ниже):
В C выражение "a"
обозначает строковый литерал, который представляет собой статический неназванный массив const char
с длиной в два - массив состоит из символов 'a'
и '\0'
- завершающий нулевой символ сигнализирует конец строки.
Тем не менее, в C, вы не можете передавать массивы в функции по значению - или присваивать им значения (после инициализации) - для массивов нет перегруженного оператора ==
, поэтому их невозможно напрямую сравнивать. Рассмотрим
int a1[] = {1, 2, 3};
int a2[] = {3, 4, 5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for
// "identity", but not for their values. In this case the result
// is always false, because the arrays (a1 and a2) are distinct objects
Если ==
не сравнивает массивы, что на самом деле делает? В C почти во всех контекстах, включая этот, массивы распадаются на указатели (которые указывают на первый элемент массива) - и сравнение указателей на равенство делает то, что вы ожидаете. Так эффективно, делая это
"a" == "a"
вы фактически сравниваете адреса первых символов в двух неназванных массивах. В соответствии со стандартом C сравнение может давать либо true, либо false (то есть 1 или 0) - "a"
может фактически обозначать один и тот же массив или два полностью несвязанных массива. С технической точки зрения результирующее значение не указано, что означает, что сравнение допустимо (т.е. Не поведение undefined или синтаксическая ошибка), но любое значение является допустимым, а реализация (ваш компилятор) не требуется для документирования того, что на самом деле произойдет.
Как указывали другие, для сравнения строк "c" (т.е. строк, заканчивающихся нулевым символом) вы используете удобную функцию strcmp
, найденную в стандартном файле заголовка string.h
. Функция имеет возвращаемое значение 0
для равных строк; он считает, что хорошая практика явно сравнивать возвращаемое значение с 0
вместо использования оператора `! ', т.е.
strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
Согласно C99 (раздел 6.4.5/6)
Литералы строк
Неизвестно, являются ли эти массивы различными, если их элементы имеют соответствующие значения.
Таким образом, в этом случае не указано, являются ли оба "a"
различными. Оптимизированный компилятор может содержать один "a"
в доступном для чтения месте, и обе ссылки могут ссылаться на это.
Посмотрите вывод на gcc здесь
Потому что они являются 2 отдельными const char*
, указателями, фактическими значениями.
Вы говорите что-то вроде 0x019181217 == 0x0089178216
, которое, конечно, возвращает NO
Используйте strcmp()
вместо ==
Проще говоря, C не имеет встроенного оператора сравнения строк. Он не может сравнивать строки таким образом.
Вместо этого строки сравниваются с использованием стандартных библиотечных подпрограмм, таких как strcmp(), или путем написания кода для циклического прохождения каждого символа в строке.
В C строка текста в двойных кавычках возвращает указатель на строку. Ваш пример сравнивает указатели, и, судя по всему, ваши две версии строки существуют с разными адресами.
Но это не сравнение самих строк, как вы, кажется, ожидаете.
Указатели.
Первый "a"
- это указатель на строку ASCII с нулевым завершением.
Второй "a"
является указателем на другую строку ASCII с нулевым завершением.
Если вы используете 32-битный компилятор, я бы ожидал "a"=="a"-4
.
Я только что попробовал это с tcc/Win32, и я получил "a"=="a"-2
.
О, хорошо...
этот вопрос устанавливает очень хороший след объяснения для всех начинающих....
позвольте мне также внести свой вклад в это.....
как объяснили все выше, почему вы получаете такой результат.
теперь, если вы хотите свою прогу. Чтобы напечатать "yes equal", тогда
используйте
if(strcmp("a", "a") == 0)
{
}
или
не используйте "a" как строки, используйте их как символы....
if('a'=='a')
{
printf ("yes Equal");
}
в символах C есть 1 байтовое короткое целое.......
Вы сравниваете два адреса памяти, поэтому результат не всегда будет правдой. Вы пробовали if('a' == 'a'){...}
?
Некоторые компиляторы имеют параметр "merge strings", который вы можете использовать, чтобы заставить все константные строки иметь один и тот же адрес. Если вы будете использовать это, "a" == "a"
будет true
.
если сравнение символа всегда в одиночной кавычке, например
if('a' == 'a')
и C не может поддерживать сравнение строк, например "abc" == "abc"
Выполняется с помощью strcmp("abc","abc")
Этот парень не использует переменные. Вместо этого он использует временные текстовые массивы: a
и a
. Причина, по которой
void main()
{
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
не работает, конечно, заключается в том, что вы не сравниваете переменные.
Если вы создадите такие переменные, как:
char * text = "a";
char * text2 = "a";
то вы можете сравнить text
с text2
, и это должно быть true
Возможно, вы не должны забывать использовать {
и }
=)
void main() {
if("a" == "a")
{
printf("Yes, equal");
}
else
{
printf("No, not equal");
}
}