«Поскольку * имеет более высокий приоритет, чем сложение, операция *ptr + n привела бы к сложению n со значением, на которое указывает ptr. Чтобы выполнить сначала сложение и лишь затем переход к переменной по указателю, следует использовать скобки. Выражение *( ptr + n ) возвращает элемент, который находится по адресу ptr плюс n элементов.»
[Атас!]
_________________
118 стр. Часть 2. Становимся функциональными программистами
В действительности соответствие между двумя формами выражений настолько строго, что С++ рассматривает элемент массива array[ n ] как *( ptr + n ), где ptr указывает на первый элемент array. С++ интерпретирует array[ n ] как *( &аrray [ 0 ] +n ). Таким образом, если дано char charArray[ 20 ], то charArray определяется как &charArray[ 0 ].
Имя массива, записанное без индекса элемента, интерпретируется как адрес нулевого элемента массива ( или просто адрес массива ). Таким образом, можно упростить приведённую выше запись, поскольку array[ n ] С++ интерпретирует как *( array + n ).
Использование операций над указателями для адресации внутри массива...119
Концепция соответствия между индексацией массива и арифметикой указателей весьма полезна.
Например, функция displayArray( ), которая выводит содержимое целочисленного массива, может быть реализована следующим образом:
/* displayArray — отображает элементы массива, имеющего длину nSize */
void displayArray( int intArray[ ] , int nSize )
{
cout << "Значения элементов массива равны:\n" ;
for ( int n = 0 ; n < nSize ; n++ )
{
cout << n << ": " << intArray[ n ] << "\n" ;
}
cout << "\n" ;
}
Эта версия функции использует операции над массивами, которые знакомы нам по предыдущим главам. Если воспользоваться для написания этой функции указателями, программа приобретёт такой вид:
/* displayArray — отображает элементы массива, имеющего длину nSize */
void displayArray( int intArray[ ] , int nSize )
{
cout << "Значения элементов массива равны:\n" ;
int* pArray = intArray ;
for ( int n = 0 ; n < nSize ; n++ , pArray++ )
{
cout << n << ": " << *pArray << "\n" ;
}
cout << "\n" ;
}
Этот вариант функции displayArray начинается с создания указателя на первый элемент массива intArray.
«Буква р в начале имени переменной означает, что эта переменная является указателем, однако это только соглашение, а не стандарт языка С++.»
[Помни!]
_________________
119 стр. Глава 9. Второе знакомство с указателями
После этого функция считывает все элементы массива по порядку. При каждом выполнении оператора for происходит вывод текущего элемента из массива intArray. Этот элемент находится по адресу рArray, который увеличивается на единицу при каждом выполнении цикла.
Убедиться в работоспособности описанной функции можно, используя её в следующей функции main( ):
int main( int nNumberOfArgs , char* pszArgs[ ] )
{
int array[ ] = { 4 , 3 , 2 , 1 } ;
displayArray( array , 4 ) ;
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
Результат работы этой программы имеет следующий вид:
Значения элементов массива равны:
0: 4
1: 3
2: 2
3: 1
Press any key to continue...
Можно сказать, что функция почти не изменилась и выполняет такие же операции, как и предыдущая версия, однако использование указателей — более распространённая практика, чем работа с массивами. По ряду причин программисты избегают работать с массивами. Чаще всего указатели используются для работы с символьными массивами.