Лекции по проге / 10_1_Указатели_Основы
.pdf
Адресная арифметика (вычитание указателей)
<переменная-указатель> - <переменная-указатель>
●Разность двух однотипных указателей дает количество элементов между ними
●Если из указателя на элемент массива вычесть указатель на начало массива, то результатом будет индекс элемента
21
Вычитание указателей
int array[15] = {4,1,2,9,4,5,6,7,8,3}; int *pointer = &array[9];
array |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0x04 |
0x00 |
0x00 |
0x00 |
|
… |
|
0x03 |
0x00 |
0x00 |
0x00 |
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
array[0] |
|
|
|
|
|
|
|
|
|
array[9] |
||||||
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pointer |
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int index = pointer — &array[0]; // index = 9
22
Задание
Определить, что напечатают на экране следующие программы
int i1 = 0; int i2 = 1; int * p1, *p2;
p1 = &i1;
p2 = &i2;
*p1 = *p2; (*p1)++;
printf("*p1=%d ", *p1); printf("*p2=%d\n", *p2); printf(" i1=%d ", i1);
23 printf(" i2=%d", i2);
int i1 = 0; int i2 = 1; int * p1, *p2;
p1 = &i1;
p2 = &i2;
p1 = p2; (*p1)++;
printf("*p1=%d ", *p1); printf("*p2=%d\n", *p2); printf(" i1=%d ", i1); printf(" i2=%d", i2);
Разница между присваиванием значения и адреса
int i1 = 0; int i2 = 1; int * p1, *p2;
p1 = &i1;
p2 = &i2;
*p1 = *p2;/* присваиваем значение */
(*p1)++;
printf("*p1=%d ", *p1); printf("*p2=%d\n", *p2); printf(" i1=%d ", i1); printf(" i2=%d", i2);
*p1=2 *p2=1 24 i1=2 i2=1
int i1 = 0; int i2 = 1; int * p1, *p2;
p1 = &i1;
p2 = &i2;
p1 = p2; /* присваиваем адрес */
(*p1)++;
printf("*p1=%d ", *p1); printf("*p2=%d\n", *p2); printf(" i1=%d ", i1); printf(" i2=%d", i2);
*p1=2 *p2=2 i1=0 i2=2
Разница между присваиванием значения и |
|||||||
|
|
|
адреса |
|
|
|
|
Присваивание значения |
Присваивание адреса |
||||||
i1 |
|
|
i2 |
i1 |
|
|
i2 |
0 |
p1 |
p2 |
1 |
0 |
p1 |
p2 |
1 |
|
*p1 = *p2 |
|
|
p1 = p2 |
|
||
1 |
p1 |
p2 |
1 |
0 |
p1 |
p2 |
1 |
|
(*p1)++ |
|
|
(*p1)++ |
|
||
2 |
p1 |
p2 |
1 |
0 |
p1 |
p2 |
2 |
25 |
|
|
|
|
|
|
|
Задание
Имеется целочисленная переменная number
На нее ссылается указатель void *pointer;
pointer 

23
number
Указать результат выражения pointer + 3
26
Операции над нетипизированными указателями
● Все операции с нетипизированными указателями, кроме присваивания, приводят к синтаксическим ошибкам
●Для выполнения операций над указателями компилятору нужно знать размер базового типа данных, а нетипизированный указатель его не имеет
●Таким образом нетипизированный указатель может только хранить адрес памяти — операции над ним
27 не допустимы
Приведение типов указателей
(<новый базовый тип> *) <переменная-указатель>
●Изменение типа указателя не приводит к изменению его значения
●Хранящийся в переменной адрес остается прежним, но компилятор запоминает, что указатель теперь ссылается на значение другого типа
●Это влияет на результаты операций адресной арифметики и обращения по адресу
28
Задание
Имеется целочисленная переменная number
На нее ссылается указатель void *pointer;
pointer 

23
number
Указать результат выражения
*( (char *)pointer + 3 ) = 9
29
Приведение типов указателей |
|||
int number = 23; |
// 0x17 в шестнадацатеричном |
||
|
|
// формате |
|
void *pointer = & number; |
|
||
*( (char *)pointer + 3 ) = 9; |
|
||
printf("%d", number); |
((char *)pointer + 3) |
||
|
|
|
|
pointer |
0x17 0x00 0x00 0x09 ... ... ... ... |
||
|
переменная number |
||
150994967 |
|
|
|
30 |
|
|
|
