2013-06-28 3 views
2

Вызов функции sum(int [], arr_size) в заявлении«Составные литералы» в качестве аргумента

total = sum((int []){1,2,3,4,5}, 5); 

Соединение Буквальное(int []){1,2,3,4,5} передается в качестве аргумента. Ясно, что длина массива определяется числами элементов в буквальном (это, конечно, 5). Тогда в чем еще нужно пропустить 5?

мы не можем определить выше функции как

sum(int []) {....} 

и затем вызвать его как

total = sum((int []){1,2,3,4,5}) 

?

ответ

5

Вы можете определить sum таким образом и вызвать его, как показано в вашем примере, но в этом случае вы не сможете определить размер массива внутри функции.

Что вы можете сделать, это объявить sum, как

int sum(int (*a)[5]) 
{ 
    ... 
} 

, а затем вызвать его как

total = sum(&(int []){1,2,3,4,5}); 

Но в этом случае вы будете ограничены массивами только размером 5. Если вы хотите иметь функцию, которая работает с массивами любого размера, вам нужно либо передать размер извне, либо зарезервировать какой-то элемент «терминатора» в вашем массиве

+0

Получил это человек! Вы определили размер массива в определении функции, и именно поэтому вы не передаете размер, верно? – haccks

+1

@haccks: Да. Таким образом, ваши варианты либо фиксируют размер, либо передают размер отдельно. Также обратите внимание, что в моей версии массив передается через параметр «указатель на массив». Вот почему в вызове есть '&'. И внутри функции массив должен быть доступен как '(* a) [i]', а не как 'a [i]'. – AnT

+1

@haccks: Почти каждый раз, когда вы имеете дело с массивами, вы должны использовать указатели. Рекомендуемое чтение: раздел 6 [comp.lang.c FAQ] (http://www.c-faq.com/). –

8

Ваша функция sum идентична sum(int *, size_t); квадратные скобки - это просто синтаксический сахар. Никакие массивы не передаются в какой-либо точке, и действительно, вы не должны не могут передать массивы как аргументы функции в C. Таким образом, в разделе «массив» параметров функции не осталось информации о размере, и размер должен передаваться отдельно.

+0

Здесь 'составной литерал' используется как аргумент. – haccks

+3

@haccks: Но параметров функции * массива еще нет. Смешанный литерал распадается на указатель на первый элемент. –

+3

@qwwqwwq: Это неправильно. '(Int [])' не является литой, это часть синтаксиса составного литерала. Операнд литья - это выражение или имя типа в скобках; '{1, 2, 3, 4, 5}' тоже. Выражение '(int []) {1, 2, 3, 4, 5}' относится к типу массива, в частности 'int [5]'. Он неявно преобразован в 'int *', потому что * все * выражения типа массива преобразуются в указатели с тремя исключениями, которые здесь не применяются. –