Разделы презентаций


Указатели

Содержание

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

Слайды и текст этой презентации

Слайд 1Указатели
Алтайский государственный университет Математический факультет Кафедра информатики
Барнаул 2013

УказателиАлтайский государственный университет Математический факультет Кафедра информатикиБарнаул 2013

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

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


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

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

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

Слайд 4Три задания для самопроверки
Задание 1
Какие из следующих описаний массивов являются

корректными?
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}};
Да
Да
Нет
Нет
Да
Да
Нет
Да

Три задания для самопроверкиЗадание 1Какие из следующих описаний массивов являются корректными?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

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

void main() {
  

int i, M[3]={1};
   for(i=0;i

Три задания для самопроверкиЗадание 2Что выведет программа?#include void main() {   int i, M[3]={1};    for(i=0;i

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


#define N 1000
void main() {
   int i, M[N], S1=0, S2=0;



   for(i=0; i M[i]=rand()%100;

   for(i=0; i S1+=M[i];
S1/=N;

   for(i=N/2; i S2+=M[i];
S1/=N;

   printf(”%d\n”, S1}
Три задания для самопроверкиЗадание 3Что делает программа? Что стоит исправить?#include #define N 1000void main() {   int i,

Слайд 7Три задания для самопроверки
Задание 4
В каком порядке в памяти располагаются

элементы описанного следующим образом массива?
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]

Так

Три задания для самопроверкиЗадание 4В каком порядке в памяти располагаются элементы описанного следующим образом массива? int M[3][2];

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

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

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

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

чаще записываемое в шестнадцатеричной системе счисления

0x2c4b1

Память:

Адрес:

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6

0x2c4b7

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

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

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

из этих ячеек


Память:

Адрес:

x

y

a

0x2c4b1

0x2c4b2

0x2c4b3

0x2c4b4

0x2c4b5

0x2c4b6

0x2c4b7

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

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

операции &
Например, &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
Организация курсаКак получить адрес переменной?Адрес переменной можно получить с помощью операции &Например, &x даст адрес x:1012720031 Память:Адрес:xya0x2c4b10x2c4b20x2c4b30x2c4b40x2c4b50x2c4b60x2c4b7...printf(“x=%d,

Слайд 12Организация курса
Что такое указатель?
Указатель – переменная, хранящая адрес
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 */

Организация курсаЧто такое указатель?Указатель – переменная,  хранящая адрес  10…Память:Адрес:…xp0x2c4b1Операция разадресации * – обратная к операции

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

обозначающее недействительный адрес



NULL – макроконстанта
NULL чаще всего (но не

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

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

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

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


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



Указатель

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

адресов)

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 ) ...

Организация курсаОперации над указателямиУказатель может быть инициализированУказателю можно присваивать значениеУказатель можно сравнивать: < > = == !=

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

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

относительно исходного


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

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

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

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

относительно исходного


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

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

Слайд 17Организация курса
Операции над указателями
Указатель может складываться с целым числом 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


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

Слайд 18Организация курса
Операции над указателями
Указатель может складываться с целым числом 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


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

Слайд 19Организация курса
Операции над указателями
Указатель может складываться с целым числом 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


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

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

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


short *px=0x2c4b1, *py=0x2c4b5, d;
d

= py-px; /* 2 */
Организация курсаОперации над указателямиМожно вычислять разность однотипных указателей, которая равна относительному смещению с учетом типа указателяshort *px=0x2c4b1,

Слайд 21Организация курса
Нетипизированный указатель
Типизированные указатели (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; /* Ошибка! */

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

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

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

адресуемые указателем – изменяемые

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

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

Организация курсаУказатели и constДва способа описания константного указателяНеизменяемый указательСинтаксис: TYPE * const ptrName = &aTYPEVar;Переменная-указатель – константа

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

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

адресуемые указателем – неизменяемые

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

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

Организация курсаУказатели и constДва способа описания константного указателяУказатель на неизменяемые данныеСинтаксис: const TYPE * ptrName = &aTYPEVar;Переменная-указатель

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

массивы

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

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

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

массива




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

short a[100];
short *ps;

ps = &a[0];

short a[100];
short *ps;

ps = a;

<=>

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

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

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





short a[100];

for (i=0;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]);

<=>

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

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






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

параметра
int a[10];

f(a); /* или */
f(&a[0]);
void f(int *array){

...
}

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

Указатели и массивыУказатели и массивыСинонимичные выраженияПередача массива в функцию как параметра int a[10];f(a);   /* или

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

массива компилятору нужно «знать» количество столбцов в матрице (т.е. мало

знать начальный адрес масива)
Пусть нужно передать в функцию массив 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-ов

Указатели и массивыУказатели на многомерные массивыДля вычисления адреса элемента двумерного массива компилятору нужно «знать» количество столбцов в

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

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

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

лишь в момент исполнения
Требуется динамически распределять массив в памяти
Стандартная функция

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



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

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

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

Динамические массивыДинамические массивыЧасто размер массива заранее не известен, а известен лишь в момент исполненияТребуется динамически распределять массив

Слайд 31Динамические массивы
Динамические массивы
Шаблон программы, использующей динамический массив
#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);
}

Динамические массивыДинамические массивыШаблон программы, использующей динамический массив#include #include void main(){ int *a; /* Выделение 4 Мб памяти

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

память , выделенную malloc()
Блоки памяти освобождаются целиком, т.е. невозможно частичное

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

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

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

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

Указатели на функцииУказатели на функцииПример

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

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











Тип возвращаемого значения функции
Указатель на функцию
Тип

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

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

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

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

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

Указатели на функцииУказатели на функцииУкaзатель на функцию содержит адрес тела функцииКак описывается указатель на функцию?Тип возвращаемого значения

Слайд 35Указатели на функции
Указатели на функции: пример
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)

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

Указатели на функцииУказатели на функции: примерint add(int x, int y) { return x+y; }int sub(int x, int

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

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

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

не значение, а адрес переменной
#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);
}

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

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

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

Указатели и параметры фугкцийКак передаются параметры  через указатель?В функцию передается не значение, а адрес переменной#include void

Слайд 38Указатели и параметры фугкций
Как изменить переменную в вызывающей функции?
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*/

Указатели и параметры фугкцийКак изменить переменную в вызывающей функции?abx510#include void swap(int *x, int *y) { int t;

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

typedef

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

Слайд 40Сложные описания с указателями
Сложные описания с указателями
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-ов

Сложные описания с указателямиСложные описания с указателямиchar **argv	argv: указатель на указатель на char	int (*x)[13]	x: указатель на массив

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

объявления используйте следующие три правила:
Начинайте с имени переменной (d

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

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

Сложные описания с указателямиСложные описания с указателямиЧтобы понять подобные сложные объявления используйте следующие три правила: Начинайте с

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

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

Сложные описания с указателямиСложные описания с указателямиЕще примерdouble **d[8] /* хмм... */char *(*(**foo [][8])())[] /* упс! что

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

сложных объявлений?
Ответ: использовать оператор 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)() */

Сложные описания с указателямиСложные описания с указателямиКак можно упростить понимание сложных объявлений?Ответ: использовать оператор typedefdouble **d[8] /*

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


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


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

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

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

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

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

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

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


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

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