Эквивалентные декларации C - PullRequest
4 голосов
/ 25 марта 2011

Являются ли

int (*x)[10];

и

int x[10];

эквивалентными?

В соответствии с правилом "Спираль по часовой стрелке" они разбираются на разныеДекларации Си.

Для утомленных кликом:

"Правило по часовой стрелке / спираль" Дэвида Андерсона

ЕстьТехника, известная как «Правило по часовой стрелке / спирали», которая позволяет любому программисту C анализировать в своей голове любое объявление C!

Существует три простых шага:

   1. Starting with the unknown element, move in a spiral/clockwise direction; 
          when ecountering the following elements replace them with the 
          corresponding english statements:

      [X] or []
          => Array X size of... or Array undefined size of... 
      (type1, type2)
          => function passing type1 and type2 returning... 
      *
          => pointer(s) to... 

   2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.

   3. Always resolve anything in parenthesis first! 

Ответы [ 5 ]

8 голосов
/ 25 марта 2011

Следуйте этому простому процессу при чтении объявлений:

Начать с имени переменной (или внутренняя конструкция, если нет идентификатора настоящее. Смотри прямо без прыжков над правой скобкой; скажи что ты увидеть. Посмотрите налево снова без прыжков через скобки; скажи что видишь. Выскочить уровень скобок, если любой. Смотреть прямо; скажи что видишь. Посмотри налево; скажи что видишь. Продолжить таким образом, пока вы не скажете тип переменной или тип возвращаемого значения.

Итак:

int (*x)[10];

x - указатель на массив из 10 int с

int x[10];

x - это массив из 10 int с

int *x[10];

x - это массив из 10 указателей на int s

8 голосов
/ 25 марта 2011

Они не равны.в первом случае x - это указатель на массив из 10 целых чисел, во втором случае x - это массив из 10 целых чисел.

Два типа различаются.Вы можете увидеть, что они не одно и то же, проверив sizeof в обоих случаях.

4 голосов
/ 25 марта 2011

Я склонен следовать Правило приоритета для понимания объявлений C , которое очень хорошо дано в книге Эксперт C Программирование - глубокие секреты C Питера ван дер Линдена

A - Declarations are read by starting with the name and then reading in 
precedence order.

B - The precedence, from high to low, is:
        B.1 parentheses grouping together parts of a declaration
        B.2 the postfix operators:
        parentheses () indicating a function, and
        square brackets [] indicating an array.
        B.3 the prefix operator: the asterisk denoting "pointer to".

C If a const and/or volatile keyword is next to a type specifier (e.g. int, 
        long, etc.) it applies to the type specifier. 
        Otherwise the const and/or volatile keyword 
        applies to the pointer asterisk on its immediate left.
2 голосов
/ 26 марта 2011

Для меня легче запомнить правило, поскольку отсутствует какая-либо явная группировка, () и [] bind before *.Таким образом, для объявления типа

T *a[N];

[] связывается перед *, поэтому a является массивом указателей из N элементов.Разбиваем его по шагам:

   a     -- a
   a[N]  -- is an N-element array
  *a[N]  -- of pointer
T *a[N]  -- to T.

Для объявления, такого как

T (*a)[N];

, паренсы заставляют * связываться перед [], поэтому

    a      -- a
  (*a)     -- is a pointer
  (*a)[N]  -- to an N-element array
T (*a)[N]  -- of T

Это все еще правило по часовой стрелке / по спирали, просто выраженное в более сжатой форме.

0 голосов
/ 25 марта 2011

Нет.Первый объявляет массив из 10 int указателей , а второй объявляет массив из 10 дюймов.

...