按值将数组传递给函数

Zuz*_*uzu 36 c arrays pass-by-reference pass-by-value

以下是C Programming Just the FAQs一书的摘录.这不是错误的,因为Arrays永远不能通过引用传递吗?

VIII.6:如何通过值将数组传递给函数?

答案:通过在被调用函数中声明带有方括号([])的数组名称,数组可以按值传递给函数.调用函数时,只需将数组的地址(即数组的名称)传递给被调用的函数即可.例如,以下程序将数组传递 x[]byval_func()value 命名 的函数:

int[]参数告诉编译器该byval_func() 函数将采用一个参数 - 一个整数数组.byval_func()调用该 函数时,将数组的地址传递给 byval_func():

byval_func(x);
Run Code Online (Sandbox Code Playgroud)

由于数组是按值传递的,因此会生成数组的精确副本并将其放在堆栈中.然后被调用的函数接收该数组的副本并可以打印它.因为传递给的数组 byval_func()是原始数组的副本,所以修改byval_func()函数中的数组对原始数组没有影响.

Pét*_*rök 60

由于数组是按值传递的,因此会生成数组的精确副本并将其放在堆栈中.

这是不正确的:数组本身没有被复制,只有指向其地址的指针的副本被传递给被调用者(放在堆栈上).(无论是否将参数声明为int[]int*,它都会衰减为指针.)这允许您从被调用函数中修改数组的内容.因此,这

因为传递给byval_func()的数组是原始数组的副本,所以在byval_func()函数中修改数组对原始数组没有影响.

是完全错的(感谢@Jonathan Leffler对他的评论如下).但是,在函数内重新分配指针不会更改指向函数外部原始数组的指针.

  • StefanHållén:你不能在C或C++中按值传递(或返回)数组,你可以在C++中通过引用传递数组,因为C++有引用类型. (4认同)
  • 我会走得更远; 虽然你引用的句子含糊不清,可以理所当然地被认为是正确的,但最后一句话在"改变数组"一词的正常含义中是完全错误的.如果被调用的函数写入`array [0]`,它会在调用函数中修改`array [0]` - 在明显的调用符号下. (3认同)

Lun*_*din 52

烧那本书.如果你想要一个非初学者程序员编写的真正的C FAQ,请使用以下内容:http://c-faq.com/aryptr/index.html.

语法方面,严格来说,你不能在C中按值传递数组.

void func (int* x); /* this is a pointer */

void func (int x[]); /* this is a pointer */

void func (int x[10]); /* this is a pointer */
Run Code Online (Sandbox Code Playgroud)

但是,为了记录,C中有一个脏技巧,它允许你在C中按值传递一个数组.不要在家里试试!因为尽管有这个技巧,仍然没有理由按值传递数组.

typedef struct
{
  int my_array[10];
} Array_by_val;

void func (Array_by_val x);
Run Code Online (Sandbox Code Playgroud)

  • 第3个例子的化妆品意味着你可以在函数中做一个`sizeof(array)/ sizeof(array [0])` (6认同)
  • @Ulterior如果有效的话会不会很好?但唉,你错了,C标准并不那么聪明.试试这个:`void func(int arr [10]){printf("不,我仍然是指针,我的大小是%d.",sizeof(arr)); }`.它将在PC上打印4或8,而不是像您期望的那样打印40. (4认同)
  • @Lundin我同意如果能做到这一点会更好.但是,如果算法在树的每个级别需要不同的数组副本,该怎么办?我编写了一种算法,其中所谓的树的每个节点都需要许多点的副本,并且没有避免使用的内存量,否则这些点将不是必需的,这是必需的.唯一可能的缺点是,在这种情况下,在开始时一次性分配所有内存可能会更快......然后,如果所需数据是动态的,这通常是不可能的. (4认同)
  • "因为尽管有这个技巧,仍然没有理由按值传递数组." - 为什么? (3认同)