Использование оператора равенства == для сравнения двух строк равенства в 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 являются массивом символов. Массивы - это просто указатели на первый элемент массива, и когда вы сравниваете два указателя с помощью==, он сравнивает адрес памяти, на который они указывают, а не значения, на которые они указывают.