Понимание строк как указателей в C++
У меня проблемы с пониманием строк как указателей. По-видимому, строка понимается как указатель, который указывает на первый адрес строки. Поэтому, используя оператор"&", я должен получить адрес первого символа строки. Вот небольшой пример:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(){
char text[101];
int length;
cout << "Enter a word: ";
cin >> text;
length = strlen(text);
for (int i = 0; i <= length; i++) {
cout << " " << &text[i];
}
return 0;
}
При вводе такого слова, как" Hello", выводится:"Hello ello llo lo o". Вместо этого я ожидал получить адрес каждого символа "Hello". Когда я использую гипс long(&text[i]), он отлично работает. Но я этого не делаю. поймите почему. Без приведения, очевидно, оператор "& " - дает начальный адрес строки, которая будет напечатана. Используя приведение, он дает адрес каждого символа отдельно.
Может быть, СБ. можете мне это объяснить - я буду вам очень благодарен!
3 ответа:
Если у вас есть массив символов, хранящий строку, например
char text[] = "Hello";Тогда массив инициализируется как
char text[] = { 'H', 'e', 'l', 'l', 'o', '\0' };В этом утверждении
std::cout << text;Используется
operator <<перегруженный типconst char *и массивtextнеявно преобразуется в указатель на его первый элемент.Вы могли бы написать вместо этого
std::cout << &text[0];Потому что в обоих утверждениях выражения
textи&text[0]имеют типchar *.Оператор перегружен для тип
const char *выводит символы, начинающиеся с адреса в указателе, пока не встретится нулевой символ.Так что если вместо утверждения
std::cout << &text[0];Ты напишешь
std::cout << &text[1];Тогда единственное, что изменяется, - это начальный адрес строки и ничего больше. То есть фактически вы выводите строку, которая представлена как
{ 'e', 'l', 'l', 'o', '\0' }Если написать
std::cout << &text[2];То есть если указатель в правой части выражения сдвинут на единицу позиция справа означает, что вы будете иметь дело со строкой
{ 'l', 'l', 'o', '\0' }И так далее.
То есть
operator <<перегруженный какtemplate<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);Просто выводит объекты, на которые указывает второй параметр, в виде строк.
Если вы хотите вывести значение самого указателя вместо строки, на которую указывает указатель, вы должны использовать другой перегруженный
operator <<, объявленный какbasic_ostream<charT, traits>& operator<<(const void* p);Tp вызвать его вы должны написать для пример
std::cout << ( void * )text;Или
std::cout << ( void * )&text[i];Где
i- некоторый индекс.Вместо приведения C можно использовать приведение C++, например
std::cout << static_cast<void *>( &text[i] );
&text[i]эквивалентноtext + iи смещает указатель вдоль массиваchar[]наiместа, используя арифметику указателя. Эффект состоит в том, чтобы начатьcoutна (i) - м Символе, с перегрузкой<<вconst char*вызывается. Это выводит все символы от начальной точки до нулевого Терминатора.
text[i]однако это типchar, и перегрузка<<вcharназывается. Это выводит один символ.В C++, если вам нужна строка, то используйте
std::stringвместо этого. Вы все еще можете написатьcin >> text;, Еслиtextявляется типомstd::string! Ваш код также не уязвим для переполнения буфераchar.