Действительно, «поскольку ваш компилятор в данном случае не использует пул строк», это технически правильный, но не особо полезный ответ:)
Это одна из многих причин, по которым класс std :: string в стандартной библиотеке шаблонов теперь существует для замены этого более раннего типа строк, когда вы хотите сделать что-нибудь полезное со строками в C ++, и является проблема почти всех, кто когда-либо изучал C или C ++, спотыкается довольно рано в своих исследованиях.
Позвольте мне объяснить.
В принципе, еще во времена C все строки работали так. Строка - это просто набор символов в памяти. Строка, которую вы встраиваете в исходный код C, преобразуется в набор байтов, представляющих эту строку в работающем машинном коде при выполнении вашей программы.
Важнейшей частью здесь является то, что хорошая старомодная «строка» в стиле C - это массив символов в памяти. На этот блок памяти часто ссылается указатель - адрес начала блока памяти. Обычно, когда вы ссылаетесь на «строку» в C, вы ссылаетесь на этот блок памяти или указатель на него. C не имеет типа string ; строки - это просто набор символов с подряд.
Когда вы пишете это в своем коде:
"wibble"
Затем компилятор предоставляет блок памяти, который содержит байты, представляющие символы 'w', 'i', 'b', 'b', 'l', 'e' и '\ 0' в этом порядке. (компилятор добавляет нулевой байт в конце, «нулевой терминатор». В C стандартной строкой является строка с нулевым символом в конце: блок символов, начинающийся с данного адреса памяти и продолжающийся до следующего нулевого байта.)
И когда вы начинаете сравнивать такие выражения, происходит следующее:
if ("Maya" == "Maya")
В момент этого сравнения компилятор - в ваш случай, в частности; см. мое объяснение объединения строк в конце - создано два отдельных блока памяти для хранения двух разных наборов символов, для которых оба установлены на «M», «a», «y», «a», «\ 0». .
Когда компилятор видит строку в кавычках, подобную этой, «под капотом» он создает массив символов, а сама строка «Maya» действует как имя массива символов , Поскольку имена массивов фактически являются указателями, указывающими на первый символ массива, тип выражения «Maya» - это указатель на символ .
Когда вы сравниваете эти два выражения, используя "==", вы фактически сравниваете указатели , адреса памяти начала этих двух различных блоков памяти, Вот почему в вашем конкретном случае сравнение ложно с вашим конкретным компилятором.
Если вы хотите сравнить две старые добрые C-строки, вы должны использовать функцию strcmp () . Это проверит содержимое памяти, обозначенной двумя «строками» (которые, как я уже объяснил, являются просто указателями на блок памяти), и пройдет через байты, сравнивая их один за другим, и скажет вам действительно ли они действительно одинаковы.
Теперь, как я уже сказал, это своего рода немного удивительный результат, который кусал начинающих C с задницы со времен прошлого. И это одна из причин, по которой язык развивался с течением времени. Теперь в C ++ есть класс std :: string , который будет содержать строки и работать так, как вы ожидаете. Оператор "==" для std :: string фактически сравнивает содержимое двух std :: strings .
По умолчанию, однако, C ++ разработан для обратной совместимости с C, т.е. программа на C обычно компилируется и работает под компилятором C ++ так же, как в компиляторе C, а это означает, что строки старомодны «подобные вещи в вашем коде» все равно будут указывать на биты памяти, которые дадут новичку неочевидные результаты, когда вы начнете их сравнивать.
О, а тот "пул струн", о котором я упоминал в начале? Вот тут-то и может возникнуть некоторая сложность. Умный компилятор, который будет эффективен со своей памятью, может заметить, что в вашем случае строки одинаковы и не могут быть изменены, и поэтому выделяются только one блок памяти, с обоими вашими именами "Майя", указывающими на него. В этот момент сравнение «строк» - указателей - покажет вам, что они , фактически равны. Но больше удачей, чем дизайном!
Это поведение «объединения строк» будет меняться от компилятора к компилятору и часто будет отличаться в зависимости от режимов отладки и выпуска одного и того же компилятора, поскольку режим выпуска часто включает в себя такие оптимизации, которые делают код вывода более компактным ( должен иметь только один блок памяти с «Maya», а не два, так что сохраняется пять - запомните этот нулевой терминатор! - байтов в объектном коде.) И это такое поведение, которое может свести с ума человека, если они не знают, что происходит:)
Если ничего другого, этот ответ может дать вам много поисковых терминов для тысяч статей, которые уже есть в сети, пытаясь объяснить это. Это немного больно, и все проходят через это. Если вы сможете разобраться с указателями, вы в конечном итоге станете намного лучше программистом на C или C ++, независимо от того, решите вы использовать вместо него std :: string или нет!