2013-11-25 3 views
0

я наткнулся на что-то довольно нечетного (для меня по крайней мере), в то время как я читал C учебник:Почему одно свободное измерение при передаче массивов в качестве параметра?

void foo(char arr[]){ 

} 


void main(){ 

    char old_buffer[100]; 

    foo(old_buffer);   //Working??! 
    char arr2[] = old_buffer; //Error! 


} 

Строка с комментарием об ошибке для меня ясно, old_buffer трактуется как адрес, так это может 't работает, потому что в массиве отсутствует информация о том, сколько памяти должно быть выделено. Но почему это работает во главе функции? Спасибо за вашу поддержку :)

+0

Вы хотите сказать, почему он работает в 'void foo (char arr [])'? –

+0

Да, точно :) – user2352375

+0

'char * arr2 = old_buffer' и' char * arr2 [] = {old_buffer}; 'оба работают ... –

ответ

2

Строка с комментарием об ошибке для меня понятна, old_buffer рассматривается как адрес, поэтому это не может работать, потому что в массиве отсутствует информация о том, сколько памяти должно быть выделено.

Это близко, но это не совсем то, что происходит: строка с ошибкой не синтаксически правильно - если вы измените его на

char *arr2 = old_buffer; 

он будет работать. Однако это не будет массив, это будет указатель. Это позволит получить доступ к массиву, но он не даст вам правильного значения в sizeof.

Но почему это работает в голове функции?

Потому что, когда вы передаете массив функции, размер всегда игнорируется. Говорят, что массив распадается на указатель. Другими словами, ваше заявление идентично этому:

void foo(char *arr) 
+0

Правда, но почему я могу писать его в обоих направлениях при объявлении функции (главы)? Хотя (array = pointer) не работает внутри функции (тела)? – user2352375

+0

@ user2352375 Это то, что допустили авторы исходной спецификации C, и это не изменилось с тех пор (фактически, они разрешили нечто очень близкое к сегодняшнему синтаксису, поскольку параметры были объявлены вне заголовка функции, но пустые скобки были там назад в версии языка K & R). Однако они никогда не допускали его для местных жителей и статики, но только для параметров функции. – dasblinkenlight

+0

@ user2352375 Если бы я был вами, я бы очистил любые предвзятые представления о том, как вы думаете, C работает. Запись 'arr []' в объявлении функции отличается от записи 'arr []' при определении переменной. Когда массивы передаются в функции, передается указатель на первый элемент массива. Оказывается, что 'arr []' и '* arr' в объявлении функции идентичны. – Justin

1

old_buffer это адрес old_buffer[0], то есть, это &old_buffer[0]. char arr[] эквивалентен char *arr.

0

массив в C/C++ работа в качестве списка последовательных указателей в MEM. имя массива - переменная, которая содержит адрес первого элемента в массиве. , когда мы используем индекс для достижения значения, которое хранится в этом индексном местоположении , компилятор знает, что значение хранится в местоположении MEM, которое равно адресу, сохраненному в имени массива, добавленном по значению индекса. Ex:

A[0] ='v' 
A = 0x000000 
A[4] = 'c' 

//it is location at 0x000000 + 4 
//so the 
&A[4] = 0x000004 

.

char * arr2 = old_buffer; будет работать над вашим кодом, и вы можете иметь дело с arr2 как массив , потому что он удерживает адрес первого элемента предварительно заданного массива в MEM. Этот способ компилятора - это причина, по которой ваш код работает в голове функции.

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