3.9.2. Взаимосвязь массивов и указателей
3.9.2. Взаимосвязь массивов и указателей
Если мы имеем определение массива:
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
то что означает простое указание его имени в программе?
ia;
Использование идентификатора массива в программе эквивалентно указанию адреса его первого элемента:
ia;
ia[0]
Аналогично обратиться к значению первого элемента массива можно двумя способами:
// оба выражения возвращают первый элемент
*ia;
ia[0];
Чтобы взять адрес второго элемента массива, мы должны написать:
ia[1];
Как мы уже упоминали раньше, выражение
ia+1;
также дает адрес второго элемента массива. Соответственно, его значение дают нам следующие два способа:
*(ia+1);
ia[1];
Отметим разницу в выражениях:
*ia+1
и
*(ia+1);
Операция разыменования имеет более высокий приоритет, чем операция сложения (о приоритетах операций говорится в разделе 4.13). Поэтому первое выражение сначала разыменовывает переменную ia и получает первый элемент массива, а затем прибавляет к нему 1. Второе же выражение доставляет значение второго элемента.
Проход по массиву можно осуществлять с помощью индекса, как мы делали это в предыдущем разделе, или с помощью указателей. Например:
#include iostream
int main()
{
int ia[9] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
int *pbegin = ia;
int *pend = ia + 9;
while ( pbegin != pend ) {
cout *pbegin ;
++pbegin;
}
}
Указатель pbegin инициализируется адресом первого элемента массива. Каждый проход по циклу увеличивает этот указатель на 1, что означает смещение его на следующий элемент. Как понять, где остановиться? В нашем примере мы определили второй указатель pend и инициализировали его адресом, следующим за последним элементом массива ia. Как только значение pbegin станет равным pend, мы узнаем, что массив кончился. Перепишем эту программу так, чтобы начало и конец массива передавались параметрами в некую обобщенную функцию, которая умеет печатать массив любого размера:
#include iostream
void ia_print( int *pbegin, int *pend )
{
while ( pbegin != pend ) {
cout *pbegin ;
++pbegin;
}
}
int main()
{
int ia[9] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
ia_print( ia, ia + 9 );
}
Наша функция стала более универсальной, однако, она умеет работать только с массивами типа int. Есть способ снять и это ограничение: преобразовать данную функцию в шаблон (шаблоны были вкратце представлены в разделе 2.5):
#include iostream
template c1ass e1emType
void print( elemType *pbegin, elemType *pend )
{
while ( pbegin != pend ) {
cout *pbegin ;
++pbegin;
}
}
Теперь мы можем вызывать нашу функцию print() для печати массивов любого типа:
int main()
{
int ia[9] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
double da[4] = { 3.14, 6.28, 12.56, 25.12 };
string sa[3] = { "piglet", "eeyore", "pooh" };
print( ia, ia+9 );
print( da, da+4 );
print( sa, sa+3 );
}
Мы написали обобщенную функцию. Стандартная библиотека предоставляет набор обобщенных алгоритмов (мы уже упоминали об этом в разделе 3.4), реализованных подобным образом. Параметрами таких функций являются указатели на начало и конец массива, с которым они производят определенные действия. Вот, например, как выглядят вызовы обобщенного алгоритма сортировки:
#include a1gorithm
int main()
{
int ia[6] = { 107, 28, 3, 47, 104, 76 };
string sa[3] = { "piglet", "eeyore", "pooh" };
sort( ia, ia+6 );
sort( sa, sa+3 );
};
(Мы подробно остановимся на обобщенных алгоритмах в главе 12; в Приложении будут приведены примеры их использования.)
В стандартной библиотеке С++ содержится набор классов, которые инкапсулируют использование контейнеров и указателей. (Об этом говорилось в разделе 2.8.) В следующем разделе мы займемся стандартным контейнерным типом vector, являющимся объектно-ориентированной реализацией массива.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Другие типы указателей
Другие типы указателей Системный указатель обеспечивает доступ к системному объекту, но при выполнении некоторых операций нужно работать с данными, содержащимися внутри таких объектов. Для этого используются другие типы указателей. Но прежде чем рассказать о них, я
5.23 Взаимосвязь имен и адресов
5.23 Взаимосвязь имен и адресов Посмотрев на имя системы (fermat.math.yale.edu) и ее IP-адрес в нотации с точками (128.36.23.3), можно подумать, что части имени соответствуют номерам в нотации с точками. Однако на самом деле между ними нет никакой связи.Действительно, иногда системам
Основы указателей
Основы указателей СОМ, подобно DCE (Distributed Computing Environment – среда распределенных вычислений), ведет свое начало от языка программирования С. Хотя лишь немногие разработчики используют С для создания или использования компонентов СОМ, именно от С СОМ унаследовала синтаксис
7.3.4. Взаимосвязь между производственным процессом проекта и планом разработки ПО
7.3.4. Взаимосвязь между производственным процессом проекта и планом разработки ПО Описание производственного процесса проекта бывает, как правило, недостаточно конкретным для непосредственного выполнения. Хотя описание обычно определяет такие понятия, как роли (т. е.
Выбор указателей мыши
Выбор указателей мыши Указатели мыши в Vista выглядят изящно, но не совсем привычно. Если хотите, можете поменять и их. Для этого щелкните кнопкой мыши на ссылке Указатели мыши в окне Персонализация. В открывшемся окне вы увидите примеры указателей для выбранной схемы (рис.
R.4.6 Преобразования указателей
R.4.6 Преобразования указателей Всюду, где указатели (§R.8.2.1) присваиваются, инициализируются, сравниваются или используются иным образом, могут происходить следующие преобразования:Константное выражение (§R.5.19), которое сводится к нулю, преобразуется в указатель, обычно
3.5. Взаимосвязь классов и объектов.
3.5. Взаимосвязь классов и объектов. Отношения между классами и объектами Классы и объекты - это отдельные, но тесно связанные понятия. В частности, каждый объект является экземпляром какого-либо класса; класс может порождать любое число объектов. В большинстве
6.4. Хранение указателей в векторе
6.4. Хранение указателей в векторе ПроблемаС целью повышения эффективности или по другим причинам невозможно хранить копии объектов в vector, но их требуется как-то разместить.РешениеСохраните в vector указатели на объекты, а не копии самих объектов. Но при этом не забудьте
Взаимосвязь процессов, доменов приложений, контекстов и потоков
Взаимосвязь процессов, доменов приложений, контекстов и потоков В предыдущей главе обсуждалось понятие потока, который был определен, как путь исполнения в рамках выполняемого приложения. И хотя многие приложения .NET имеют только один поток и, тем не менее, оказываются
Совет 7. При использовании контейнеров указателей, для которых вызывался оператор new, не забудьте вызвать delete для указателей перед уничтожением контейнера
Совет 7. При использовании контейнеров указателей, для которых вызывался оператор new, не забудьте вызвать delete для указателей перед уничтожением контейнера Контейнеры STL отличаются умом и сообразительностью. Они поддерживают итераторы для перебора как в прямом, так и в
Описание указателей
Описание указателей Мы знаем, как описывать переменные типа int и других типов. Но как описать переменную типа "указатель"? На первый взгляд это можно сделать так: pointer ptr; /* неправильный способ описания указателя */Почему нельзя использовать такую запись? Потому
Б.4. Взаимосвязь с библиотечными функциями ввода-вывода
Б.4. Взаимосвязь с библиотечными функциями ввода-вывода Выше уже говорилось о том. что функции ввода-вывода стандартной библиотеки языка С реализованы на основе низкоуровневых функций. Иногда удобнее работать с одними, иногда — с другими.Если файл был открыт с помощью
7.9.4. Массивы указателей на функции
7.9.4. Массивы указателей на функции Можно объявить массив указателей на функции. Например:int (*testCases[10])();testCases – это массив из десяти элементов, каждый из которых является указателем на функцию, возвращающую значение типа int и не имеющую параметров.Подобные объявления
6.7 Преобразования Указателей
6.7 Преобразования Указателей Везде, где указатели присваиваются, инициализируются, сравниваются и т.д. могут выполняться следующие преобразовния.Константа 0 может преобразовываться в указатель, и грантируется, что это значение породит указатель, отлиный от указателя на
Типы указателей
Типы указателей PBoolean Тип указателя на boolean PByte Тип указателя на byte PShortint Тип указателя на shortint PChar Тип указателя на char PSmallint Тип указателя на smallint PWord Тип указателя на word PPointer Тип указателя на pointer PInteger Тип указателя на