Это старый вопрос, но мне недавно пришлось его кому-то объяснить, и я подумал, что запись ответа здесь будет полезна, по крайней мере, для понимания того, как работает С.
Строковые литералы, такие как
"a"
или
"This is a string"
помещаются в текстовые или информационные сегменты вашей программы.
Строка в C на самом деле является указателем на символ, и понимается, что строка является последующими символами в памяти до тех пор, пока не встретится символ NUL. То есть C на самом деле не знает о строках.
Так что, если у меня есть
char *s1 = "This is a string";
тогда s1 - указатель на первый байт строки.
Теперь, если у меня есть
char *s2 = "This is a string";
это также указатель на тот же первый байт этой строки в текстовом или информационном сегменте программы.
Но если у меня есть
char *s3 = malloc( 17 );
strcpy(s3, "This is a string");
тогда s3 - указатель на другое место в памяти, в которое я копирую все байты других строк.
Иллюстративные примеры:
Хотя, как правильно указывает ваш компилятор, этого делать не следует, следующее будет иметь значение true:
s1 == s2 // True: we are comparing two pointers that contain the same address
, но следующее будет ложным
s1 == s3 // False: Comparing two pointers that don't hold the same address.
И хотя может быть заманчиво иметь что-то вроде этого:
struct Vehicle{
char *type;
// other stuff
}
if( type == "Car" )
//blah1
else if( type == "Motorcycle )
//blah2
Вы не должны этого делать, потому что это не то, что гарантированно работает. Даже если вы знаете, что этот тип всегда будет установлен с использованием строкового литерала.
Я проверил это, и оно работает. Если я сделаю
A.type = "Car";
затем исполняется blah1 и аналогично для "Мотоцикла". И вы сможете делать такие вещи, как
if( A.type == B.type )
но это просто ужасно. Я пишу об этом, потому что думаю, что интересно знать, почему это работает, и это помогает понять, почему вы не должны этого делать.
Решения:
В вашем случае вам нужно использовать strcmp(a,b) == 0
для замены a == b
В случае моего примера вы должны использовать enum.
enum type {CAR = 0, MOTORCYCLE = 1}
Вышеприведенная вещь со строкой была полезна, потому что вы можете напечатать тип, поэтому у вас может быть такой массив
char *types[] = {"Car", "Motorcycle"};
И теперь, когда я думаю об этом, это подвержено ошибкам, поскольку нужно соблюдать осторожность, чтобы поддерживать тот же порядок в массиве типов.
Поэтому может быть лучше сделать
char *getTypeString(int type)
{
switch(type)
case CAR: return "Car";
case MOTORCYCLE: return "Motorcycle"
default: return NULL;
}