2012-04-09 2 views
4

Что означает (int (*)[30]) Среднее значение в C? Например, в:Что означает (*) in (int (*) [30])?

int (*b)[30] = (int (*) [30]) malloc(30 * sizeof(int [20])); 
+1

Это тип cast – BlackBear

+0

@OliCharlesworth Я не спрашиваю, что означает * в C, я имею в виду конкретно (\ *), т. Е. (Int (*) [30]). – Max

+0

@Max: Ах, извините. Я пропустил, что вы спрашивали о '' (*) '", а не '' '' ". –

ответ

11

Это значит, что это «указатель».

int (*b)[30] 

Это означает, что «b является указателем на массив из 30 целых чисел».

(int (*) [30]) 

Это означает «приведение к указателю на массив из 30 целых чисел».

+3

И другая звездочка в строке означает «умножить». –

+2

И ключевым моментом является то, что 'int * [30]' будет означать нечто совершенно иное, а именно массив из 30 указателей на 'int'. –

0

(*) до того, как имя переменной означает POINTER.

Мы только что видели, что переменная, которая хранит ссылку на другую переменную, называется указателем. Указатели, как говорят, указывают на «переменную, чью ссылку они хранят.

Используя указатель, мы можем напрямую получить доступ к значению, хранящемуся в переменной, на которую оно указывает. Для этого нам просто нужно предшествовать идентификатору указателя со звездочкой (*), которая действует как оператор разыменования и которая может быть буквально переведена на «значение, обозначенное».

2

Как разобрать объявления C и типов: размотать их снаружи в

  • int (*b)[30]..
  • (*b)[30] является int.
  • (*b) является массив int длины 30.
  • b является указателем на int массив длиной 30.

Безымянная версия int (*) [30] полностью идентична, просто имя опущено.

Если у вас есть копия языка программирования C, там есть программа, называемая cdecl, которая может преобразовывать такие объявления на английский язык. С течением времени были различные модификации, например cutils в Debian поддерживает безымянную форму, а cdecl.org - онлайн.

0

Нет ничего особенного в области (*). Поскольку вы просто ссылаетесь на тип в вашем typecast (а не на переменную, которая имеет имя этого типа), вы просто опускаете это имя. Здесь parens по-прежнему необходимо различать массив указателей от указателя на массив.

1

Вы можете использовать cdecl, чтобы понять такие вещи из:

cdecl> explain (int (*) [30]) 
cast unknown_name into pointer to array 30 of int 
3
int (*b)[30] = (int (*) [30]) malloc(30 * sizeof(int [20])); 

разбив его:

 b  -- b 
    (*b)  -- is a pointer 
    (*b)[30] -- to a 30-element array 
int (*b)[30] -- of int. 

В обоих деклараций и выражений, операторов Постфиксные как [] имеют более высокий приоритет чем унарные операторы, такие как *, поэтому T *a[] интерпретируется как T *(a[]); IOW, a - массив указателя на T. Чтобы назначить a в качестве указателя на массив, мы вынуждены группировать T (*a)[].

Simlilarly, выражение литого (int (*) [30]) означает «лечить значение указателя, возвращаемый malloc как указатель на 30-элементный массив int в». Обратите внимание, что, с технической точки зрения, литое выражение является излишним и должно быть удалено.

malloc звонок сам кажется очень неправильным. Вы выделяете 30 экземпляров 20-элементного массива int, но присваиваете результат указателю на 30-элементный массив из int; это вызовет проблемы. Предполагая, что вы пытаетесь выделить N х 30 матрицу int, следующий будет безопаснее:

int (*b)[30] = malloc(N * sizeof *b); 

типа выражения *b является int [30], так sizeof *b таким же, как sizeof (int [30]).

Смежные вопросы