Понимание справочника char
Я написал этот простой script, чтобы понять, что такое ссылка, и я зацикливаюсь на массиве char.
int numbers[5] = {3, 6, 9, 12, 15};
for (int i = 0; i < 5; i++)
{
cout << numbers[i] << endl;
cout << &numbers[i] << endl;
}
cout << "--------------" << endl;
char letters[5] = {'a', 'b', 'c', 'd', 'e'};
for (int i = 0; i < 5; i++)
{
cout << letters[i] << endl;
cout << &letters[i] << endl;
}
и это результат:
3
0xbffff958
6
0xbffff95c
9
0xbffff960
12
0xbffff964
15
0xbffff968
--------------
a
abcde
b
bcde
c
cde
d
de
e
С массивом int
, когда я использую &numbers[i]
, я получаю странное число, которое является ячейкой памяти. Хорошо; это именно то, что я понял.
Но с char
я не понимаю, почему у меня этот вывод.
Ответы
Ответ 1
Причина в том, что cout
"знает", что делать со значением char *
- он печатает символьную строку как строку C с завершающим NUL.
То же самое не относится к значению int *
, поэтому cout
вместо этого выводит значение указателя.
Вы можете принудительно выводить значение указателя путем кастинга:
cout << static_cast<void *>(&letters[i]) << endl;
Ответ 2
Вы смотрите на особенности потоков С++. Он пытается преобразовать свои аргументы в то, что обычно печатается. Тип этого выражения &ints[x]
int*
. &chars[x]
становится char*
, который, кстати, также является типом символьной строки C. Поскольку мы хотим, чтобы этот cout << "FOO"'
распечатывал всю строку, необходимо иметь такое поведение. В вашем случае это фактически приводит к поведению undefined, так как строка, которую вы используете, не имеет нулевого завершения. Для решения этой проблемы используйте static_cast
.
Ответ 3
Когда вы переходите к ostream::operator<<
(на самом деле это глобальная функция, а не оператор) аргумент типа char*
, он рассматривается как строка с завершающим нулем.