C. Переменные
Время чтения: 7 минут
Одним из ключевых понятий в программировании является понятие переменная.
Переменные хранят значения, используемые в программе.
Типы переменных
Переменные могут быть следующих типов:
- char – целое число, которое занимает 1 байт
- int – целое число, которое занимает 4 байта
- float – вещественное число, которое занимает 4 байта
- double – вещественное число, которое занимает 8 байт
В зависимости от компилятора и разрядности системы (x64 или x86) размер типа int может занимать 2, 4 или 8 байт. Дальше в статье я покажу как узнать сколько он занимает на твоей машине.
Вот пример определения переменных в C:
// Можно так: ТИП ИМЯ;
char charVariable;
// или так: ТИП ИМЯ = ЗНАЧЕНИЕ;
int intVariable = 777;
// или так (больше одной переменной заданного типа): ТИП ИМЯ_ПЕРЕМЕННОЙ, ИМЯ_ДРУГОЙ_ПЕРЕМЕННОЙ;
int anotherIntVariable1, anotherIntVariable2;
// или так: ТИП ИМЯ_ПЕРЕМЕННОЙ = ЗНАЧЕНИЕ, ИМЯ_ДРУГОЙ_ПЕРЕМЕННОЙ;
float floatVariable = 983.223, anotherFloatVariable;
// Если после запятой у ещественного числа нет знаков, то можно вместо "766.0" написать просто "766."
double doubleVariable = 766.;
- Символ “=” означает операцию присваивания – она перезаписыват значение переменной на указанное. Его можно использовать не только при создании переменной, но и отдельно:
char charVariable;
charVariable = 42;
int a, b, c = 7;
// Вот так можно присвоить значение сразу наскольким переменным:
a = b = 24;
-
Имя переменной может содержать любые числа, латинские буквы (большие и маленькие) и символ “_”. При этом оно не должно начинаться с числа – так “777variable” нельзя.
-
В конце каждой строчки надо ставить “;” – это как “.” в конце предложения в русском.
-
Два слеша “//” обозначают начало комментария. Комментарии нужны для того, чтобы оставлять заметки в тексте программы, которые помогут понять что происходит. Комментарии не учитываются при исполнении кода программы.
А чего это я упомянул байты при описании типов? Дело в том, что количество байт ограничивает размер числа, которое мы можем “засунуть” в переменную.
Почему так происходит? Давай вспомним школьную информатику – вот представление целочисленных значений в бинарном виде:
Выходит, что чем больше байт мы выделяем под переменную, тем больше бит там будет, и тем большее число мы можем там записать. Вот минимальные и максимальные значения для всех типов:
- char: -128, 128
- int: -2147483647, 2147483648
- float: -3.410^38, 3.410^38
- double: -1.710^308, 1.710^308
Обрати внимание, что один бит в самом начале числа всегда занят под храниение знака. Представь, что ты всегда работаешь с положительными числами – зачем он тебе сдался в таком случае?
Специально для этого, существуют модификаторы типа.
Модификаторы типов переменных
Всего существует три модификатора:
- unsigned – превращает тип в беззнаковый (по умолчанию все типы со знаком)
- short – уменьшает стандартное количество байт типа
- long – увеличивает стандартное количество байт типа
Однако, не все типы можно использовать со всеми модификаторами. Вот все возможные комбинации:
- char – целое со знаком, 1 байт
- unsigned char – беззнаковое целое, 1 байт
- int – целое со знаком, 4 байт
- long int – целое со знаком, 4 байта
- unsigned long int – беззнаковое целое, 4 байта
- short int – целое со знаком, 2 байта
- unsigned short int – беззнаковое целое, 2 байта
- float – вещественное, 4 байта
- double – вещественное, 8 байт
- long double – вещественное, 16 байт
Может показаться сложным, но не надо их запоминать! Если тебе понадобятся модификаторы типов, то ты про них вспомнишь, посмотришь в интернете и выберешь нужный.
Ввод и вывод значения
Чтобы вводить и выводить значение, мы с тобой в первое время (потом из файла почитаем) будем использовать функции:
- printf – форматированный вывод, выводит в консоль строку
- scanf – форматированный ввод, обеспечивает запись введённого с клавиатуры значения в переменную
Как с ними работать? Вот так:
int x;
// scanf(строка_формата_ввода, адрес_переменной);
scanf("%d", &x);
// printf(строка_формата_вывода, значение);
printf("Value from keyboard: %d\n", x);
- строка_формата_ввода – это строка, которая в одном случае задаёт формат ввода. Обычно там одно значение с “%” (сейчас расскажу про это)
- адрес_переменной – так как каждая переменная на самом деле хранится в памяти, мы можем узнать адрес ячейки, в которой эта переменная хранится. Для того, чтобы получить адрес переменной, надо написать “&” перед именем переменной. scanf принимает адрес переменной для того, чтобы положить полученные данные по указанному адресу.
В этом примере адреса идут от 0x0000 (0) до 0xFFFF (65535), но в реальном компьютере адресов намного больше – до 0xFFFFFFFF в x32 системах (максимум можно адресовать 4 Гб ячеек по одному байту), и 0xFFFFFFFFFFFFFFFF в x64 системах (хватит на адресацию 17 экзабайт – это 17 миллиардов Гб).
- строка_формата_вывода – это строка, которая задаёт формат вывода. Там может быть какая угодно строка, с вкраплениями значений с “%”
- значение – может быть как переменная, так и значение (0, 77, 94.1)
- \n – это символ, обозначающий перенос строки (то, что происходит, когда ты нажимаешь Enter)
ДА КТО ТАКОЙ ЭТОТ ВАШ “%”?!
Это специальный символ, который необходим для указания типа входного/выходного значения. Тип значения указывается буквой после “%”:
- %hd – целое однобайтовое число (char)
- %d – целое четырёхбайтовое число (int)
- %u – целое четырёхбайтовое беззнаковое число (unsigned int)
- %f – целое четырёхбайтовое число (float)
- %lf – целое восьмибайтовое число (double)
- %p – шеснадцатеричное число для отображения адреса
Существуют ещё другие обозначения типов. Если понадобятся – поищи описание функции scanf или printf.
В функции scanf и printf в строках с форматом ввода/вывода может быть указано сразу несколько значений:
char a;
int b;
float c;
// При вводе этих значений надо отделять числа пробелом -- то есть я бы ввёл "5 88 2.5", и нажал бы Enter
scanf("%hd %d %f", &a, &b, &c);
printf("a: %hd; b: %d; c: %f; The answer to life, the universe, and everything: %d", a, b, c, 42);
Задание на закрепление
Скопируй этот код в IDE:
#include <stdio.h>
int main()
{
int intVariable;
scanf("%d", &intVariable);
printf ("Value of intVariable: %d\n", intVariable); // Вот в этот printf добавить остальные переменные
printf ("Adress of intVariable: %p\n", &intVariable);
return 0;
}
Создай ещё три новых переменных с типами char, float и double – заполни их через scanf, и выведи их значения в одном printf.
Попробуй убрать \n – что изменится?
Инициализация переменной
Чтобы избежать определённых ошибок, необходимо понимать особенность создания переменных в C (и в C++) – если ты сразу не присваиваешь ей значение, то там может быть какое угодно значение.
Пример:
int a = 5;
int b;
Мы создали две переменных:
- a – для этой переменной выделится память, и в эту память сразу запишется значение 5
- b – для этой переменной так же выделится память, но ничего не запишется. Это значит, что там останется значение, которое было туда записано когда-то до этого, когда эта память использовалась (возможно другой программой) под другую переменную
Из-за этой особенности необходимо не забывать инициализировать переменную каким-то значением, которое ты в ней ожидаешь.
В некоторых случаях, инициализировать переменную не обязательно – например, если туда точно что-то будет записано:
// В этом случае можно не инициализировать значения:
// - a и b будут заполнены значением с клавиатуры
// - в result запишется сумма a и b
int a, b, result;
// Я в следующей статье расскажу что это за scanf
// Пока что воспринимай это как способ записать в переменную значение, введённое с клавиатуры
scanf("%d", &a);
scanf("%d", &b);
result = a + b;
Однако, в этом случае инициализация переменной необходима:
int a, b;
// В этом случае необходимо было проинициализировать переменную a,
// так как там может быть какое-угодно значение (0, -341124, 777 и т.д.)
// и сумма a + b будет непредсказуемой
scanf("%d", &b);
a = a + b;
Как узнать размер переменной
В самом начале статьи я обещал показать как можно узнать сколько байт занимает переменная типа int.
Для этого тебе понадобится функция sizeof. Вот примеры использования:
int someIntVariable;
float someFloatVariable;
int sizeOfIntVariable = sizeof(someIntVariable), sizeOfFloatVariable = sizeof(someFloatVariable);
printf("size of int: %d, size of float: %d\n", sizeOfIntVariable, sizeOfFloatVariable);
// Ещё можно так, без промежуточных переменных:
// printf("size of int: %d, size of float: %d\n", sizeof(someIntVariable), sizeof(someFloatVariable));
Функция sizeof возвращает количество байт, которое занимает указанная переменная.
На моей машине вывелась такая строка:
size of int: 4, size of float: 4
А какая у тебя? :)
Заключение
Итого, ты изучил:
- Переменные
- Типы переменных (char, int, float, double)
- Модификаторы типов переменных (short, long, unsigned)
- Ввод и вывод значения (scanf, printf)
- Адреса переменных
- Особенность инициализации переменных
- Как узнать размер переменной (sizeof)
Если что – пиши, я помогу и постараюсь объяснить лучше.
Дальше на очереди – операторы.