Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на С.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

Занятие 16. Указатели.

Сегодня у нас важная и сложная тема. Возможно, самая сложная тема за все время. Указатели. Прежде вспомним основы шестнадцатеричной системы счисления.

Любое число в 16-тиричной системе счисления записывается с помощью символов 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. Шестнадцатеричной она называется, потому что в ней для записи различных чисел используются 16 основных цифр. Например, в привычной нами десятичной системе счисления используется десять основных цифр 0,1,2,3,4,5,6,7,8 и 9.

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

A=10

B=11

C=12

D=13

E=14

F=15.

Перевод числа из шестнадцатеричной системы счисления в десятичную.

Пусть у нас есть число 2D5. И мы хотим узнать, сколько это в нашей десятичной системе счисления.

Для этого сначала разделим число на цифры: 2 D 5

Теперь заменим все буквы, на их числовые обозначения: 2 13 5

Пронумеруем эти цифры справа налево начиная с нуля. 2 13 5

2 1 0

Умножим каждую из цифр, на 16 в степени, соответствующей порядковому номеру. И сложим все это между собой.

Рис.1 Перевод шестнадцатеричного числа в десятичную систему счисления

Рис.2 Перевод из 10-ой в 16-ричную

В результате получим 725. Это и есть число 2D5 в десятичной системе счисления.

Перевод числа из десятичной в шестнадцатеричную систему счисления.

Давайте переведем число 725 обратно в шестнадцатеричную систему счисления. В результате у нас должно получится 2D5.

Для перевода, нам необходимо поделить с остатком число 725 на 16 в столбик. Получим 45 и остаток 5.

Теперь делим 45 на 16 с остатком. Получим 2 и остаток 13. Оба числа меньше 16 значит на этом можно закончить деление.

Теперь записываем эти числа в обратном порядке и заменяем буквами соответствующие.

Как вы уже успели заметить, мы получили то, что и ожидали 2D5.

А теперь посмотрите на следующее число 235. Оно может быть как числом в десятичной, так и в шестнадцатеричной системе счисления. А кстати, чему будет равно число 235 в шестнадцатеричной системе счисления при переводе в десятичную систему? Переведите самостоятельно, посмотрите сколь велико отличие.

Нужно как-то уметь отличать. Для этого используются специальные обозначения. Одним из способов является запись в которой шестнадцатеричному числу предшествует пара символов «0х». Т.е. запись 0х235 говорит нам, что 235 это число, записанное в шестнадцатеричной системе счисления.

Переменные и их адреса.

Как отмечалось во втором уроке, каждая переменная хранится в памяти. Естественно у каждой переменной в памяти есть свой адрес, по которому она записана. Мы уже даже использовали адреса переменных, когда пользовались функцией scanf().

Чтобы получить адрес переменной нам необходимо перед её именем написать символ “&”.

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

Рис.3 Пример представления памяти компьютера

Как мы уже знаем, каждая переменная в зависимости от её типа, она занимает в памяти различное количество байт. Ну или в нашей интерпретации ячеек. Для того, чтобы узнать размеры различных типов переменных можно использовать функцию sizeof(). Ниже представлена программа, иллюстрирующая её использование.

Листинг 16.1

#include <stdio.h>

int main (){

printf ("razmer peremennoi tipa char %d\n", sizeof(char));

printf ("razmer peremennoi tipa int %d\n", sizeof(int));

printf ("razmer peremennoi tipa float %d\n", sizeof(float));

printf ("razmer peremennoi tipa double %d\n", sizeof(double));

return(0);

}

Результат её работы:

Рис 4. Программа иллюстрирующая работу sizeof()

У вас данные цифры могут быть другими кстати. Так как стандартом языка не оговаривается какой тип сколько должен занимать в памяти. Оговариваются только из соотношения. Например, размер double не должен быть меньше чем размер float.

То есть, если я объявляю в программе переменную типа int, то под нее в памяти выделяется 4 байта (ячейки).

Так как мы уже умеем получать адрес переменной, то давайте посмотрим на него. Для того, чтобы вывести число в шестнадцатеричной системе существует специальный спецификатор “%x”. И для него есть модификатор “#” при его записи, шестнадцатеричное число выводится с символами «0х».

Листинг 16.2

#include <stdio.h>

int main (){

int a,b;

printf ("adres peremennoi a %#x\n", &a);

printf ("adres peremennoi b %#x\n", &b);

return(0);}

Рис.5 Адреса переменных в памяти

Мы получили два адреса 0x12ff60 и 0x12ff56. По этим адресам в памяти записаны наши переменные a и b. При этом они занимают в памяти по 4 клетки подряд, так как это переменные целого типа и из рисунка 3 видно, что их размер 4 байта. Это выглядит примерно следующим образом.

Рис.6. Пример расположения переменных в памяти

Как вы уже заметили, переменные в память записываются не одна за другой, а в произвольном месте, лишь бы там было пусто и хватило места. Исключение составляют массивы. Они записываются в память последовательно. Посмотрите на результат работы следующей программы.

Листинг 16.3

#include <stdio.h>

int main (){

int a[3];

printf ("adres peremennoi a[0] %#x\n", &a[0]);

printf ("adres peremennoi a[1] %#x\n", &a[1]);

return(0);

}

Рис.7 Расположение массива в памяти

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

Адреса это хорошо, но что с ними делать? На кой чёрт они нам сдались?

Обо всем по порядку.