Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции по проге / 10_1_Указатели_Основы

.pdf
Скачиваний:
31
Добавлен:
14.03.2016
Размер:
213 Кб
Скачать

Адресная арифметика (вычитание указателей)

<переменная-указатель> - <переменная-указатель>

Разность двух однотипных указателей дает количество элементов между ними

Если из указателя на элемент массива вычесть указатель на начало массива, то результатом будет индекс элемента

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