MyTetra Share
Делитесь знаниями!
Правила чтения сложных описаний типов в языке C и C++
Время создания: 02.02.2024 10:43
Текстовые метки: c++, си++, тип, правила, сложный, составной, определение, объявление, синтаксис, указатель, ссылка, массив, функция, выражение
Раздел: Компьютер - Программирование - Язык C (Си)
Запись: xintrea/mytetra_syncro/master/base/17068598312dvznjxsn5/text.html на raw.github.com

Правила чтения сложных описаний типов

Конструкции, определяющие переменные или вводящие новые типы в языках C и C++, могут порой иметь довольно запутанный вид. Ниже дано правило, помогающее разобраться в смысле сложных конструкций.


  1. Начиная с имени (в случае typedef, в случае using имя находится вне — см. ниже), читать вправо, пока это возможно (до закрывающей круглой скобки или точки с запятой).
  2. Пока невозможно читать вправо, читать влево (убирая скобки).


Вот некоторые примеры “расшифровки” типов переменных:


// c (влево) константа char (const и char можно поменять местами):

const char c;


// str (влево) указатель на (влево) константу char (или константный массив из char):

const char* str;


// str (влево) константный (влево) указатель на константу char:

const char* const str;


// n (вправо) массив (вправо) из 10 (влево) int:

int n[10];


// n (вправо) массив (вправо) из 10 (влево) указателей на (влево) int:

int* n[10];


// n (влево) указатель на (вправо) массив из 10 (влево) указателей на int:

int* (*n)[10];


// n указатель на массив из 10 (влево) указателей на (вправо) функции,

// не принимающие аргументов, (влево) возвращающие указатели (влево)

// на константы типа int:

const int* (*(*n)[10])();


Разница между typedef и using

Директива typedef объявляет синоним типа. Используется синтаксис определения переменной, к которой добавили ключевое слово typedef, только вместо собственно переменной вводится синоним типа этой как-бы переменной с её именем.


int * p; // переменная: указатель на int

typedef int * pt; // имя pt -- синоним типа "указатель на int"


pt px; // тоже переменная типа "указатель на int"


В С++11 появилась возможность объявлять синонимы типов с помощью using-директивы в стиле инициализации переменных:


using pointer = type*;


Объявление typedef можно превратить в using-директиву, заменив typedef на using, вставив после using имя типа и знак равно и убрав это имя типа из объявления справа.


// то же, что typedef double (*Binary_op)(double, double);

using Binary_op = double (*)(double, double);


Типы, ассоциируемые с массивами

Пусть N — константа времени компиляции и дано определение


float a[N];


Тогда


  • float — тип элемента;
  • float& — ссылка на элемент, тип результата операции обращения по индексу, например a[0];
  • float* — указатель на элемент, например &a[0]; a и &a автоматически неявно приводятся к float*;
  • float[N] — формальный тип переменной a;
  • float(*)[N] — формальный тип указателя на массив a, результат операции взятия адреса &a;
  • float(&)[N] — тип ссылки на массив a; a автоматически неявно приводятся к этому типу; так же как сам массив, ссылка на него автоматически приводится к указателю на массив и на его первый элемент.


Типы, ассоциируемые с функциями

Пусть дано объявление


float foo(int, int);


Тогда


  • float — тип результата, получаемый при вызове функции, например foo(1, 2);
  • float(int, int) — формальный тип символа foo — foo не является переменной, так как переменные функционального типа невозможны, и тем не менее, имеет тип;
  • float(*)(int, int) — указатель на функцию, результат &foo; foo автоматически неявно приводится к этому указателю;
  • float(&)(int, int) — ссылка на функцию; foo автоматически неявно приводится к этому типу; так же как сама функция, ссылка на неё автоматически приводится к указателю на неё же.


Так же в этом разделе:
 
MyTetra Share v.0.60
Яндекс индекс цитирования