Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2014_2015 / lab3_functions.pptx
Скачиваний:
48
Добавлен:
27.12.2015
Размер:
270.09 Кб
Скачать

Сам указатель-переменная тоже имеет адрес.

Поэтому, например, корректным будет такой фрагмент:

int var1, *ptr1,*ptr2=&var1; ptr1=(int*)&ptr2;

Здесь описываются два указателя-переменные и ptr2 инициализируется значением адреса переменной varl. Затем ptrl присваивается значение адреса, по которому в памяти располагается ptr2.

Особым типом указателя является указатель типа void *, называемый часто родовым (generic). Ключевое слово void говорит об отсутствии данных о размере объекта в памяти. Но компилятору для корректной интерпретации ссылки на память через указатели нужна информация о числе байт, участвующих в операции.

во всех случаях использования указателя,

описанного как void *, необходимо выполнить операцию явного приведения типа указателя. unsigned long block = 0xFFEEDDCCL;

void* ptr=█ char ch;

unsigned two bytes;

ch = * (char*) ptr; two_bytes = *( unsigned*) ptr;

Указатель-переменная ptr инициализируется значением адреса первого байта переменной block. При выполнении присваивания компилятору необходимо знать размер объекта справа от знака =. Эту информацию сообщают компилятору операции приведения типа void * к типу (char *), (unsigned *), (long int *). В первой операции присваивания операнд слева – это первый байт переменной block. Поэтому переменная ch становится равной 0хСС. (Напомним, что младший байт всегда

располагается в памяти по меньшему адресу.) Во второй

Для указателей-переменных разрешены следующие

операции:присваивание;

инкремент или декремент;сложение или вычитание;сравнение.

Язык С (С++) разрешает операцию сравнения указателей одинакового типа. При выполнении присваивания значение указателя в правой части выражения пересылается в ячейку памяти, отведенную для указателя в левой части.

Если к указателю, описанному как type * ptr; , прибавляется или отнимается константа N, значение ptr изменяется на N * sizeof(type). Разность двух указателей type * ptrl, * ptr2 – это разность их значений, поделенная на sizeof(type).

Использование механизма указателей - один из

способов доступа к элементам массива. Массив - это расположенные вплотную друг за другом в памяти элементы одного и того же типа. Каждый массив имеет имя, оно является указателем-константой, равной адресу начала массива (первого байта первого элемента массива). Можно: доступ к отдельным элементам массива по имени массива и индексу (порядковому номеру) элемента, рассматривая имя как указатель и используя операцию *.

Будут полностью эквивалентными ссылки на i-й элемент массива array (независимо от типа элемента) array [i] и *(array + i).

аrrау &аrrау[0], ((array + i) &аггау [i]).

Использование указателей дает несколько более

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

Имя двумерного массива является указателем-

константой

на

массив

указателей-констант.

Элементами массива

 

Для двумерного массива m

константы на начало

 

matrix[2][2]

указателями

возможны

следующие

первую и вторую строки

способы

индексации для

matrix[2], причем:

 

доступа к ij-му элементу

matrix[0] &matrix[0][0],

массива:

 

matrix[1] &matrix[1][0],

m[i][j],

 

matrix[2] &matrix[2][0].

*(m[i]+j)),

 

Как и для одномерных

*(*(m + i) +j)).

двумерного массива может помощью механизма указателей, причем "точкой

отсчета" может быть как самый первый элемент

массива, так и первый элемент каждой из строк, т. е.

Элементы массива - любой тип, в том числе и

указатели-переменные: для компактного располо- жения в памяти строк текста, структурных переменных и других "протяженных" объектов данных, такие массивы указателей удобны при динамическом управлении памятью.

Как и любой другой массив, массив указателей должен описываться, причем может выполняться инициализация отдельных элементов:

char * messages[20]; //массив указателей из 20 элементов

Каждый элемент массива messages имеет тип char *.

Число байт памяти, занимаемых элементом, зависит от модели памяти (2 или 4 байта).

Описание массива указателей с инициализацией: char * messages[ ] = {"Не открыт файл",

"Ошибка ввода", "Диск", "Тайм-аут",};

Компилятор резервирует место для 4 указателей. Они получают начальное значение, равное адресу начала в памяти соответствующих строковых литералов.

Существует принципиальное различие в расположении в памяти массива указателей и, на первый взгляд, подобного ему двухмерного массива типа char, например, такого:

char array [ ][16] = { "Не открыт файл", "Ошибка ввода", "Диск", "Тайм-аут", };

Преимущества использования массивов - появляется

возможность манипулировать не самими объектами, а только их адресами выигрыш в скорости выполнения программы. Объекты, с кот. работает программа, могут распола-гаться в выделяемой динамически области памяти.

Имя массива указателей является указателем- константой на I элемент массива. Первый элемент

массива сам является указателем имя массива указасторожно!!!елей является указателем а указатель.

В С (C++) м жно описать и переменную, имеющую тип "указатель на указатель". Приз ак м такого типа является повторение символа * при описании переменной. Число символов * определяет число "уровней" указателя. Фактически указатель на указатель – это ячейка памяти, хранящая адрес указателя. Размер области памяти, выделяемой для

такой переменной, зависит от модели памяти. При

Структурирование обработки данных: Составной

оператор ("блок", что эквивалентно) дает возможность использовать несколько операторов в том месте, где предполагается использование одного:

составной_оператор:

{

список_описаний optional список_операторов optional

}

Блоки могут быть вложенными список_описаний:

описание описание список_описаний

список_операторов: оператор

оператор список_операторов Если какой-либо из идентификаторов в

списке_описаний был ранее описан, то внешнее

описание выталкивается на время выполнения блока,

long k

Каждая инициализация auto или register переменных

производится всякий раз при входе в начало блока. В блок можно делать передачу; в этом случае инициализации не выполняются. Инициализации переменных, имеющих класс памяти static осуществляются только один раз в начале выполнения программы.

#include<stdio.h> long k=0;

void main()

{

int k=1;

 

 

 

 

 

 

int k

 

{

 

 

 

 

 

 

 

char k

 

 

printf(“%d”, k);

 

 

 

 

 

 

 

 

 

char k = 'A';

 

 

 

 

 

 

 

 

 

 

printf(“%c”, k);

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

printf(“%c”, k);

 

 

 

 

 

}

 

 

 

 

 

Соседние файлы в папке 2014_2015