2015-09-27 2 views
3

Я имел в виду книгу «Программирование на языке программирования только для часто задаваемых вопросов» Пола С R Chisholm. По словам автора: «Поскольку массив передается по значению, то создается точная копия массива и помещается в стек. Затем вызываемая функция получает эту копию массива и может ее распечатать. Поскольку массив передан byval_func() является копией исходного массива, изменение массива в функции byval_func() не влияет на исходный массив »Передача массива функции по значению

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

Ниже приведен пример, приведенный в учебнике.

void byval_func(int[]); 

void main(void) 
{ 
    int x[10]; 
    int y; 
    /* Set up the integer array. */ 
    for (y=0; y<10; y++) 
    x[y] = y; 
    /* Call byval_func(), passing the x array by value. */ 
    byval_func(x); 
} 

/* The byval_function receives an integer array by value. */ 
void byval_func(int i[]) 
{ 
    int y; 
    /* Print the contents of the integer array. */ 
    for (y=0; y<10; y++) 
    printf(“%d\n”, i[y]); 
} 
+0

должен быть могущественной старой книгой, потому что в современном C, main() ALWAYS имеет тип возврата 'int'. – user3629249

+0

в C, имя массива ухудшается до адреса первого байта массива. поэтому передается указатель на массив, а не содержимое массива – user3629249

+0

этот параметр функции: '(int i [])' определяет «указатель на целочисленный массив», а не содержимое массива – user3629249

ответ

3

Похоже, автор этой книги не знает С.

  • Массивы не «передаются по значению», потому что нет значений массива в С. Значение массива эффективно указатель к его первому элементу.
  • Это означает, что функция может изменять массив вызывающего (сам массив никогда не копируется).
  • void main неправ. main должен вернуть int.

Правило большого пальца: Если книга C содержит void main, это, вероятно, плохо.

+0

Я проверил ссылку, действительно, автор предполагает, что весь массив скопирован –

2

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

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

0

Я думаю, автор сделал путаницу там. Что происходит в вашем коде, так это то, что адрес первого элемента в массиве передается по значению, но не массив «данных» в целом.

Передача по значению и по ссылке является предметом большой путаницы. Люди склонны думать, что, поскольку изменения значения, переданные функции, отражаются за пределами ее объема, это означает, что аргумент передавался по ссылке. Это просто неправильно. Вы не можете передавать что-либо по ссылке в C только по значению, и это значение может быть рефером.

В C++, например, вы можете передать/объявить ссылку с помощью оператора &.

Дальнейшее объяснение:

В C, в некоторых контекстах (как отмечает М.M) *, когда вы только выразить имя массива, он такой же, как выражающее адрес его первого элемента:

int x[10]; // you can call func(x) OR func(&x[0]); 

Как я уже говорил, вы передаете ссылочный по значение а, и это значение является адресом первого элемента.

Интересно отметить:

x[0] is the same as *(x + 0) 
x[1] is the same as *(x + 1) 

И потому [] результаты в операции сложения, вы также можете написать

0[x], и она будет переведена на *(0 + x), что приводит к тому же адресу, что делает назвать такие, как int a = 9[x]; 100% действует C.

* Is an array name a pointer?

+0

Оператор '&' делает то же самое в C и C++: возьмите адрес объекта, который вы передаете ему в качестве аргумента. Возможно, вы думаете о символе '&', который используется как часть ссылочного декларатора в C++ (в этом контексте он не является оператором). –

+0

«В C, когда вы только выражаете имя массива, это то же самое, что выражение адреса его первого элемента» - не совсем верно, в * некоторых контекстах, выражающих имя массива *, создает * указатель на адрес первого элемента. 'sizeof x' является примером контекста, где этого не происходит. Вы также предлагаете ту же проблему, указав «указатель на массив». Нет указателя на массив; временный указатель создается при необходимости, массив не содержит по существу указателя. –

+0

@MM & имеет 2 использует в С ++ 1. Чтобы объявить переменную в качестве эталона 2. Чтобы получить адрес переменной 1 не является частью С Не & рассматривать оператор при объявлении ссылки ? Можете ли вы предоставить ссылку, которая говорит, что в этом случае оператор не является оператором? Я не знаю об этом Я адаптирую ответ.Спасибо – victor

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