Указатели в языке программирования С
Пример 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.
Как видно из полученного результата, размеры участков памяти, выделенных указателям разных типов, одинаковы.
- В программу добавьте вывод размера памяти для разыменованного указателя типа void.
- Выведите значения указателей заданных типов. Определите указатель с правильным доступом к значению переменной d = 6.78.
- Объявление указателей и взятие адреса сделайте в одной строчке для соответствующего типа.
- В программу добавьте строки по вводу целого, вещественного типов данных, а также одиночного символа. Затем с помощью указателей выведите на консоль значения введенных данных.
Пример 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 = π
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;
}В программе для получения числа пи (
) используется функция acos(0), так как косинус
/2 равен нулю. Затем полученный результат умножается на два. Дополнительная рандомизация осуществляется в цикле, одним из параметров которого является случайная функция rand(), возвращающая целое число. При этом предусмотрено приведение типов. Изменение числа х осуществляется по равномерному случайному закону из интервала [-100.0; 100.0].
Возможный результат выполнения программы показан на рис. 7.7.
Задание 7
- Выполните инкрементирование указателей на константы и константных указателей. Объясните полученный результат.
- Введите в программу двойной ввод с клавиатуры вещественного числа. Первый раз с помощью указателя, а второй раз с помощью переменной. В обоих случаях вывести на печать значения указателя.
- В качестве константы примите некоторое шестнадцатеричное число (с буквами). Определите указатель на константу и в цикле от 1 до 16 измените значение указателя с последующим выводом результатов на консоль.
- Выполните возможные арифметические операции с константными указателями и с указателями на константы.
- В программу введите строковую переменную, определенную через фамилию (буквами латинского алфавита) автора закона всемирного тяготения. Определите указатель на константу и выведите фамилию на консоль через указатель. Затем в цикле введите известные вам фамилии трех лауреатов нобелевской премии по литературе. Вывод результатов на консоль выполните с помощью указателя.
Контрольные вопросы
- Какое общее назначение указателей в языке С?
- Какие арифметические операции допускаются для указателей?
- Какие унарные операторы используются с указателями? Как они называются?
- Для каких типов данных может быть использован указатель?
- Как числовые значения указателей изменяются при их инкрементировании в зависимости от типов данных.
- С помощью какого формата осуществляется вывод на консоль адресов переменных заданного типа?
- Что такое многоуровневая адресация? Как она организуется в языке С?
- Как осуществляется инициализация указателей на вещественные типы данных?
- Как осуществляется инициализация указателей на символьный тип данных?
- Какой смысл имеет значение указателя NULL?
- Что произойдет, если применить к указателю со значением NULL операцию разыменования?
- Как следует определять и инициализировать указателя на константу?
- Как следует определять и инициализировать константный указатель?
- Какое отличие константного указателя от указателя на константу?

