Опубликован: 14.12.2010 | Уровень: для всех | Доступ: свободно
Лекция 8:

Указатели в языке программирования С

< Лекция 7 || Лекция 8: 123 || Лекция 9 >

Пример 6. Напишите программу по реализации условия: определить и инициализировать переменную типа double. Определите указатели типа char *, int *, double *, void *, инициализируйте их адресом переменной. Выведите на экран пользователя значения указателей, их размеры и длины участков памяти, которые связаны с выражениями, разыменовывающими указатели [7.5].

Программный код решения примера:

#include <stdio.h>
#include <conio.h>

int main (void) {
	double d = 6.78;
	char *cp; 
	int *ip; 
	double *dp; 
	void *vp; 
// Адресация с приведением типов
	cp = (char *)&d;
	ip = (int *)&d;
	dp = (double *)&d;
	vp = &d;
	printf("\n\t Address:\n\t char = %p\n\t int = %p\n\t double = %p\n\t void = %p\n", cp, ip, dp, vp);

// Размеры указателей и памяти разыменованных указателей:
printf("\n\t The dimension of the object type \"pointer\":\n\t char = %d\n\t int = %d\n\t double = %d\n\t void = %d\n", 
	   sizeof(cp), sizeof(ip), sizeof(dp), sizeof(vp));
	
printf("\n\t The size of the memory pointer:\n\t char = %d\n\t int = %d\n\t double = %d\n", 
	   sizeof(*cp), sizeof(*ip), sizeof(*dp));

	printf("\n Press any key: ");
	_getch();
	return 0; 
}

Результат выполнения программы показан на рис. 7.6.

Адреса и размеры указателей разных типов

Рис. 7.6. Адреса и размеры указателей разных типов

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

  1. В программу добавьте вывод размера памяти для разыменованного указателя типа void.
  2. Выведите значения указателей заданных типов. Определите указатель с правильным доступом к значению переменной d = 6.78.
  3. Объявление указателей и взятие адреса сделайте в одной строчке для соответствующего типа.
  4. В программу добавьте строки по вводу целого, вещественного типов данных, а также одиночного символа. Затем с помощью указателей выведите на консоль значения введенных данных.

Пример 7. Напишите программу, в которой с помощью указателя и функции scanf_s() читаются данные с клавиатуры, а также определяются и инициализируются указатели на константы и константные указатели. Программный код решения примера:

#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

int main (void) {
	double x,
		*px = &x,
		e = exp(1);
	const double pi = acos(0.0);
	
     const double *pexp = &e;
	const int base = 10;
	const int *const pbase = &base;
	const double *ptr_pi = &pi;
	int i;
	time_t t;

	printf("\n Enter a real number: ");
	scanf_s("%lf", px);

	printf("\n The value of the entered number is \"%g\"\n", x);

	printf("\n The base of natural logarithms \
is \"%0.14f\"\n", *pexp);

printf("\n The base of the decimal logarithm is \"%d\"\n",\ *pbase); 

	srand((unsigned) time(&t)); // рандомизация
	for (i = 0; i < rand(); i++)
	{
		rand();
	}
// Случайное вещественное число из интервала [-100.0; 100.0]
	x =  -100.0 + (100.0 - (-100.0))* (double)rand() / RAND_MAX;

	printf("\n The modified value of x: %g\n \
Pointer to the variable x: %g\n", x, *px);

	printf("\n The value of pi through the pointer \
and the function acos(0): %0.14f\n", *ptr_pi * 2);


	printf("\n\n ... Press any key: ");
	_getch();
	return 0;

}

В программе для получения числа пи ( \pi ) используется функция acos(0), так как косинус \pi /2 равен нулю. Затем полученный результат умножается на два. Дополнительная рандомизация осуществляется в цикле, одним из параметров которого является случайная функция rand(), возвращающая целое число. При этом предусмотрено приведение типов. Изменение числа х осуществляется по равномерному случайному закону из интервала [-100.0; 100.0].

Возможный результат выполнения программы показан на рис. 7.7.

Пример работы программы с указателями

Рис. 7.7. Пример работы программы с указателями

Задание 7

  1. Выполните инкрементирование указателей на константы и константных указателей. Объясните полученный результат.
  2. Введите в программу двойной ввод с клавиатуры вещественного числа. Первый раз с помощью указателя, а второй раз с помощью переменной. В обоих случаях вывести на печать значения указателя.
  3. В качестве константы примите некоторое шестнадцатеричное число (с буквами). Определите указатель на константу и в цикле от 1 до 16 измените значение указателя с последующим выводом результатов на консоль.
  4. Выполните возможные арифметические операции с константными указателями и с указателями на константы.
  5. В программу введите строковую переменную, определенную через фамилию (буквами латинского алфавита) автора закона всемирного тяготения. Определите указатель на константу и выведите фамилию на консоль через указатель. Затем в цикле введите известные вам фамилии трех лауреатов нобелевской премии по литературе. Вывод результатов на консоль выполните с помощью указателя.

Контрольные вопросы

  1. Какое общее назначение указателей в языке С?
  2. Какие арифметические операции допускаются для указателей?
  3. Какие унарные операторы используются с указателями? Как они называются?
  4. Для каких типов данных может быть использован указатель?
  5. Как числовые значения указателей изменяются при их инкрементировании в зависимости от типов данных.
  6. С помощью какого формата осуществляется вывод на консоль адресов переменных заданного типа?
  7. Что такое многоуровневая адресация? Как она организуется в языке С?
  8. Как осуществляется инициализация указателей на вещественные типы данных?
  9. Как осуществляется инициализация указателей на символьный тип данных?
  10. Какой смысл имеет значение указателя NULL?
  11. Что произойдет, если применить к указателю со значением NULL операцию разыменования?
  12. Как следует определять и инициализировать указателя на константу?
  13. Как следует определять и инициализировать константный указатель?
  14. Какое отличие константного указателя от указателя на константу?
< Лекция 7 || Лекция 8: 123 || Лекция 9 >
Мухаммадюсуф Курбонов
Мухаммадюсуф Курбонов