Указатели и массивы
Понятия указателя и массива тесно связаны. Имя массива без индекса возвращает адрес первого элемента (имя_массива[0]). int *pm; int ma[10]; pm = ma; //два варианта получения адреса массива. pm = &ma[0];
int x; x = ma[2]; //доступ через индекс; x = *(ma +2); //доступ через адресную арифметику;
В С/С++ существуют два метода обращения к элементам массива: Ø Адресная арифметика; Ø Индексация массива. С помощью адресной арифметики часто можно сократить время доступа к элементам массива. Пример – посимвольный вывод строки. Признак конца – нуль-байт. //Индексация указателя s как массива int putstr(char *s) { for(int t=0; s[t]; t++) putchar(s[t]); }
// Использование адресной арифметики (вариант более профессиональный) int putstr(char *s) { while(*s) putchar(*s++); } Ø и ++ стоят на одном уровне иерархии операторов языка и выполняются последовательно слева направо. Ø Запись *s++ означает «выбрать значение переменной по адресу s, увеличить адрес на 1, то есть переход к следующему объекту заданного типа». Как объекты любых других типов, указатели могут быть собраны в массивы. int *x[10]; // массив из 10 указателей на объекты типа int; Для присвоения, например, адреса переменной var третьему элементу массива указателей, необходимо написать: int var = 232; int *x[10]; // массив из 10 указателей на объекты типа int; x[2] = &var; //запомнили адрес переменной var; int var1 = *x[2] – выбрали значение переменной var;
Пример многоуровневой адресации, когда указатель ссылается на указатель. 1) int **ptrx = &x[0]; // ptrx – указатель на массив указателей.
2) int i =123; // i – имя переменной. int *pi = &i; // pi – указатель на переменную i. int **ppi = π // ppi – указатель на «указатель на переменную». int ***pppi = &ppi; // pppi – указатель на «указатель» на «указатель на переменную».
Указатели часто инициализируются нулевым значением. В С/С++ часто бывает объявлен макрос NULL, являющийся нулевой указательной константой. int *ptri = 0; // два возможных варианта. int *ptri = NULL;
Указатели весьма небезопасны. Неправильное использование адреса может вызвать разрушение программы. int *ptri = NULL; *ptri = 10; //Крах программы! Системная ошибка, попытка записи в системную область памяти.
|