c/c++语言开发共享将整个数组传递给函数

当我们将一个数组的元素传递给一个函数时,它被视为一个普通变量,被调用的函数创建一个实际参数的副本并对其进行操作。 在forms参数中进行的任何更改都不会影响实际参数。

但是当我们传递整个数组时,情况并非如此。 在这种情况下,它(称为函数)可以访问实际参数,并且正式参数中的任何更改都会影响实际参数。 为什么会这样?

    该数组作为指向元素的指针传递。

    如果我写:

    void doStuff(int *ptr) { ptr[1] = 5; } int main() { int arr[] = {0, 1, 2}; doStuff(arr); printf("%d %d %dn", arr[0], arr[1], arr[2]); } 

    输出将为“0 5 2”。 那是因为C通过值传递任何实际参数。 该参数是指向int的指针。 因此,指向int的指针按值传递。 因此,doStuff在main的堆栈帧中获取指向内存的指针的副本。 当它用ptr[1]取消引用该指针时,它跟随指向main的内存并在那里修改数组。

    C只能通过值传递,但它“浅”。 如果要求它传递int *,它将传递一个int *。 它只复制指针的值,而不是它指向的任何值。

    如果你想让doStuff获得它自己的数组副本,要么像其他人建议的那样将数组包装在结构中,要么使用memcpy手动深度复制数组,如下所示:

     void doStuff(int *ptr, int nElems) { int myCopyOfTheArray[nElems]; memcpy(myCopyOfTheArray, ptr, sizeof(int) * nElems); /* do stuff with the local copy */ } 

    与使用结构不同,如果只在运行时知道nElems,则memcpy方法有效。

    数组不能通过C中的值传递。它们被降级为指针。 因此被调用的函数看到一个指向数组的指针(通过引用传递)并对其进行操作。 如果要创建副本,则必须显式执行此操作,或将数组放在结构中(可以通过值传递给函数。)

    通常,制作整个arrays的副本是昂贵的。 回到C首次创建的日子,它可能很容易耗尽机器资源(特别是堆栈)。

    如果您确实想要传递数组,请将其包装在结构中:

     struct wrap { int array[100]; }; int somefunc(struct wrap large) { ... } void anotherfunc(void) { struct wrap a; ...add data to array... printf("%dn", somefunc(a)); } 

    我还没有看到任何答案,但尚未涵盖整个问题。 从我看到的,看起来问题是这样的:

    给出以下代码:

     int a[5]; foo(a); bar(a[0]); 

    为什么foo可以操作原始值而bar只接收传入值的副本?

    这是因为使用了数组表示法: []运算符取消引用它在数组中引用的项目并传入该位置的值。

    所以

     int a[5]; bar(a[0]); 

    不同于:

     int* a; bar(a); 

    如果要传递对数组中特定项的引用,则需要使用&运算符:

     bar(&a[5]); 

    “通过引用传递”是C中的红色鲱鱼。函数的所有参数都只是“按值传递”。 在数组的情况下,您以指针的forms传递第一个元素的地址。 然后,您可以使用此指针指向所需的内存位置以及读取或写入值。

    从在线C标准 :

    6.3.2.1左值,数组和函数指示符

    3除非它是sizeof运算符或一元运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为“array of type”的表达式转换为类型为“指向类型的指针”的表达式指向数组对象的初始元素,而不是左值。 如果数组对象具有寄存器存储类,则行为未定义。

    假设以下代码段:

     int a[10]; ... foo(a); 

    在对foo的调用中, 表达式 a的类型是“10元素数组的int ”。 但是,由于表达式不是sizeof&运算符的操作数,并且因为它不是用于初始化声明中的另一个数组的字符串文字,所以它的类型从“10-”隐式转换(“衰减”) int “to”指向int “的元素数组,其值将是数组中第一个元素的地址(即&a[0] )。

    因此, foo接收的是指向int的指针,而不是数组。 取消引用或下标此指针允许您更改数组的值。

    这是C语言的一个特性; 数组不是第一类对象。 实际上,在大多数情况下(包括下标),数组表达式将被转换为指针类型。

    我一直在强调单词表达式,以区分实际的数组对象 (永远是永远的数组类型)和代码中对该对象的任何引用 ,可以将其转换为指针类型。

    因为当你将整个数组传递给函数时你传递一个指向该数组的指针,这意味着你给函数一个位于这个数组所在的内存中的位置。 因此,当您在函数中更改数组时,您也在更改原始数组。

    C中的数组可以被视为指向数组第一个元素的指针。 指针按值传递(您无法修改传入的值),但您可以取消引用它并修改它指向的内存。

    需要了解更多c/c++开发分享将整个数组传递给函数,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享将整个数组传递给函数相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/979874.html

      (0)
      上一篇 2021年12月13日
      下一篇 2021年12月13日

      精彩推荐