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