C Language                
            Типы данных
        
        
            
    Поиск…
замечания
-  Хотя charдолжен быть 1 байт, 1 байт не должен быть 8 бит (часто также называемый октетом ), хотя большинство современных компьютерных платформ определяют его как 8 бит. Число бит реализации для каждогоcharобеспечивается макросомCHAR_BIT, определенным в<limits.h>. POSIX требует, чтобы 1 байт был 8 бит.
- Целые типы с фиксированной шириной должны использоваться редко, встроенные типы C предназначены для того, чтобы быть естественными для каждой архитектуры, типы фиксированной ширины должны использоваться только в том случае, если вам явно требуется целое число определенного размера (например, для сетей).
Целочисленные типы и константы
 Подписанные целые числа могут быть такого типа ( int после short или long необязательно): 
signed char c = 127; /* required to be 1 byte, see remarks for further information. */
signed short int si = 32767; /* required to be at least 16 bits. */
signed int i = 32767; /* required to be at least 16 bits */
signed long int li = 2147483647; /* required to be at least 32 bits. */
signed long long int li = 2147483647; /* required to be at least 64 bits */
Каждый из этих подписанных целочисленных типов имеет неподписанную версию.
unsigned int i = 65535;
unsigned short = 2767;
unsigned char = 255;
 Для всех типов, кроме char signed версия предполагается, если пропущена signed или unsigned часть. Тип char представляет собой третий тип символа, отличный от signed char и unsigned char а подпись (или нет) зависит от платформы. 
Различные типы целых констант (называемые литералами на языке C) могут быть записаны в разных базах и различной ширине на основе их префикса или суффикса.
/* the following variables are initialized to the same value: */
int d = 42;   /* decimal constant (base10) */
int o = 052;  /* octal constant (base8) */
int x = 0xaf; /* hexadecimal constants (base16) */
int X = 0XAf; /* (letters 'a' through 'f' (case insensitive) represent 10 through 15) */
 Десятичные константы всегда signed . Шестнадцатеричные константы начинаются с 0x или 0X а восьмеричные константы начинаются с 0 . Последние два являются signed или unsigned зависимости от того, соответствует ли значение подписанному типу или нет. 
/* suffixes to describe width and signedness : */
long int i = 0x32; /* no suffix represent int, or long int */
unsigned int ui = 65535u; /* u or U represent unsigned int, or long int */
long int li = 65536l; /* l or L represent long int */
 Без суффикса константа имеет первый тип, который соответствует его значению, то есть десятичная константа, которая больше INT_MAX имеет тип long если это возможно, или long long противном случае. 
 Заголовочный файл <limits.h> описывает пределы целых чисел следующим образом. Их значения, определяемые реализацией, должны быть равны или больше по величине (по абсолютной величине) тем, которые показаны ниже, с тем же знаком. 
| макрос | Тип | Значение | 
|---|---|---|
| CHAR_BIT | наименьший объект, который не является битовым полем (байтом) | 8 | 
| SCHAR_MIN | signed char | -127 / - (2 7 - 1) | 
| SCHAR_MAX | signed char | +127 / 2 7 - 1 | 
| UCHAR_MAX | unsigned char | 255/2 8 - 1 | 
| CHAR_MIN | char | увидеть ниже | 
| CHAR_MAX | char | увидеть ниже | 
| SHRT_MIN | short int | -32767 / - (2 15 - 1) | 
| SHRT_MAX | short int | +32767 / 2 15 - 1 | 
| USHRT_MAX | unsigned short int | 65535/2 16 - 1 | 
| INT_MIN | int | -32767 / - (2 15 - 1) | 
| INT_MAX | int | +32767 / 2 15 - 1 | 
| UINT_MAX | unsigned int | 65535/2 16 - 1 | 
| LONG_MIN | long int | -2147483647 / - (2 31 - 1) | 
| LONG_MAX | long int | +2147483647 / 2 31 - 1 | 
| ULONG_MAX | unsigned long int | 4294967295/2 32 - 1 | 
| макрос | Тип | Значение | 
|---|---|---|
| LLONG_MIN | long long int | -9223372036854775807 / - (2 63 - 1) | 
| LLONG_MAX | long long int | +9223372036854775807 / 2 63 - 1 | 
| ULLONG_MAX | unsigned long long int | 18446744073709551615/2 64 - 1 | 
 Если значение объекта типа char sign-extends при использовании в выражении, значение CHAR_MIN должно быть таким же, как значение SCHAR_MIN а значение CHAR_MAX должно быть таким же, как значение SCHAR_MAX . Если значение объекта типа char не подписывается, если оно используется в выражении, значение CHAR_MIN должно быть 0, а значение CHAR_MAX должно быть таким же, как значение UCHAR_MAX . 
 В стандарте C99 добавлен новый заголовок <stdint.h> , который содержит определения для целых чисел фиксированной ширины. См. Пример целочисленной фиксированной ширины для более подробного объяснения. 
Строковые литералы
Строковый литерал в C - это последовательность символов, завершаемая буквальным нулем.
char* str = "hello, world"; /* string literal */
/* string literals can be used to initialize arrays */
char a1[] = "abc"; /* a1 is char[4] holding {'a','b','c','\0'} */
char a2[4] = "abc"; /* same as a1 */
char a3[3] = "abc"; /* a1 is char[3] holding {'a','b','c'}, missing the '\0' */
Строковые литералы не изменяются (и фактически могут быть помещены в постоянное запоминающее устройство, такое как .rodata). Попытка изменить их значения приводит к неопределенному поведению.
char* s = "foobar";
s[0] = 'F'; /* undefined behaviour */
/* it's good practice to denote string literals as such, by using `const` */
char const* s1 = "foobar";
s1[0] = 'F'; /* compiler error! */
Несколько строковых литералов объединяются во время компиляции, что означает, что вы можете написать такую конструкцию.
/* only two narrow or two wide string literals may be concatenated */
char* s = "Hello, " "World";
/* since C99, more than two can be concatenated */
/* concatenation is implementation defined */
char* s1 = "Hello" ", " "World";
/* common usages are concatenations of format strings */
char* fmt = "%" PRId16; /* PRId16 macro since C99 */
Строковые литералы, такие же, как символьные константы, поддерживают разные наборы символов.
/* normal string literal, of type char[] */
char* s1 = "abc";
/* wide character string literal, of type wchar_t[] */
wchar_t* s2 = L"abc";
/* UTF-8 string literal, of type char[] */
char* s3 = u8"abc";
/* 16-bit wide string literal, of type char16_t[] */
char16_t* s4 = u"abc";
/* 32-bit wide string literal, of type char32_t[] */
char32_t* s5 = U"abc";
Типы целых чисел с фиксированной шириной (с C99)
 Заголовок <stdint.h> содержит несколько определений целочисленного типа фиксированной ширины. Эти типы являются необязательными и предоставляются только в том случае, если платформа имеет целочисленный тип соответствующей ширины, и если соответствующий подписанный тип имеет два дополнительных представления отрицательных значений. 
См. Раздел примечаний для подсказок использования типов фиксированной ширины.
/* commonly used types include */
uint32_t u32 = 32; /* exactly 32-bits wide */
uint8_t u8 = 255;  /* exactly 8-bits wide */
int64_t i64 = -65  /* exactly 64 bit in two's complement representation */
Константы с плавающей запятой
 Язык C имеет три обязательных типа с плавающей запятой, float , double и long double . 
float f = 0.314f;        /* suffix f or F denotes type float */
double d = 0.314;        /* no suffix denotes double */
long double ld = 0.314l; /* suffix l or L denotes long double */
/* the different parts of a floating point definition are optional */
double x = 1.; /* valid, fractional part is optional */
double y = .1; /* valid, whole-number part is optional */
/* they can also defined in scientific notation */
double sd = 1.2e3; /* decimal fraction 1.2 is scaled by 10^3, that is 1200.0 */
 Заголовок <float.h> определяет различные ограничения для операций с плавающей запятой. 
Определенная реализация арифметики с плавающей точкой. Однако большинство современных платформ (arm, x86, x86_64, MIPS) используют операции с плавающей запятой IEEE 754 .
C также имеет три необязательных типа с плавающей точкой, которые получены из вышеизложенного.
Интерпретация деклараций
Отличительной синтаксической особенностью C является то, что объявления отражают использование объявленного объекта, как это было бы в нормальном выражении.
Следующий набор операторов с одинаковым приоритетом и ассоциативностью повторно используется в деклараторах, а именно:
-  унарный *«разыменовать» оператор , который обозначает указатель;
-  бинарный []«подписчик на массив», который обозначает массив;
-  оператор (1 + n) -ary ()«вызов функции», который обозначает функцию;
-  ()скобки группировки, которые переопределяют приоритет и ассоциативность остальных перечисленных операторов.
Вышеуказанные три оператора имеют следующий приоритет и ассоциативность:
| оператор | Относительный приоритет | Ассоциативность | 
|---|---|---|
| [](подписка на массив) | 1 | Слева направо | 
| ()(вызов функции) | 1 | Слева направо | 
| *(разыменование) | 2 | Справа налево | 
При интерпретации объявлений нужно начинать с идентификатора наружу и применять соседние операторы в правильном порядке в соответствии с приведенной выше таблицей. Каждое приложение оператора может быть заменено следующими английскими словами:
| выражение | интерпретация | 
|---|---|
| thing[X] | массив размера X... | 
| thing(t1, t2, t3) | функция, принимающая t1,t2,t3и возвращающая ... | 
| *thing | указатель на ... | 
Из этого следует, что начало английской интерпретации всегда начинается с идентификатора и заканчивается типом, который стоит в левой части объявления.
Примеры
char *names[20];
 [] имеет приоритет над * , поэтому интерпретация: names - это массив размером 20 указателя на char . 
char (*place)[10];
 В случае использования скобок для переопределения приоритета сначала применяется * : place - это указатель на массив размером 10 char . 
int fn(long, short);
 Здесь нет приоритета: fn - это функция, выполняющая long , short и возвращающие int . 
int *fn(void);
 Сначала применяется функция () : fn - это функция, принимающая void и возвращающая указатель на int . 
int (*fp)(void);
 Переопределение приоритета () : fp является указателем на функцию, принимающую void и возвращающую int . 
int arr[5][8];
 Многомерные массивы не являются исключением из правила; операторы [] применяются в порядке слева направо в соответствии с ассоциативностью в таблице: arr представляет собой массив размером 5 массива размером 8 из int . 
int **ptr;
 Два оператора разыменования имеют одинаковый приоритет, поэтому ассоциативность вступает в силу. Операторы применяются в порядке справа налево: ptr является указателем на указатель на int . 
Несколько объявлений
Запятая может использоваться как разделитель (* not *, действующий как оператор запятой), чтобы разграничить несколько деклараций внутри одного оператора. Следующий оператор содержит пять объявлений:int fn(void), *ptr, (*fp)(int), arr[10][20], num;
Объявленные объекты в приведенном выше примере:
-  fn: функция, принимающаяvoidи возвращающаяint;
-  ptr: указатель наint;
-  fp: указатель на функцию, принимающуюintи возвращающуюint;
-  arr: массив размера 10 массива размера 20 изint;
-  num:int.
Альтернативная интерпретация
Поскольку использование зеркал отражения используется, декларация также может быть интерпретирована в терминах операторов, которые могут быть применены к объекту, и конечного результирующего типа этого выражения. Тип, стоящий с левой стороны, является конечным результатом, который получается после применения всех операторов.
/*
 * Subscripting "arr" and dereferencing it yields a "char" result.
 * Particularly: *arr[5] is of type "char".
 */
char *arr[20];
/*
 * Calling "fn" yields an "int" result.
 * Particularly: fn('b') is of type "int".
 */
int fn(char);
/*
 * Dereferencing "fp" and then calling it yields an "int" result.
 * Particularly: (*fp)() is of type "int".
 */
int (*fp)(void);
/*
 * Subscripting "strings" twice and dereferencing it yields a "char" result.
 * Particularly: *strings[5][15] is of type "char"
 */
char *strings[10][20];