В этом разделе представлена серия примеров деклараций объектов и функций. Вместе с каждым примером приводится описание, в котором показано как читать декларацию.
Этот раздел можно использовать как «поваренную книгу» деклараций. Здесь даны некоторые сложные, но подчас нужные декларации.
Первые примеры очень простые, последующие более сложные. Некоторые примеры в конце каждого раздела, скорее всего, никогда не понадобятся в реальной программе, но будут полезны, так как помогут понять как читать и писать декларации C.
Для уменьшения сложности и, чтобы лучше проиллюстрировать как маленькие различия в декларации могут привести к большим различиям в значении, используются следующие правила:
x
или X
,F
,int
, хотя может быть использован любой другой,int
, хотя может быть использован любой другой.
Спецификаторы класса памяти (extern
, static
,
auto
или register
) опущены намеренно.
Некоторые примеры деклараций объекта (переменной):
int x; 2 1
(1)x
является (2) целым.
int * x; 3 2 1
(1)x
— (2)указатель на (3)целое.
int ** x; 4 32 1
(1)x
— (2)указатель на (3)указатель на (4)целое.
const int x; 2 3 1
(1)x
— (2)константное (3)целое.
int const x; 3 2 1
(1)x
— (2)константное (3)целое (то же, что и выше).
const int * x; 3 4 2 1
(1)x
— (2)указатель на (3)константное (4)целое. Значение
x
можно изменить, но целое, на которое он указывает, изменить
нельзя. Другими словами, *x
изменить нельзя.
int * const x; 4 3 2 1
(1)x
— (2)константный (3)указатель на (4)целое. Значение
x
изменить нельзя, но целое, на которое он указывает можно.
Другими словами, x
всегда указывает в одно и то же место, но
содержимое в этом месте можно изменять.
const int * const x; 4 5 3 2 1
(1)x
— (2)константный (3)указатель на (4)константное
(5)целое. Значение x
нельзя изменить, и целое, на которое он
указывает, тоже нельзя менять. Другими словами, x
всегда
указывает в одно и то же место, которое нельзя изменять при помощи
x
.
int x[]; 3 12
(1)x
— (2)массив (3)целых.
int x[53]; 4 123
(1)x
— (2)массив из (3)53 (4)целых.
int * x[]; 4 3 12
(1)x
— (2)массив (3)указателей на (4)целые.
int (*x)[]; 4 21 3
(1)x
— (2)указатель на (3)массив (4)целых.
int * (*x)[]; 5 4 21 3
(1)x
— (2)указатель на (3)массив (4)указателей на (5)целые.
int (*x)(); 4 21 3
(1)x
— (2)указатель на (3)функцию возвращающую (4)целое.
int (*x[25])(); 6 4123 5
(1)x
— (2)массив из (3)25 (4)указателей на (5)функции возвращающие (6)целое.
Некоторые примеры деклараций функции:
int F(); 3 12
(1)F
является (2)функцией, возвращающей (3)целое.
int * F(); 4 3 12
(1)F
— (2)функция, возвращающая (3)указатель на (4)целое.
int (*F())(); 5 312 4
(1)F
— (2)функция, возвращающая (3)указатель на
(4)функцию, возвращающую (5)целое.
int * (*F())(); 6 5 312 4
(1)F
— (2)функция, возвращающая (3)указатель на
(4)функцию, возвращающую (5)указатель на (6)целое.
int (*F())[]; 5 312 4
(1)F
— (2)функция, возвращающая (3)указатель на (4)массив (5)целых.
int (*(*F())[])(); 7 5 312 4 6(1)
F
— (2)функция, возвращающая (3)указатель на (4)массив
(5)указателей на (6)функции, возвращающие (7)целое.
int * (*(*F())[])(); 8 7 5 312 4 6
(1)F
— (2)функция, возвращающая (3)указатель на (4)массив
(5)указателей на (6)функции, возвращающие (7)указатель на (8)целое.
__far
, __near
и __huge
Следующие примеры демонстрируют использование ключевых слов
__far
и __huge
.
Использование ключевого слова __near
симметрично использованию
ключевого слова __far
, поэтому примеры для __near
не показаны.
int __far X; 3 2 1
(1)X
является (2)дальним (3)целым.
int * __far x; 4 3 2 1
(1)x
— (2)дальний и является (3)указателем на (4)целое.
int __far * x; 4 2 3 1
(1)x
— (2)дальний (3)указатель на (4)целое.
int __far * __far x; 5 3 4 2 1
(1)x
— (2)дальний и является (3)дальним (4)указателем на (5)целое.
int __far X[]; 4 2 13
(1)X
— (2)дальний (3)массив (4)целых.
int __huge X[]; 4 2 13
(1)X
— (2)huge (3)массив (4)целых (X
—
массив, размер которого может превышать 64K).
int * __far X[]; 5 4 2 13
(1)X
— (2)дальний (3)массив (4)указателей на (5)целые.
int __far * X[]; 5 3 4 12
(1)X
— (2)массив (3)дальних (4)указателей на (5)целые.
int __far * __far X[]; 6 4 5 2 13
(1)X
— (2)дальний (3)массив (4)дальних (5)указателей на (6)целые.
int __far F(); 4 2 13
(1)F
— (2)дальняя (3)функция, возвращающая (4)целое.
int * __far F(); 5 4 2 13
(1)F
— (2)дальняя (3)функция, возвращающая (4)указатель на (5)целое.
int __far * F(); 5 3 4 12(1)
F
— (2)функция, возвращающая (3)дальний (4)указатель на (5)целое.
int __far * __far F(); 6 4 5 2 13
(1)F
— (2)дальняя (3)функция, возвращающая (4)дальний (5)указатель на (6)целое.
int (__far * x)(); 5 2 3 1 4
(1)x
— (2)дальний (3)указатель на (4)функцию, возвращающую (5)целое.
int __far * (* x)(); 6 4 5 2 1 3
(1)x
— (2)указатель на (3)функцию, возвращающую (4)дальний (5)указатель на (6)целое.
int __far * (__far * x)(); 7 5 6 2 3 1 4
(1)x
— (2)дальний (3)указатель на (4)функцию, возвращающую (5)дальний (6)указатель на (7)целое.
__interrupt
Следующий пример демонстрирует использование ключевого слова __interrupt
.
void __interrupt __far F(); 5 3 2 14
(1)F
является (2)дальней (4)функцией (3)прерывания, не возвращающей (5)ничего.