Но, к счастью для нас, выражение вида array + n будет всегда указывать на элемент array[ n ], независимо от размера элемента, поскольку в таком выражении С++ самостоятельно учитывает длину элемента.
И вновь обратимся за аналогией к моему дому. Третий дом от 123 Main Street будет иметь адрес 126 Main Street, независимо от размеров стоящих на Main Street домов.
Отличия между указателями и массивами...122
В использовании массива и указателя есть несколько отличий. Во-первых, объявление массива вызывает выделение памяти для всего массива, тогда как объявление указателя не требует выделения памяти для массива.
void arrayPointer( )
{
/* Выделение памяти для 128 символов */
char charArray[ 128 ] ;
/* Выделение памяти для указателя, но не для объекта, на который он указывает */
char* pArray ;
}
_________________
122 стр. Часть 2. Становимся функциональными программистами
В этом примере для charArray выделяется 128 байт, а для pArray — четыре, ровно столько, сколько необходимо для хранения указателя. Приведённая ниже функция работать не будет.
void arrayVsPointer( )
{
/* Этот фрагмент будет работать нормально */
char charArray[ 128 ] ;
charArray[ 10 ] = '0' ;
*( charArray + 10 ) = '0' ;
/* Этот фрагмент не будет работать так, как надо */
char* pArray ;
pArray[ 10 ] = '0' ;
*( pArray + 10 ) = '0' ;
}
Выражения charArray[ 10 ] и *( charArray + 10 ) с позиции компилятора эквивалентны и вполне законны. Те же выражения с использованием pArray являются бессмысленными. Несмотря на то что для С++ они являются законными, pArray не инициализирован как указатель на массив, а значит, память была выделена только для указателя. Таким образом, рАггау[ 10 ] и *( рАггау + 10 ) указывают на неизвестные и непредсказуемые значения.
«Неправильно инициализированные указатели обычно вызывают ошибку нарушения сегмента ( segment violation ). Эту ошибку вы иногда встречаете в повседневной работе со своими любимыми приложениями в своей любимой ( а может, и не очень ) операционной системе.»
[Советы]
Второе отличие между указателями и индексами массива состоит в том, что charArray — константа, тогда как pArray — нет. Приведённый ниже цикл for, который должен инициализировать значения элементов массива, тоже не будет работать.
void arrayVsPointer( )
{
char charArray[ 10 ] ;
for ( int i = 0 ; i < 10 ; i++ )
{
*charArray = '\0' ; /* Эта строка имеет смысл... */
charArray++ ; /* ... а эта нет */
}
}
Выражение charArray++ имеет не больше смысла, чем 10++. Правильно следует написать так:
void arrayVsPointer( )
{
char charArray[ 10 ] ;
char* pArray = charArray ;
for ( int i = 0 ; i < 10 ; i++ )
{
*pArray = '\0' ; /* Этот вариант будет работать так, как надо */
pArray++ ;
}
}
_________________
123 стр. Глава 9. Второе знакомство с указателями
►Объявление и использование массивов указателей...124
Если есть указатели на массивы, можно предположить, что существуют и массивы указателей. Именно их мы сейчас и рассмотрим.
Поскольку массив может содержать данные любого типа, он может состоять и из указателей. Массив указателей объявляется так: