указатель c ++ на определенный элемент в массиве char возвращает все элементы после указанного

0

Чтобы воссоздать эту небольшую проблему, я использую этот код (да, он был грубым и может быть уменьшен):

char hello[] = "John";
char *ptr1 = &hello[0];
char *ptr2 = &hello[1];
char *ptr3 = &hello[2];
char *ptr4 = &hello[3];
std::cout << ptr1 << "$";
std::cout << ptr2 << "$";
std::cout << ptr3 << "$";
std::cout << ptr4 << "$";

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

John$ohn$hn$n$

Я понятия не имею, почему он принимает все элементы после указанного.

Любая помощь?

Теги:
arrays
pointers
char

5 ответов

1
Лучший ответ

Это потому, что вы печатаете указатель, а не то, на что оно указывает. И указатели char в программах на C часто указывают на начало char[] который представляет строку '\0' -terminated. Вот почему std::ostream (из которого cout является экземпляром) имеет перегруженный оператор << который выводит всю строку, вплоть до терминатора.

Чтобы напечатать только символ, сначала разыщите указатели:

std::cout << *ptr1 << "$";

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

char &ptr1 = hello[0];
1

Ваш вопрос, похоже, основан на некоторых совершенно необоснованных ожиданиях. Похоже, вы ожидали, что ваш код напечатает один символ для каждой строки cout <<... Но почему вы ожидали этого? То, что вы отправляете cout в свой код, на самом деле является указателем char *. Почему вы ожидали, что cout разыщет этот указатель для вас и напечатает символ? Ожидается, что будет выглядеть указатель на выходе (адрес), а не на значение символа.

Итак, вопрос, который вы действительно должны задавать, не "почему он печатает несколько символов из моего массива?". Вопрос, который вы действительно должны задавать, - "почему он печатает любого из моих персонажей вообще?". Вы никогда не разыменовали указатель. Однако вместо значения указателя вывод содержит последовательность объектов char которые указывал указатель. Т.е., по-видимому, cout решил разыграть ваш указатель для вас, даже если вы никогда явно не просили его об этом. Это вопрос, который вы должны задать: почему мой указатель получил разыменование?

И ответ заключается в том, что указатели [const] char * получают специальное обращение при отправке в cout с помощью оператора <<. Там специально выделена перегруженная версия << оператора, введенная специально для этой цели. Эта версия оператора << будет обрабатывать указатели char * как указывающие на начало строки C. И этот оператор будет выводить всю C-строку до нулевого символа-ограничителя. Это именно то, что происходит в вашем эксперименте.

Обратите внимание: если вы используете, например, любой другой тип указателя (например, int *), вы не увидите заостренного значения (или значений) на выходе. Вы увидите представление, зависящее от реализации, самого указателя.

1

ptr1 через ptr4 также являются указателями на символы, поэтому << будет рассматривать их как строки и печатать их как таковые, давая вам то, что вы видели.

Если вам просто нужны символы в каждом месте, строки формы:

char ch1 = hello[0];

будет работать, так как изменит вывод на:

std::cout << *ptr1 << "$";
  • 0
    Просто увидел твой ответ после того, как увидел Томаса. Спасибо за быстрый ответ.
0

Я не совсем уверен, но если он cout получает указатель на char, он будет печатать все до тех пор, пока он не достигнет пробела в памяти (строка символов стиля C), и если вы просто хотите напечатать символ, вы должны напечатать только содержимое переменной, то есть просто передать содержимое, а не местоположение памяти...

0

если вы хотите напечатать значение на определенном адресе, то:

std::cout << *ptr1 << "$";
std::cout << *ptr2 << "$";
std::cout << *ptr3 << "$";
std::cout << *ptr4 << "$";

Ещё вопросы

Сообщество Overcoder
Наверх
Меню