+--------------------------+
|.------------------------.|
|| kee_reel@blog:~$ cd    ||
|| си python терминал     ||
|| opengl sql             ||
||                        ||
||                обо_мне ||
|.------------------------.|
+-::--------------------::-+
.--------------------------.
 // /ooooooooooooooooooooo\\ \\ 
 // /ooooooooooooooooooooooo\\ \\ 
//------------------------------\\
\\------------------------------//

C. Переменные

Одним из ключевых понятий в программировании является понятие переменная.

Переменные хранят значения, используемые в программе.

Типы переменных

Переменные могут быть следующих типов:

  • 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” нельзя.

  • В конце каждой строчки надо ставить “;” – это как “.” в конце предложения в русском.

  • Два слеша “//” обозначают начало комментария. Комментарии нужны для того, чтобы оставлять заметки в тексте программы, которые помогут понять что происходит. Комментарии не учитываются при исполнении кода программы.

А чего это я упомянул байты при описании типов? Дело в том, что количество байт ограничивает размер числа, которое мы можем “засунуть” в переменную.

Почему так происходит? Давай вспомним школьную информатику – вот представление целочисленных значений в бинарном виде:

Байты в int

Выходит, что чем больше байт мы выделяем под переменную, тем больше бит там будет, и тем большее число мы можем там записать. Вот минимальные и максимальные значения для всех типов:

  • 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)

Если что – пиши, я помогу и постараюсь объяснить лучше.

Дальше на очереди – операторы.