Используя оператор равенства == для сравнения двух строк для равенства в C

int main (int argc, **argv)
{
       if (argv[1] == "-hello")
            printf("True\n");
       else
            printf("False\n");
}
# ./myProg -hello
False

Почему? Я понимаю, что strcmp(argv[1], "-hello") == 0 возвращает true... но почему я не могу использовать оператор равенства для сравнения двух строк C?

Ответ 1

Потому что argv[1] (например) на самом деле является указателем на строку. Итак, все, что вы делаете, это сравнение указателей.

Ответ 2

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

Компилятор видит сравнение с char* с обеих сторон, поэтому он сравнивает указатель (который сравнивает адреса, хранящиеся в указателях)

Ответ 3

В C, потому что в большинстве контекстов массив "распадается на указатель на его первый элемент".

Итак, когда у вас есть массив "foobar" и используйте его в большинстве контекстов, он распадается на указатель:

if (name == "foobar") /* ... */; /* comparing name with a pointer */

Что вы хотите сравнить с содержимым массива. Вы можете сделать это вручную

if ('p' == *("foobar")) /* ... */; /* false: 'p' != 'f' */
if ('m' == *("foobar"+1)) /* ... */; /* false: 'm' != 'o' */
if ('g' == *("foobar"+2)) /* ... */; /* false: 'g' != 'o' */

или автоматически

if (strcmp(name, "foobar")) /* name is not "foobar" */;

Ответ 4

Потому что нет такой вещи, как строка C.

В C строка обычно представляет собой массив char или указатель на char (что почти то же самое). Сравнение указателя/массива с массивом const не даст ожидаемых результатов.

UPDATE: что я имел в виду под "no C string", нет строки в C. То, что обычно называют "строкой C", не зависит от языка (поскольку "строка Pascal" есть), это представление строк как линейный массив символов с нулевым символом.

Ответ 5

В C строковые значения (включая строковые литералы) представлены в виде массивов char, за которыми следует 0-терминатор, и вы не можете использовать оператор == для сравнения содержимого массива; язык просто не определяет операцию.

За исключением случаев, когда он является операндом операторов sizeof или & или когда это строковый литерал используется для инициализации другого массива в объявлении, выражение с типом "N-элементный массив из T" будет иметь тип, неявно преобразованный (распад), чтобы ввести "указатель на T", а значение выражения будет адресом первого элемента массива.

Итак, когда вы пишете

if (argv[1] == "-hello")

компилятор неявно преобразует выражение "-hello" из массива "7-элементный элемент char" в "указатель на char" (argv[1] уже является типом указателя), а значение выражения адрес символа '-'. Итак, то, что сравнивает ==, - это два значения указателя, которые (скорее всего) никогда не будут равны, поскольку "-hello" и argv[1] (скорее всего) занимают разные регионы в памяти.

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

Ответ 6

Потому что строки C не существуют как таковые. Это char массивы, заканчивающиеся на \0.

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

С другой стороны, "-hello" == "-hello" может возвращать ненулевое значение, но это не означает, что оператор == сравнивает лексикографию. Это связано с другими фактами.

Если вы хотите сравнить lexicographycally, вы всегда можете

#define STR_EQ(s1,s2)    \
   strcmp(s1,s2) == 0

Чтение сложнее. Я вижу, что вы отметили как С++. Таким образом, вы могли

 std::string arg1 ( argv[1] );

 if (arg1 == "-hello"){
    // yeahh!!!
 }
 else{
    //awwwww
 }

Ответ 7

Строки не являются родными типами в C. То, что вы сравниваете в этом примере, - это два указателя. Один для вашего первого аргумента, а другой - это статический массив символов с содержимым "-hello".

Вы действительно хотите использовать strncmp или что-то подобное.

Ответ 8

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

Ответ 9

Поскольку строки C представляют собой массив символов. Массивы просто указывают на первый элемент в массиве, и когда вы сравниваете два указателя, используя ==, он сравнивает адрес памяти, на который они указывают, а не те значения, которые они указывают.