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

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

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

9 ответов


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


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

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


на 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" */;

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

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

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


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

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

поэтому, когда вы пишите

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

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

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


потому что строки C не существуют как таковые. Это массивы символов, заканчивающиеся на .

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

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

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

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

чтение сложнее я вижу, что вы помечены как c++. Так что вы могли бы

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

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

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

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


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


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