Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика 1.docx
Скачиваний:
11
Добавлен:
26.09.2019
Размер:
364.88 Кб
Скачать

Указатель на void.

Всё вышесказанное применимо к указателям на любые типы, как простые, так и сложные. Отдельно выделяется лишь указатель на пустой тип, т.е. void*.

Указатель на пустой тип не может работать напрямую с памятью, т.к. непонятно какой размер имеет элементарная область, адресуемая этим указателем. Операции сложения/вычитания к нему также неприменимы. Но void* обладает одним важным свойством. В языке C указатель на какой-либо тип далеко не всегда может быть преобразован в указатель на какой-либо другой произвольный тип. Преобразование типа к void* можно осуществить для любого указателя. Это свойство удобно использовать при сравнении адресов, хранящихся в указателях на разные типы, и т.п.

Применение указателей для передачи данных между функциями.

Очень часто требуется, чтобы одна функция могла изменять переменные, относящиеся к другой. Например, в задачах сортировки часто бывает необходимо осуществить обмен значениями между двумя переменными. Предположим, что у нас есть две переменные х и у и нам надо создать функцию, производящую обмен значениями между этими двумя переменными. Тело функции создать весьма легко:

void change(int a, int b)

{

int m;

m=a;

a=b;

b=m;

}

Проблема заключается в том, что в ходе выполнения такой функции необходимо обновить значения у обоих переменных. Значения обоих передаваемых в функцию переменных при обычном вызове функции switch(x,y) не изменятся, т.к. их значения просто копируются в формальные аргументы а и b, с которыми потом уже производятся все манипуляции внутри функции. И по выходу из функции значения a и b просто потеряются, т.к. они никуда не возвращаются.

Можно переопределить функцию switch так, что она будет возвращать какое-либо из значений, например a:

int change(int a, int b)

{

int m;

m=a;

a=b;

b=m;

return a;

}

Но это тоже не решит всех проблем, т.к. по условию задачи нам нужно изменить ОБА значения, а оператор return позволяет возвращать только одно из них. В принципе, решить эту проблему можно с помощью глобальных переменных – используя их можно возвращать из функции несколько значений. Но такое решение будет громоздким и элегантным его назвать никак нельзя.

Стандартным решением такой задачи является использование указателей на переменные в качестве аргументов функции. В этом случае вместо значений переменных в функцию передаются их адреса, а внутри функции с помощью операции косвенной адресации по этим адресам извлекаются значения переменных.

Так, полное решение поставленной в начале раздела задачи будет выглядеть следующим образом:

void change(int *u, int *v)

{

int temp;

temp = *u; //записываем в temp значение, хранимое по адресу u

*u = *v; //записываем по адресу u значение, хранимое по адресу v

*v = temp; //записываем по адресу v значение, сохранённое в temp

return;

}

main ( )

{

int x = 5, y = 10;

printf (“Вначале x = %d и y = %d\n”, x, y);

change (&x, &y); // Вызов функции. В качестве аргументов

// передаём указатели на переменные.

printf (“Теперь x = %d и y = %d\n”, x,y);

return;

}

  1. Массивы. Элементы массивов, доступ к элементам массива. Имя массива как указатель. Массивы указателей.