Почему "a"!= "A" в C?

void main() {
    if("a" == "a")
      printf("Yes, equal");  
    else
      printf("No, not equal");
}

Почему вывод No, not equal?

Ответ 1

То, что вы сравниваете, - это два адреса памяти для разных строк, которые хранятся в разных местах. Выполнение этого по существу выглядит следующим образом:

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

Ответ 2

Я немного опаздываю на вечеринку, но я все равно отвечу; технически одни и те же биты, но с немного другой точки зрения (ниже):

В 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)

Ответ 3

Согласно C99 (раздел 6.4.5/6)

Литералы строк

Неизвестно, являются ли эти массивы различными, если их элементы имеют соответствующие значения.

Таким образом, в этом случае не указано, являются ли оба "a" различными. Оптимизированный компилятор может содержать один "a" в доступном для чтения месте, и обе ссылки могут ссылаться на это.

Посмотрите вывод на gcc здесь

Ответ 4

Потому что они являются 2 отдельными const char*, указателями, фактическими значениями. Вы говорите что-то вроде 0x019181217 == 0x0089178216, которое, конечно, возвращает NO

Используйте strcmp() вместо ==

Ответ 5

Проще говоря, C не имеет встроенного оператора сравнения строк. Он не может сравнивать строки таким образом.

Вместо этого строки сравниваются с использованием стандартных библиотечных подпрограмм, таких как strcmp(), или путем написания кода для циклического прохождения каждого символа в строке.

В C строка текста в двойных кавычках возвращает указатель на строку. Ваш пример сравнивает указатели, и, судя по всему, ваши две версии строки существуют с разными адресами.

Но это не сравнение самих строк, как вы, кажется, ожидаете.

Ответ 6

Указатели.

Первый "a" - это указатель на строку ASCII с нулевым завершением.

Второй "a" является указателем на другую строку ASCII с нулевым завершением.

Если вы используете 32-битный компилятор, я бы ожидал "a"=="a"-4. Я только что попробовал это с tcc/Win32, и я получил "a"=="a"-2. О, хорошо...

Ответ 7

этот вопрос устанавливает очень хороший след объяснения для всех начинающих....
позвольте мне также внести свой вклад в это.....

как объяснили все выше, почему вы получаете такой результат.

теперь, если вы хотите свою прогу. Чтобы напечатать "yes equal", тогда

используйте

if(strcmp("a", "a") == 0)
{

}

или
не используйте "a" как строки, используйте их как символы....

if('a'=='a')  
{  
printf ("yes Equal");  
}  

в символах C есть 1 байтовое короткое целое.......

Ответ 8

Вы сравниваете два адреса памяти, поэтому результат не всегда будет правдой. Вы пробовали if('a' == 'a'){...}?

Ответ 9

Некоторые компиляторы имеют параметр "merge strings", который вы можете использовать, чтобы заставить все константные строки иметь один и тот же адрес. Если вы будете использовать это, "a" == "a" будет true.

Ответ 10

если сравнение символа всегда в одиночной кавычке, например

if('a' == 'a')

и C не может поддерживать сравнение строк, например "abc" == "abc"

Выполняется с помощью strcmp("abc","abc")

Ответ 11

Этот парень не использует переменные. Вместо этого он использует временные текстовые массивы: 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");
    }
}