Программирование на языке Си: Первичные типы данных в Си

Почти в любом языке программирования данные обладают определенным типом...

Posted by Марк Мельник on October 29, 2011

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

Первичные типы данных в Си включают в себя:

Целочисленные типы (integer)
Целочисленные типы используются для хранения чисел в диапазоне определяемом компилятором. Традиционно целые числа занимают 2 байта памяти и значения, которые относятся к типу int находятся в диапазоне от -32768 до +32767. Тип signed int (целое со знаком) использует один бит для хранения знака числа и 15 бит для хранения самого числа. Помимо канонического int, Си имеет еще 2 integer-типа данных:

- short int
- long int

Все три типа имеют как форму со знаком, так и беззнаковую форму (соотв. signed и unsigned). Short int обычно использует половину объема памяти int однако это не константное соотношение, например, в некоторых компиляторах int может занимать не 16 бит, а 32, а short int 16, а не 8. Тип long int обычно использует объем памяти в двое больший, чем int, то есть 4 байта, что опять-таки может изменяться в различных компиляторах. В signed-типах один бит всегда занимается хранением знака числа, в unsigned все биты занимаются исключительно хранением значения числа при этом unsigned-числа всегда считаются целыми.

Синтаксис объявления переменных integer-типов:

[signed | unsigned] (short int | int | long int) <имя_переменной>

int a;
unsigned short int num;
signed long int longnum;

Если явно не указано является ли тип со знаком или беззнаковым, то предполагается, что целочисленный тип имеет знак. Вы также можете использовать сокращенную запись для short int и long int без использования ключевого слова int:

long lnum;
short sh_num;

Числа с плавающей точкой (Float)
Тип float используются для хранения дробных чисел, которые, как правило занимают 4 байта памяти. Переменные хранящие дробные числа обозначаются ключевым словом float. Когда точности типа float недостаточно мы можем использовать тип double. Тип double аналогичен типу float, но с тем отличием, что обычно использует в двое больший объем оперативной памяти, чем использует float (чаще всего 8 байт). По аналогии с long int имеется тип long double, который обычно использует объем памяти в 10 байт. Здесь опять таки все зависит от компилятора, точнее от того, какой объем памяти под какой тип данных посчитали нужным выделять разработчики компилятора.

Синтаксис объявления переменных float-типов:

[signed | unsigned] (float | double | long double) <имя_переменной>

signed float num;
unsigned double long_float_num;
long double longest_float_num;

Символьный тип (Character — char)
Переменная типа char используется для хранения одиночных символов в кодировке ASCII которые занимают один байт памяти. Так как символ относится к integer типам, он может быть как числом со знаком, так и беззнаковым числом и занимает всего один байт. В зависимости от того является ли char signed или unsigned типом, он может хранить соответственно числа в диапазоне от -128 до 127 и от 0 до 225.

Синтаксис:

[signed | unsigned] char ch
char ch = ‘a’;

Тип Void («Пустота», «ничто»)
Тип void не используется для объявления переменных, его основная задача — объявление функций, которые не возвращают какого-либо значения. В старых стандартах Си ключевое слово void помещается в скобки, где перечисляются аргументы функции при ее объявлении для того, чтобы показать, что функция не принимает аргументов, в последних стандартах Си такое использование void необязательно. Если вы программируете на Ruby то можете сравнивать void со значением nil, хотя это не одно и то же.

О void можно рассказать еще кое что интересное, но это будет уже тема другой статьи — к ней вы еще не готовы.

Примечания

1. Тип char хранит не сам символ, а его код, например char c = ‘a’ хранит ASCII-последовательность символа ‘а’ — число 97. Благодаря тому, что типом является char, а не просто int, мы можем работать с числом не просто как с числом, но и конвертировать его в соответствующий ASCII-символ при необходимости:

#include <stdio.h>

int main(int a_num) {
  char c = 'a';
  printf("%c -> %d\n", c, c); // c -> 97
}

2. В Си нет строкового типа. Любая строка является массивом символов. О массивах и других вторичных типах данных языка Си будет рассказано в отдельных статьях.

3. В современных компиляторах уже практически отсутствуют различия в выделяемом под хранения данных того или иного типа объема памяти. Можно смело считать, что int — 2 байта, short int — 1 байт и т.д.