В чем разница между добавлением этих строк? - PullRequest
4 голосов
/ 03 февраля 2020

Программа 1:

#include <iostream>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp + "bc";
    cout << str;
    return 0;
}

Вывод:

Неизвестные символы

Программа 2:

#include <iostream>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp;
    str += "bc";
    cout << str;
    return 0;
}

Вывод:

ab c

Почему оба выходы разные? Разве оба выхода не должны быть одинаковыми?

Ответы [ 4 ]

0 голосов
/ 03 февраля 2020

Этот оператор

str += temp + "bc";

может быть представлен как

str = str + ( temp + "bc" );

В подвыражении temp + "bc" строковый литерал "bc" неявно преобразован в указатель на свой первый символ и имеет тип const char *. Значение переменной temp преобразуется в целочисленный тип из-за целочисленных переходов, которые, например, в таблице ASCII имеют значение 97.

Таким образом, в подвыражении используется арифметика указателя c. Выражение temp + "bc" указывает на память вне строкового литерала. Таким образом, результат выражения не определен.

Если вы напишите, например,

char temp = 1;

, тогда выражение temp + "bc" указывает на второй символ строкового литерала. В результате str будет иметь значение 'b'.

Или для получения того же результата, что и во второй программе, вы можете написать

str += temp + std::string( "bc" );

Что касается второй программы, то в В этом операторе

str += temp;
str += "bc";

используются перегруженные операторы += для класса std :: string и объектов типа char и char *. Так что эти утверждения четко определены.

Обратите внимание на то, что вы должны явно включить заголовок <string>.

#include <string>
0 голосов
/ 03 февраля 2020

Программа 1 в этой строке

str += temp + "bc";
  1. оцениваются первые аргументы сложения
  2. справа находится массив char: const char[3]
  3. on слева есть char, который может быть автоматически преобразован в int
  4. const char[3] ухудшается до const char *
  5. , добавляется int (97) и const char * выполнимо , но результаты указывают за пределы диапазона буфера.
  6. , тогда вы используете basic_string::operator+=( const CharT* s );, но аргумент недействителен. У вас переполнение буфера.

Программа 2. Не имеет этого неопределенного поведения, и используются операторы формы std::string.

Другая разумная версия:

str = str + temp + "bc";

Теперь каждое добавление будет создавать std::string в результате.

0 голосов
/ 03 февраля 2020

std::string класс имеет перегруженные операторы + и +=, что позволяет использовать их для объединения std::string s друг с другом, с отдельными символами и массивами символов.

Но так же, как в C, "bc" - это не std::string, а const char [3] (постоянный массив из 3 символов). Массивы часто автоматически конвертируются ( decay ) в указатели на их первые элементы. Это происходит и здесь.

str += "foobar"; добавляет символы, указанные указателем, один за другим, пока он не достигнет нулевого байта, заканчивающего строку.

Вы можете добавлять целые числа к указателям: str += "foobar" + 3; добавит "bar" к строке.

В C ++ char являются просто маленькими целыми числами. Так что 'a' + "bc" на самом деле означает 97 + "bs" (при условии, что ваш компилятор использует ASCII, все обычные делают).

Это формирует указатель, который находится за пределами массива и вызывает неопределенное поведение.

Случайные символы, которые вы видите, представляют собой содержимое памяти, расположенное в 97 байтах после массива "bc", которое заканчивается случайным нулевым байтом, который был в этой памяти.

0 голосов
/ 03 февраля 2020

Первый код

#include <iostream>
#include<string>
using namespace std;

int main() {
    string str;//defining an empty string
    char temp = 'a';//defining a char
    str += temp + "bc";//adding a defined a char to a const char*
                       //which is undefined behavior because there is
                       //no operator+ overloaded to do that and then
                       //assigning your string to them so you get undefined behavior
    cout << str;
    return 0;
}

Второй код

#include <iostream>
#include<string>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp;//this creat a temporary std::string containing the character temp
                //then concatenate between it with your string then you get your output 
    str += "bc";
    cout << str;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...