Подтвердить что ты не робот

Что означают скобки в объявлении переменной C?

Может кто-нибудь объяснить, что это значит?

int (*data[2])[2];
4b9b3361

Ответ 1

Каковы скобки для?

В скобках С [] имеют более высокий приоритет, чем звездочка *

Хорошее объяснение из Википедии:

Объявить переменную как указатель на массив, мы должны использовать круглых скобок. Это происходит потому, что в C скобки ([]) имеют более высокий приоритет чем звездочка (*). Поэтому, если мы хотим объявить указатель на массив, нам нужно поставить скобки, чтобы переопределить это:

double (*elephant)[20];

Это заявляет, что слон - это указатель, и тип, на который он указывает, равен массив из 20 двойных значений.

Объявить указатель на массив указатели, просто объедините нотации.

int *(*crocodile)[15];

Источник.

И ваш фактический случай:

int (*data[2])[5];

data - это массив из двух элементов. Каждый элемент содержит указатель на массив из 5 целых чисел.

Итак, вы можете иметь код, используя свой тип данных:

int (*data[2])[5];
int x1[5];
data[0] = &x1;
data[1] = &x1;

data[2] = &x1;//<--- out of bounds, crash data has no 3rd element
int y1[10];
data[0] = &y1;//<--- compiling error, each element of data must point to an int[5] not an int[10]

Ответ 2

Существует очень классная программа под названием "cdecl", которую вы можете скачать для Linux/Unix и, возможно, для Windows. Вы вставляете в декларацию переменной C (или С++, если используете С++ decl), и она произносит это простыми словами.

Ответ 3

Если вы знаете, как читать выражения на C, то вы отступаете от чтения сложных объявлений.

Что делает

char *p;

действительно означает? Это означает, что *p является char. Что делает

int (*data[2])[5];

означает? Это означает, что (*data[x])[y] является int (при условии 0 <= x < 2 и 0 <= y < 5). Теперь подумайте, каковы последствия этого. data должен быть... массив из 2... указателей... для массивов из 5... целых чисел.

Разве вы не считаете это довольно элегантным? Все, что вы делаете, указывает тип выражения. Как только вы поймете это, объявления никогда не будут запугать вас снова!

"Быстрое правило" должно начинаться с имени переменной, сканировать вправо до тех пор, пока вы не нажмете a), вернитесь к имени переменной и сканируйте влево, пока не нажмете a. пару круглых скобок и повторите процесс.

Пусть это применимо к чему-то смешному:

void **(*(*weird)[6])(char, int);

weird - это указатель на массив из 6 указателей на функции, каждый из которых принимает значение char и int как аргумент, и каждый возвращает указатель на указатель на void.

Теперь, когда вы знаете, что это такое и как это делается... не делайте этого. Используйте typedefs, чтобы разбить ваши объявления на более управляемые куски. Например.

typedef void **(*sillyFunction)(char, int);

sillyFunction (*weird)[6];

Ответ 4

data [2] - массив из двух целых чисел

* data [2] - указатель на массив из двух целых чисел

(* данные [2]) - "

(* data [2]) [2] - массив из 2 указателей на массивы из двух целых чисел.

Ответ 5

Если у вас есть массив:

int myArray[5];
int * myArrayPtr = myArray;

Было бы разумно. myArray без скобок - это указатель на int. Когда вы добавляете скобки, как и вы, вы указываете указатель myArray. Вы могли бы написать...

myArrayPtr[1] = 3;

Это вполне разумно. Использование скобок просто усложняет чтение и понимание ИМО. И они показывают, что люди не понимают указатели, массивы и арифметику указателей, а именно, как компилятор или компоновщик переходят от одного к другому. Кажется, что в скобках вы проверяете границы.