C++ Сравнение строк с использованием реляционного оператора

Может кто-то уточнить, что на самом деле происходит во время этого сравнения.

В программе на C++, если у меня есть:

string name1 = "Mary";

и я делаю:

name1 < "Mary Jane" // true

Почему это правда? Если C++ сравнивает каждый символ с каждым символом, а первый несовпадающий символ - это одинарная двойная кавычка в конце name1 = "Mary" против значения пробела в "Mary Jane", то по значению ASCII значение пробела меньше, чем единичное знак кавычки...

3 ответа

string name1 = "Mary";

Давайте откроем это, происходит несколько вещей.

Знак

"Mary"

взятый отдельно является строковым литералом, который приблизительно вычисляется в массив

const char literal_array[5] = { 'M', 'a', 'r', 'y', 0 };

Вы можете понять, почему стоит иметь какой-то синтаксический сахар - писать это для каждой строки было бы ужасно.

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

Затем, когда мы узнаем правую часть выражения, мы можем посмотреть слева:

string name1 = "Mary"

действительно

string name1(literal_array);

используя конструктор

basic_string<char>::basic_string<char>(const char *)

Я немного перефразирую, но это пункт 5 здесь.


name1 < "Mary Jane"

Теперь мы наконец знаем, что такое левая сторона, мы можем посмотреть на это выражение, которое расширяется до

const char literal_array2[10] = { 'M', 'a', 'r', 'y', ' ', 'J', 'a', 'n', 'e', 0 };
operator< (name1, literal_array2)

который является 9-й перегрузкой здесь (на момент написания), и который вызывает compare как

name1.compare(literal_array2)

который описывается как делать следующее:

4) Сравнивает эту строку с завершающей нулем последовательностью символов, начинающейся с символа, на который указывает s, как если бы compare(basic_string(s))

что возвращает нас к первой перегрузке:

1) Сначала вычисляется количество сравниваемых символов, как если бы

size_type rlen = std::min(size(), str.size()).

Затем сравнивает по телефону

Traits::compare(data(), str.data(), rlen).

Для стандартных строк эта функция выполняет посимвольное лексикографическое сравнение.

Если результат равен нулю (строки равны до сих пор),

обратите внимание, что это тот случай, когда мы только что сравнили "Мэри" с "Мэри"

тогда их размеры сравниваются следующим образом:

size(data) < size(arg)    => data is less than arg    => result <0

где "результат <0" означает operator< вернет истину.

Хотя мы пишем строковые литералы в C++, окруженные кавычками, эти кавычки на самом деле не являются частью строки. Это означает, что строки, которые вы на самом деле сравниваете здесь, Mary а также Mary Jane, без кавычек.

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

Перегруженный < оператор не сравнивать " в строке. "" используется для обозначения строк, так что компилятор будет анализировать его как строку. Они не являются частью строки.

Другие вопросы по тегам