Вопрос о массиве C

#c #arrays #turbo-c

Вопрос:

Когда простое имя переменной используется в качестве аргумента, передаваемого функции, функция принимает значение, соответствующее этому имени переменной, и устанавливает его как новую переменную в новой области памяти, созданной функцией для этой цели. Но что происходит, когда адрес массива передается функции в качестве аргумента? Создает ли функция другой массив и перемещает в него значения из массива в вызывающей программе?

Ответ №1:

Нет, если вы передадите адрес чего-либо функции, функция получит адрес. Технически, он получает копию адреса (все это передается по значению, мы просто используем указатели для имитации передачи по ссылке), так что, если вы измените этот адрес в функции, это не повлияет на возврат.

Разыменовав адрес, вы можете изменить то, на что он указывает. Например:

 void changeValA (int x) {
    x = 42;                  // x is 42 but a is unchanged.
}
void changeValB (int *x) {
    *x = 42;                 // *x (hence a) is now 42
}
:
int a = 31415;               // a is 31415
changeValA (a);              // a is still 31415
changeValB (amp;a);             // a is now 42
 

Передача адреса массива в значительной степени совпадает с передачей самого массива. При таких обстоятельствах массив распадается по адресу своего первого элемента.

Комментарии:

1. Тогда ладно. Я перестану печатать свой ответ 😉

2. @Демиан Брехт О, я понимаю. Таким образом, вместо передачи значений в массиве передается только адрес массива. Мм, тогда функция может использовать адрес для доступа к исходному массиву???

3. @aerohn: да, именно так вы передаете ссылки в старом стиле C. Надеюсь, в следующем стандарте ISO мы получим void changeValC (int amp;x) { x = 42; } ... changeValC (a); ссылочные типы C , и один из самых недружественных для новичков фрагментов C будет удален: -)

4. То есть вы имеете в виду, что, как только он узнает адрес, функция напрямую связывается с массивом , скажем list[] , in main() ???

5. @aerohn, да, у него есть адрес для первого элемента в массиве (и массив, конечно, непрерывный). Это означает, что он может использовать индексы для доступа к другим элементам. Но у него нет размера массива — если вы хотите, чтобы функция знала это, вы также должны передать ее: fn (myarr, sizeof(myarr)/sizeof(*myarr)) . Это распад также является причиной sizeof того, что функция бесполезна при передаче массива — она всегда дает вам размер указателя , а не размер массива.

Ответ №2:

Нет.

Когда массив передается функции, он распадается на указатель на первый элемент массива. Это позволяет функции получать доступ к элементам массива точно так же, как в исходном коде, включая возможность изменять элементы, которые поставляются с передачей указателя на функцию, но теряет возможность узнать размер массива во время компиляции sizeof .

В принципе, это:

 void func(int a[]);

// ...

int i[] = { 0, 1, 2, 3, 4 };
func(i);
 

Эффективно ли это делает:

 void func(int *a);

// ...

int i[] = { 0, 1, 2, 3, 4 };
func( amp; (i[0]) );
 

Обратите внимание, что функция, получающая массив, не имеет возможности узнать, как долго он находится из-за этого. Вот почему почти все функции, которые принимают массивы (или указатели), также принимают параметр размера.

Ответ №3:

Числовое значение адреса будет скопировано в стек, а не в область памяти, на которую указывает адрес!

Ответ №4:

Имя массива можно рассматривать как указатель на его начало. Поэтому, когда вы передаете массив функции, это выглядит так, как если бы вы передавали указатель. Новый массив не создается.

Ответ №5:

Нет. Будет отправлена только ссылка/адрес массива. Таким образом, любое обновление функции в массиве повлияет на переданный массив.

Ответ №6:

В C массив всегда передается по ссылке (т. Е. передается только указатель на его начало).

Если вы действительно хотите передать массив по значению, вы можете обернуть его в структуру и передать структуру. Другого способа передать массив по значению нет.

Ответ №7:

Нет, когда вы передаете адрес массива (я полагаю, вы говорите об указателях), копия указателя передается функции.