Проблема разыменования символьного указателя в C ++ - PullRequest
2 голосов
/ 06 марта 2011

У меня есть небольшое школьное задание.Мой вывод не верен.Вы видите, что я делаю что-то не так?

//1. Create a char pointer named cp
char *cp;

//2. Dynamically allocate a char and store its address in cp
char dynamicChar = 'A';
cp = &dynamicChar;

//3. Write the character 'x' into the char
*cp = 'x';

//4. Print out the value of the char using cout
cout << cp << endl;

В распечатанном операторе печатается A@@ вместо A.Я не уверен, что я делаю неправильно.

Ответы [ 3 ]

10 голосов
/ 06 марта 2011

Попробуйте

cout << *cp << endl;

Вы хотите напечатать символ , а не указатель на него. Когда вы вручаете ему указатель, cout думает, что вы говорите ему распечатать массив символов, начинающийся там.

5 голосов
/ 06 марта 2011

К сожалению, из своего происхождения языка программирования C, char * (т.е. указатели на символы) не рассматриваются как просто указатель на тип, такой как int * (указатель на int) или float * (указатель на float), но многие библиотечные функции обрабатывают их как строки с NUL-символами. Под «строкой» мы понимаем текст.

Таким образом, существует множество библиотечных функций, которые обрабатывают char * как особый случай и рассматривают их как «строку с нулевым символом в конце», то есть этот указатель будет обрабатываться как Массив (то есть несколько смежных) символов, пока он не достигнет символ NUL (т.е. числовое значение 0, а не символ '0', имеющий числовое значение байта 48 или 0x30).

Итак, если в вашем коде у вас есть

char *sz = "123";

это выделит 4 символа, 3, которые вы видите, плюс символ NUL

Addr:0x00050014 0x31  // ASCII char '1'
Addr:0x00050015 0x32  // ASCII char '2'
Addr:0x00050016 0x33  // ASCII char '3'
Addr:0x00050017 0x00  // ASCII char nul

sz (указатель на символ, представляющий адрес) будет иметь значение 0x00050014 (обратите внимание, что значение начального адреса определяется вашим компьютером через несколько шагов через компилятор, затем компоновщик, затем загрузчик, затем, возможно, сама прогрма).

Когда вы делаете cout << sz << endl; программа интерпретирует указатель на символ как указатель на буфер символов с нулевым символом в конце и выводит строку символов 123 к выходному потоку cout. Он просматривает значение по адресу 0x00050014 и видит, имеет ли его NUL (то есть 0), если нет, выводит символ, а затем просматривает следующий адрес. Если 0x00050015 не является NUL, он выводит его. Затем значение 0x00050016 видит, что оно не равно NUL, выводит его, затем оно достигает 0x00050017 и видит, что оно равно NUL, и НЕ выводит его, и перестает просматривать адреса и возвращается к ВАШЕМУ коду сразу после того, где вы это сделали вывод sz, в частности, в этом коде, он вернется к точке, где он сбросит endl (конец строки) в cout;

В конечном итоге вы узнаете лучшие способы представления текста, чем старый механизм char * в стиле C, но сейчас вам просто нужно понять существующее поведение, которое существует.

3 голосов
/ 06 марта 2011

C ++ (или, более конкретно, ostream в данном случае) автоматически обрабатывает char* как строку (стиль C).Вам необходимо явно привести его к нужному типу, например:

cout << (void*)cp << endl;

, если вы хотите значение указатель , или

cout << *cp << endl;

, если хотитесам персонаж (как показывает ваш вопрос).

...