Цель работы - получение навыков использования указателей
Под сам указатель (там, где хранится адрес) также должна быть выделена память. Объем этой памяти можно узнать с помощью функции sizeof():
int *pi, i=5;
float *pf, f=2.1f;
printf("%lu\n", sizeof(pi));
printf("%lu\n", sizeof(pf));
Под указатели всех типов выделяется одинаковый объем памяти, т. к. размер адреса не зависит от типа, а зависит от вычислительной системы. Однако по типу данных определяется, сколько ячеек памяти занимает значение, на которое ссылается указатель, и через сколько ячеек начнется следующее значение.
int main()
{
float PI=3.14159,*p1,*p2;
p1=p2=Π
printf("По адресу p1=%p хранится *p1=%g\n",p1,*p1);
printf("По адресу p2=%p хранится *p2=%g\n",p2,*p2);
}
Обратите внимание на спецификатор формата %p. Он используется для вывода значений указателей в функции printf. Но поскольку указатель – это адрес, т. е. целое положительное число, то в зависимости от ситуации можно использовать любые спецификаторы целочисленных переменных. Для наглядности результатов используйте спецификатор %x – для вывода шестнадцатеричном коде.
int *pа, x=5;
pа = &x;
printf("По адресу %p хранится *ptr=%g\n",pa,*pa);
pа++;
printf("По адресу %p хранится *ptr=%g\n",pa,*pa);
pа--;
printf("По адресу %p хранится *ptr=%g\n",pa,*pa);
Измените тип данных на double и посмотрите, как изменятся значения (на сколько байт смещается указатель после инкремента\декремента)
Измените тип данных на char и сравните результаты с предыдущими (на сколько байт смещается указатель после инкремента\декремента)
Исследуйте изменение указателей типа long double, short unsigned int, _Bool.
Перед выполнением операций обязательно выполните инициализацию указателей через разыменование (&) инициализированных переменных того же типа.
float array[10]={1.1, 2.2, 3.3, 4.4 ...};
float *ptr_a;
4.1 Убедитесь, что имя массива в действительности является его адресом, т.е напечатайте значения array, &array[0], &array; с помощью спецификатора %p.
4.2 Установите указатель на начало массива ptr_a и выполните операции, одновременно напечатав значение указателя и то, на что он указывает (*ptr_a):
ptr_a ++; ptr_a+4; ptr_a-2
4.3 Напишите цикл прохода по массиву с помощью указателя с прямом порядке с увеличением указателя на 2
4.4 Выполните проход по массиву в обратном порядке, предварительно установив указатель на конец массива с использованием операции декремента
Листинг программы побайтового вывода целого числа
Рисунок. Распределение байтов одного слова в памяти -А ) с наименьшего адреса ("big-endian" - обратное размещение байтов или MSB – Most Significant Byte) – байт с наибольшей значащей частью
B) с наибольшего адреса ("little-end" - прямое размещение байтов))
1. Сделайте вывод о порядке размещения байтов в текущей системе.
2. Усовершенствуйте программу так, чтобы она могла побайтно выводить переменные любого типа.
3. Сравните код рационального числа, например 12345.0 заданного переменными различного типа int, float и double
Напишите программу, которая вычисляет размер основных типов данных в байтах:
1) char
2) short int
3) unsigned short int
4) int
5) unsigned char
6) wchar_t
7) long long int
8) size_t
9) float
10) double
11) signed int
12)
!НЕЛЬЗЯ ПОЛЬЗОВАТЬСЯ sizeof и КОНСТАНТАМИ ИЗ limits.h и float.h