11_Pointers презентация

Содержание

План Лекция 11 План Указатели Указатели и массивы Динамические массивы Указатели на функции Указатели и параметры функций Сложные описания с указателями

Слайд 1Указатели
Алтайский государственный университет Факультет математики и ИТ Кафедра информатики
Барнаул 2014


Слайд 2План
Лекция 11
План
Указатели
Указатели и массивы
Динамические массивы Указатели на функции
Указатели и

параметры функций
Сложные описания с указателями



Слайд 3Несколько заданий для самопроверки



Слайд 4Три задания для самопроверки
Задание 1
Что выведет программа?
#include

void main() {
   int

i, M[3]={1};
   for(i=0;i<3;i++)
      printf(”%d”, M[i]);
}

100


Слайд 5Три задания для самопроверки
Задание 2
Какие из следующих описаний массивов являются корректными?
int

A[3]={1,3,5};

int B[3]={11,22};

int C[3]={0,1,2,3};

int D[1..3];

int M[3];

int N[]={10,20,30,40};

int P[3,5];

int Q[2][2]={{0},{0}};

Да

Да

Нет

Нет

Да

Да

Нет

Да


Слайд 6Три задания для самопроверки
Задание 3
В каком порядке в памяти располагаются элементы

описанного следующим образом массива?

int M[3][2];


a) A[1][1] A[1][2] A[2][1] A[2][2] A[3][1] A[3][2]

b) A[0][0] A[1][0] A[2][0] A[0][1] A[1][1] A[2][1]

c) A[0][0] A[0][1] A[1][0] A[1][1] A[2][0] A[2][1]

d) A[0][0] A[0][1] A[1][0] A[0][2] A[2][0] A[2][3]

Так


Слайд 7Указатели
Адреса переменных
Что такое указатель?
Значение NULL
Операции над указателями
Нетипизированные указатели
Указатели и const


Слайд 8Организация курса
Что такое адрес переменной?
Оперативная память организована как последовательность ячеек (байт)
Каждая

ячейка имеет собственный адрес (порядковый номер)
Адрес – целое число, чаще записываемое в шестнадцатеричной системе счисления










0x2c4b1

Память:

Адрес:

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6

0x2c4b7


Слайд 9Организация курса
Что такое адрес переменной?
Каждая переменная размещается в последовательных ячейках (количество

ячеек зависит от типа переменной)
Адрес переменной – адрес первой из этих ячеек










Память:

Адрес:


x



y



a


0x2c4b1

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6

0x2c4b7


Слайд 10Организация курса
Как получить адрес переменной?
Адрес переменной можно получить с помощью операции

&
Например, &x даст адрес x:

10


127

20031






Память:

Адрес:


x



y



a


0x2c4b1

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6

0x2c4b7

...
printf(“x=%d, &x=%p”, x, &x); ...

x=10, &x=2c4b1


Слайд 11Организация курса
Что такое указатель?
Указатель – переменная, хранящая адрес
10








Память:
Адрес:


x


p

0x2c4b1
Операция разадресации

* – обратная к операции &

0x2c4b1

0x2c4b2

0x2c4b8

0x2c4b9

0x2c4ba

0x2c4bb


int x; /*целая переменная*/ int *px; /*указатель*/ px = &x; /*присвоить адрес*/

int x=10, y; int *px; px = &x; /*взять адрес*/ y = *px; /*взять значение по адресу px, y=10*/
*px = 20; /* <=> x=20 */


Слайд 12Организация курса
Значение NULL
Помимо адресов, указатель может принимать специальное значение NULL, обозначающее

недействительный адрес



NULL – макроконстанта
NULL чаще всего (но не всегда!) равен 0
Разадресовывать указатель со значением NULL небезопасно!

int *px; /*указатель*/
px = NULL; /*присвоить NULL*/


Слайд 13Организация курса
Операции над указателями
Указатель может быть инициализирован


Указателю можно присваивать значение



Указатель можно

сравнивать: < > <= >= == != (т.е. вычислять отношения адресов)

int y, *px=NULL, *py=&y, *pz=py; /* инициализация */

int x=10, y=20, *px, *py;
px=&x;
py=px;

int x=10, y=20, *px=&x, *py=&y;
if( px == py ) ...


Слайд 14Организация курса
Операции над указателями
Указатель может складываться с целым числом N. Результат

сложения – адрес, смещенный на N компонент соответствующего типа относительно исходного


short x=10, *px=&x; /* инициализация */


Слайд 15Организация курса
Операции над указателями
Указатель может складываться с целым числом N. Результат

сложения – адрес, смещенный на N компонент соответствующего типа относительно исходного


short x=10, *px=&x; /* инициализация */
px=px+1;


Слайд 16Организация курса
Операции над указателями
Указатель может складываться с целым числом N. Результат

сложения – адрес, смещенный на N компонент соответствующего типа относительно исходного


short x=10, *px=&x; /* инициализация */
px=px+1;
px=px-2;

0


10


345





x



0x2c4b1

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6









px


0x2c4b1






Слайд 17Организация курса
Операции над указателями
Указатель может складываться с целым числом N. Результат

сложения – адрес, смещенный на N компонент соответствующего типа относительно исходного


short x=10, *px=&x; /* инициализация */
px=px+1;
px=px-2;
px++;

0


10


345





x



0x2c4b1

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6









px


0x2c4b3






Слайд 18Организация курса
Операции над указателями
Указатель может складываться с целым числом N. Результат

сложения – адрес, смещенный на N компонент соответствующего типа относительно исходного


short x=10, *px=&x; /* инициализация */
px=px+1;
px=px-2;
px++; *(px+1)+=1;

0


10


346





x



0x2c4b1

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6









px


0x2c4b3






Слайд 19Организация курса
Операции над указателями
Можно вычислять разность однотипных указателей, которая равна относительному

смещению с учетом типа указателя


short *px=0x2c4b1, *py=0x2c4b5, d;
d = py-px; /* 2 */


Слайд 20Организация курса
Нетипизированный указатель
Типизированные указатели (int *, char *, double *, …)

неявно задают длину фрагмента памяти (4,1,8, …), начинающегося с адреса, хранимого указателем
Длина важна при разадресации и адресной арифметике
Однако иногда приходится использовать указатели, не подразумевая длины адресуемого фрагмента памяти – void *
Разадресация указателя void * невозможна!
Указатель void * совместим по типу со всеми типизированными указателями

int i=10, *pi=&i;
double d=3.14, *pd=&d;
void *p;
p=pi; /* Ok */
p=pd; /* Ok */
*p=*p+1; /* Ошибка! */


Слайд 21Организация курса
Указатели и const
Два способа описания константного указателя
Неизменяемый указатель
Синтаксис: TYPE *

const ptrName = &aTYPEVar;
Переменная-указатель – константа (не может изменяться)
Данные, адресуемые указателем – изменяемые

int a=42, b=42;
int* const ptr=&a;

*ptr=1; /* Ok */
ptr=&b /* Ошибка! */


Слайд 22Организация курса
Указатели и const
Два способа описания константного указателя
Указатель на неизменяемые данные
Синтаксис:

const TYPE * ptrName = &aTYPEVar;
Переменная-указатель – может изменяться
Данные, адресуемые указателем – неизменяемые

int a=42, b=42;
const int *ptr=&a;

*ptr=1; /* Ошибка! */
ptr=&b /* Оk */


Слайд 23Указатели и массивы
Указатели и массивы
Массивы как параметры функций
Указатели на многомерные массивы


Слайд 24Указатели и массивы
Указатели и массивы
Указатели и массивы очень тесно связаны в

языке Си
Имя массива – константный указатель на 0-й элемент массива




a[i] == *(a+i)

short a[100];
short *ps;

ps = &a[0];

short a[100];
short *ps;

ps = a;

<=>


Слайд 25Указатели и массивы
Указатели и массивы
a[i] == *(a+i) == *(i+a) == i[a]
a[2]

== *(a+2) == *(2+a) == 2[a]





short a[100];

for (i=0;i<100;i++)
scanf(“%h”,&a[i]);

short a[100];

for (i=0;i<100;i++)
scanf(“%h”,a+i);

<=>

short a[100];
short *ps;
for (ps=a;ps==a+100;ps++)
scanf(“%h”,ps);

<=>

short a[100];
short *ps=a;
for (i=0;i<100;i++)
scanf(“%h”,&ps[i]);

<=>


Слайд 26Указатели и массивы
Указатели и массивы
Синонимичные выражения






Передача массива в функцию как параметра


int a[10];

f(a); /* или */
f(&a[0]);

void f(int *array){
...
}

/*или*/
void f(int array[]){
...
}


Слайд 27Указатели и массивы
Указатели на многомерные массивы
Для вычисления адреса элемента двумерного массива

компилятору нужно «знать» количество столбцов в матрице (т.е. мало знать начальный адрес масива)
Пусть нужно передать в функцию массив int array[3][15], чтобы ее вызов выглядел так: f(array)
Возможны следующие идентичные варианты описания функции f:
f(int x[3][15]) { … }
f(int x[][15]) { … }
f(int (*x)[15]) { … }
Важно: в последнем случае нельзя опустить скобки!
f(int *x[15]) { … } – передается массив из 15 указателей на int, а не указатель на массив из 15 int-ов


Слайд 28Динамические массивы
Динамические массивы
Выделение памяти, malloc()
Освобождение памяти, free()


Слайд 29Динамические массивы
Динамические массивы
Часто размер массива заранее не известен, а известен лишь

в момент исполнения
Требуется динамически распределять массив в памяти
Стандартная функция malloc() позволяет запросить память у ОС
Для использования malloc() нужно подключать stdlib.h
Полный прототип функции: void *malloc(size_t size);



malloc() возвращает нетипизированный указатель на начальный байт выделенного массива. Для дальнейшего использования обычно указатель преобразуют в типизированный

Указатель на первый байт массива или NULL, если выделить память не удалось

Требуемое количество байт


Слайд 30Динамические массивы
Динамические массивы
Шаблон программы, использующей динамический массив
#include
#include

void main(){
int

*a;

/* Выделение 4 Мб памяти = 1Мб int-ов */
a = (int *)malloc(1024*1024*sizeof(int));

if(a == NULL) {
printf(“Ошибка выделения памяти.\n”);
return;
}

... /* Работа с элементами a[i] */

/* Освобождение памяти */
free(a);
}


Слайд 31Динамические массивы
Динамические массивы
Выделенную память необходимо освобождать
Стандартная функция free() позволяет освободить память

, выделенную malloc()
Блоки памяти освобождаются целиком, т.е. невозможно частичное освобождение (см. также функцию realloc())
Полный прототип функции: void free(void *ptr);

Адрес начала освобождаемого фрагмента памяти


Слайд 32Указатели на функции
Указатели на функции
Пример


Слайд 33Указатели на функции
Указатели на функции
Укaзатель на функцию содержит адрес тела функции
Как

описывается указатель на функцию?











Тип возвращаемого значения функции

Указатель на функцию

Тип параметра функции

Тип параметра функции

float myfun(int a, float b) {
return a+b;
}
...
float (*fptr)(int,float);
fptr = myfun;
...
x=fptr(42,3.14f);
...

Указатель на функцию, воспринимающую параметры типов int и float и возвращающую float

Вызов функции по указателю


Слайд 34Указатели на функции
Указатели на функции: пример
int add(int x, int y) {

return x+y; }
int sub(int x, int y) { return x-y; }
int mul(int x, int y) { return x*y; }
int div(int x, int y) { return x/y; }

int evaluate(unsigned int op, int x, int y) {
int (*eval[])(int, int) = { add, sub, mul, div };

if (op>3) {
printf(“Недопустимая операция”);
return 0;
}

return eval[op](x, y);
}

void main() {
printf(“%d\n”, evaluate(3, 42, 3));
}

Операции пронумерованы 0 – add, 1 – sub, 2 – mul, 3 – div

Массив из указателей на функции вида int f(int,int)

Вызов подходящей функции


Слайд 35Указатели и параметры функций
Указатели в параметрах функций


Слайд 36Указатели и параметры фугкций
Как передаются параметры через указатель?
В функцию передается не

значение, а адрес переменной

#include
void swap(int *x, int *y) {
int t;
t = *x; *x = *y; *y = t;
}
void main() {
int a=5, b=10;
swap(&a, &b);
printf(“a=%d, b=%d\n”, a, b);
}

Для доступа к значению переменной используется операция разадресации

При описании параметров функции используются указатели

При вызове функции как параметр передается адрес переменной


Слайд 37Указатели и параметры фугкций
Как изменить переменную в вызывающей функции?



a
b
x
5

10












#include
void swap(int

*x, int *y) {
int t;
t = *x; *x = *y; *y = t;
}
void main() {
int a=5, b=10;
swap(&a, &b);
printf(“a=%d, b=%d\n”, a, b);
}





y

t

x = &a; /*в х – адрес a*/ y = &b; /*в y – адрес a*/ t = *x; /*в t поместить значение, хранящееся по адресу x*/ *X = *y; /*по адресу x записать значение, хранящееся по адресу y*/ *y = t; /*по адресу y записать значение, хранящееся в t*/


Слайд 38Сложные описания с указателями
Сложные объявления
Правила чтения сложных объявлений
Класс памяти typedef


Слайд 39Сложные описания с указателями
Сложные описания с указателями
char **argv argv: указатель на указатель

на char
int (*x)[13] x: указатель на массив из 13 int-ов
int *x[13] x: массив из 13 указателей на int
void *comp() comp: функция, возвращающая указатель на void
void (*comp)() comp: указатель на функцию, возвращающую void
char (*(*x())())[5] x: функция, возвращающая указатель на массив из 5 указателей на функцию, возвращающую char
char (*(*x[3])())[5] x: массив из 3 указателей на функцию, возвращающую указатель на массив из 5 char-ов


Слайд 40Сложные описания с указателями
Сложные описания с указателями
Чтобы понять подобные сложные объявления

используйте следующие три правила:
Начинайте с имени переменной (d или foo в примерах выше)
Заканчивайте на имени типа (double или char выше)
Идите вправо пока можно, затем влево (влево необходимо идти при обнаружении закрывающейся скобки)
Например

double **d[8] /* хмм... */
char *(*(**foo [][8])())[] /* упс! что такое foo? */


Слайд 41Сложные описания с указателями
Сложные описания с указателями
Еще пример
double **d[8] /* хмм...

*/
char *(*(**foo [][8])())[] /* упс! что такое foo? */

Слайд 42Сложные описания с указателями
Сложные описания с указателями
Как можно упростить понимание сложных

объявлений?
Ответ: использовать оператор typedef

double **d[8] /* хмм... */
char *(*(**foo [][8])())[] /* упс! что такое foo? */

typedef float real; /* real – синоним float */
typedef unsigned char byte; /* byte – синоним unsigned char */
typedef int *INTPTR; /* INTPTR – синоним int* */
typedef void (*FUNCPTR)(); /* FUNCPTR – указатель на функцию */ /* с прототипом void f() */

real r=0.0; /* то же, что и float r=0.0 */
byte b=0; /* то же, что и unsigned char b=0 */
INTPTR p; /* то же, что и int *p */
FUNCPTR pf; /* то же, что и void (*pf)() */
FUNCPTR paf[10]; /* массив из указателей на функции void (*pf)() */


Слайд 43Вопросы и ответы
Вопросы?
Указатели
Указатели и массивы
Динамические массивы Указатели на функции
Указатели

и параметры функций
Сложные описания с указателями


Н.Копейкин Металлурги и компьютер


Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика