Взаимодействие Pointer-Array с нулевым терминатором - PullRequest
3 голосов
/ 19 августа 2011

Я просто экспериментировал с использованием указателей при работе с массивами, и я немного запутался в том, как C ++ обрабатывает массивы. Вот соответствующие фрагменты кода, который я написал:

//declare a string (as a pointer)
char* szString = "Randy";               

cout << "Display string using a pointer: ";
char* pszString = szString;
while (*pszString)
cout << *pszString++;

Прежде всего, когда я попытался использовать cout для записи того, что было в "pszString" (без разыменования), я был немного удивлен, увидев, что он дал мне строку. Я просто предположил, что это потому, что я дал указателю строку, а не переменную.

Что действительно привлекло мое внимание, так это то, что когда я убрал звездочку из строки cout << *pszString++;, она напечатала «Randyandyndydyy». Я не уверен, почему он пишет массив, а затем записывает его снова на 1 букву меньше. Я рассуждаю так: после написания строки символов оператор приращения немедленно переносит индекс на следующую букву, прежде чем он достигнет нулевого терминатора. Я не понимаю, почему нулевой терминатор не заставил бы цикл возвращать ложь после первого вывода строки в противном случае. Это правильное рассуждение? Может ли кто-нибудь объяснить, получаю ли я эту связь между массивами и указателями?

1 Ответ

6 голосов
/ 19 августа 2011

cout имеет перегрузку operator<< для char* для печати всей строки (то есть, для печати каждого символа, пока он не встретит 0).Напротив, перегрузка char для cout operator<< печатает только этот один символ.В этом и заключается разница.Если вам нужно больше объяснений, читайте дальше.

Когда вы разыменовываете указатель после его увеличения, вы отправляете cout a char, , а не и char*, поэтомупечатает один символ.

Так что cout << *pszString++; похоже на выполнение

cout << *pszString;
pszString = pszString + 1;

Когда вы не разыменовываете указатель, выотправив ему char*, чтобы cout печатал всю строку, и вы перемещаете начало строки на один символ в каждой итерации цикла.

Итак, cout << pszString++; - этокак делать

cout << pszString;
pszString = pszString + 1;

Иллюстрация с небольшой разверткой петли:

Для cout << *pszString++;

Randy\0
^ pszString points here

// this means increment pszString and send cout the character at which pszString *used* to be pointing
cout << *pszString++;

// so cout prints R and pszString now points
Randy\0
 ^ here

// this means increment pszString and send cout the character at which pszString *used* to be pointing
cout << *pszString++;

// so cout prints a and pszString now points
Randy\0
  ^ here

// and so on

Для cout << pszString++;

Randy\0
^ pszString points here

// this means increment pszString and pass the old pointer to cout's operator<<
cout << pszString++;

// so cout prints Randy, and now pszString points
Randy\0
 ^ here

cout << pszString++;

// cout prints andy, and now pszString points
Randy\0
  ^ here

// and so on

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

...