2015-04-27 2 views
9

Я читаю Программирование на C: Современный подход 0NN: K.N.King, чтобы узнать язык программирования C и текущую главу о функциях, а также параметры массива. Это объясняется тем, что можно использовать конструкции, как это выразить длину параметров массива:Длина массива в параметрах массива

1.

void myfunc(int a, int b, int[a], int[b], int[*]); /* prototype */ 

void myfunc(int a, int b, int n[a], int m[b], int c[a+b+other_func()]) { 
... /* body */ 
} 

2.

void myfunc(int[static 5]); /* prototype */ 

void myfunc(int a[static 5]) { 
... /* body */ 
} 

Так вопрос (ы):

a. Являются ли конструкции в примере 1 чисто косметическими или они влияют на компилятор?

b. Модификатор static в этом контексте только косметической природы? что именно это означает и делает?

c. Можно также объявить параметр массива следующим образом: и является ли это косметическим, как пример 1?

void myfunc(int[4]); 

void myfunc(int a[4]) { ... } 
+2

Никто не знает. Делайте эксперименты :) – i486

+4

@ i486 Пожалуйста, прекратите лежать. Существует стандарт для языка C. Конечно, кто-то знает. Для справки, делать эксперименты с C является плохой идеей, потому что каждый компилятор делает вещи немного разные. Обратитесь к стандарту, чтобы убедиться. – fuz

+0

Кажется, что все это удаляется при компиляции, и никакие дополнительные проверки не выполняются компилятором. Выражения внутри скобок вычисляются во время выполнения, но их значение, кажется, теряется. Но это все, что можно сказать об этом? А что именно статично? – MinecraftShamrock

ответ

2

Внутреннее измерение параметров функции массива всегда переписывается на указатель, так что значения, которые вы даете там не имеют большого значения, к сожалению. Это изменяется для многомерных массивов: начиная со второго измерения, они затем используются компилятором для вычисления таких вещей, как A[i][j].

В этом контексте static означает, что вызывающий должен предоставить как минимум столько элементов. Большинство компиляторов игнорируют само значение. Некоторые недавние компиляторы выводят из него, что нулевой указатель не разрешен в качестве аргумента и, если это возможно, предостерегает вас.

Также обратите внимание, что прототип может иметь *, так что значение здесь не имеет значения. В случае многомерных массивов конкретным значением является то, которое вычисляется с помощью выражения для определения.

+0

Возможно, 'sizeof a' даст разные результаты в соответствии с определением. – i486

+0

@ i486, что вы имеете в виду? 'sizeof' может использоваться только в определении функции. 'sizeof'' параметра указателя всегда будет возвращать размер этого указателя, а не массив, на который он указывает. –

+0

Я имею в виду, что 'sizeof' может отличаться в зависимости от размера массива в определении функции. Все остальные могут быть одинаковыми - например, между 'func (int a [5])' и 'func (int a [8])'. Вы определяете параметр как массив - на самом деле он используется как указатель. Но 'sizeof a' будет рассчитываться с учетом размера массива в определении. (Не на 100% уверен и не проверен, только гадать.) – i486