首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么要将一个数组作为一个实际的参数发送给函数,它需要一个指向数组的指针,需要两次取消引用才能访问该数组?

将一个数组作为实际参数发送给函数时,需要一个指向数组的指针,并且需要两次取消引用才能访问该数组的原因如下:

  1. 数组在内存中的存储方式:数组在内存中是连续存储的,即相邻元素在内存中的地址是连续的。通过指针可以获取数组在内存中的起始地址,从而访问整个数组。
  2. 数组传递给函数的方式:在函数调用时,参数传递可以通过值传递或引用传递。对于数组来说,传递数组的地址(指针)比传递整个数组更高效,因为传递整个数组会涉及到数据的复制,而传递指针只需要传递一个地址。
  3. 指针的作用:通过指针可以间接访问数组元素,即通过指针的地址定位到数组的起始地址,再通过偏移量访问数组中的元素。因此,将数组作为参数传递给函数时,需要一个指向数组的指针。
  4. 取消引用的目的:取消引用指针即获取指针所指向的值。在访问数组时,需要先取消引用指针获取数组的起始地址,然后再通过偏移量访问数组中的元素。

综上所述,将一个数组作为实际参数发送给函数时,需要一个指向数组的指针,并且需要两次取消引用才能访问该数组,这是因为数组在内存中的存储方式和指针的作用所决定的。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

面试总结-C++

见为什么不能建立引用数组 将引用作为函数的参数时,可以避免对变量或者对象的复制,因此不会调用对象的拷贝构造函数。当不希望传入的引用参数不被改变时,使用const引用。...例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成内存泄露。)。 可以返回类成员的引用,但最好是const。...- int (*p)(int)是函数指针,强调是指针,该指针指向的函数具有int类型参数,并且返回值是int类型的。 ##### 指针与数组名 - 二者均可通过增减偏移量来访问数组中的元素。...C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。...访问时间,访问堆的一个具体单元,需要两次访问内存,第一次得取得指针,第二次才是真正得数据,而栈只需访问一次。 堆的内容被操作系统交换到外存的概率比栈大,栈一般是不会被交换出去的。

2.1K11

小白学算法-数据结构和算法教程:什么链表以及操作

节点结构:链表中的节点通常由两个组件组成: 数据:它保存与该节点关联的实际值或数据。 下一个指针:它存储序列中下一个节点的内存地址(引用)。 头尾:链表通过头节点访问,头节点指向链表中的第一个节点。...链表的最后一个节点指向NULL或nullptr,表示链表的结尾。该节点称为尾节点。 为什么需要链表数据结构? 下面列出了链表的一些优点,它将帮助您理解为什么有必要了解它。...动态数据结构:可以在运行时根据操作插入或删除来分配或取消分配内存大小。 易于插入/删除:元素的插入和删除比数组简单,因为插入和删除后不需要移动元素,只需更新地址。...灵活性:链表可以轻松地重新组织和修改,而不需要连续的内存块。 链表的缺点 随机访问:与数组不同,链表不允许通过索引直接访问元素。需要遍历才能到达特定节点。...额外内存:与数组相比,链表需要额外的内存来存储指针。 插入链表 给定一个链表,任务是在这个给定的链表中的以下位置插入一个新节点:  在链表的最前面   在给定节点之后。  位于链表的末尾。

15630
  • 【C语言总集篇】指针篇——从不会到会的过程

    ,所以对于数组指针变量我们可以写成以下形式: 当我们通过两次解引用操作来访问变量a中存放的数据时,此时的数组指针就和二级指针类似; 当我们通过两次下标引用操作符来访问变量a中存放的数据时,此时的数组指针就和二维数组类似...为了进一步验证这个结论,我们来进行以下的测试; 通过数组下标访问数组的各个元素 此时我们通过两次解引用不管是使用数组名还是指针名都成功的访问到了数组各每个元素; 通过解引用操作访问二维数组的各个元素 通过解引用操作...这里要注意的是,对函数指针类型重命名时,我们需要将新的名字放在指针标志的括号内才能完成重命名; 16.5 有趣的代码 下面我们来看两个有趣的代码: //代码1 (*(void(*)())0)(); 这个代码是在干啥呢...signal这个函数它有两个参数——一个是int类型,一个是函数指针类型; 那它实际上是数据类型 标识符(参数类型,参数类型),这个格式是函数声明的格式。...如下所示: 当然,我们在实际使用时调用函数的数量是根据实际情况而定的,只要被调用的函数满足以下三个条件即可通过函数指针数组来进行调用: 函数具有相同的返回类型 函数具有相同的参数数量 函数具有相同的参数类型

    37010

    还有人不知道什么是柔性数组?还不速来!!!

    ,确保calloc/malloc与free是一一对应的关系: 空间扩容后,及时的改变原指针的指向,确保指针指向的是扩容好的内存空间地址 为了避免这些问题的出现,所以我们需要在使用动态函数前,先了解一个各个函数的用法...对柔性数组的特点有了一个初步的理解后,接下来我们就来看一下我们应该如何使用柔性数组; 三、柔性数组的使用 使用柔性数组时,实际上就是创建一个该结构类型的指针变量,并在堆区申请空间,如下所示: typedef...实际上我们从最后的空间释放就可以到,如果采用指针变量的话,在进行空间释放时,我们需要进行两次空间释放,一次是指针变量成员指向的内存空间,一个只是结构体指针变量指向的内存空间,且它们释放的顺序还不能改变。...当结构体中的最后一个成员是柔性数组时,我们只需要找到了柔性数组的起始地址,就可以开始正常的访问数组中的元素; 而当结构体中的最后一个成员是指针变量时,我们需要先找到该成员的地址,再由该成员的空间中存储的地址找到其所指向的内存空间...,才能访问空间内的元素。

    8710

    指针(2)--指针与数组

    我们需要知道的一个很重要的事实是: 数组其实就是指针,它的底层含义就是地址。 从1中我们也得知数组名就是其首元素地址。...4.二级指针/多级指针 指向某一个变量的地址就是指针,当这个变量本身不是指针时,那么这里的指针叫做一级指针。 我们知道,指针变量是指向某一类型数据的内存地址的变量,它作为变量的本质是不会改变的。...所以指针变量的地址就叫做二级指针。它是指向指针的指针。 那么如果我们要通过pp来找到或者改变a变量,就要解引用两次。...数据类型不同 普通数组的数据类型是普通的类型,但指针数组的数据类型实际上是普通的类型再加上*号,用来表明该数据是指针。 2....毕竟只需要获取指针就可以访问数据,也就可以模拟实现二维数组了。 注意:上述的代码模拟出二维数组的效果,实际上并非完全是⼆维数组,因为每⼀行并非是连续的。 4.

    8510

    【C语言】深入解开指针(四)

    具体来说: 二维数组名代表整个二维数组,它其实就是一维数组指针,指向该数组的首行地址。 当二维数组作为参数传递给函数时,它会自动退化为一维数组指针。...,它也需要指向具体的函数地址才能调用该函数。...由于指针指向0地址,实际调用的是内核NULL地址下的代码。这通常会触发异常或者崩溃。 所以这个代码展示了一个通过函数指针调用匿名函数的语法,它实际上是在尝试访问空指针下的代码从而触发错误。...第二个是函数指针类型,该指针指向的函数参数是int,返回类型是void signal函数的返回类型是这种类型的void(*)(int)函数指针 该指针指向的函数参数是int,返回类型是void 细节分析拓展如下...实际应用中,可以通过函数指针数组实现回调函数、插件等机制。函数也可以作为参数传递给其他函数。 总之,函数指针数组提供了一种灵活高效的方式来管理和调用多个函数在C语言中。怎么高效?

    13110

    指针详解(二级指针、指针数组和数组指针、字符指针、二维数组传参、函数指针变量)(二)

    每行实际上是一个指向整数数组的指针,这些整数数组可能在内存中是分散的。 2、性能:由于内存布局的原因,使用指针数组模拟的二维数组在访问特定元素时可能需要更多的计算,这可能会影响性能。...:当你在写函数时,如果你想让函数操作一个数组,你可以将数组的指针作为函数的参数传递。...:在很多情况下,我们需要将一个函数作为参数传递给另一个函数。...;//是一个函数声明 1.signal是一个函数声明 2.signal函数的参数有两个,第一个是int类型, 第二个是函数指针类型,该指针指向的函数参数是int,返回类型是void signal...函数的返回类型是这种类型的void(*)(int)函数指针 该指针指向的函数参数是int,返回类型是void 3.signal函数的返回类型也是一个函数指针: void(*)(int) 这个函数指针指向的函数参数是

    55210

    C++ 面试必备:常见 C++ 面试题汇总及详细解析

    内存用法 数组名是一个指向数组首元素的常量指针,它存储的是数组首元素的地址。而指针是一个变量,它存储的是某个对象的地址。...函数参数传递 如果将数组名作为函数参数传递,实际上传递的是一个指向数组首元素的指针。而如果将指针作为函数参数传递,可以方便地修改指针所指向的对象。...数组解引用 可以通过数组下标访问数组元素,也可以使用指针进行访问,但是需要注意的是,使用指针访问数组元素需要先将指针解引用,即使用 * 运算符。例如:*p 表示 p 指向的对象。...C++函数调用是编程中常见的一个操作,其过程可以分为以下几个阶段: 函数调用前的准备工作 在函数调用之前,需要进行一些准备工作。首先,需要将函数的参数压入栈中,以向函数传递参数。...函数将根据其实现过程来计算参数并进行其他操作,然后返回一个结果,该结果通常被保存在寄存器中。 函数返回 当函数执行完毕时,需要将返回值存储,并恢复主函数的栈帧及处理状态。

    2.2K30

    深入解析C语言数组和指针(0)

    对于一个NULL指针进行解引用是非法的,因为它并未指向任何东西。如果你知道指针将被初始化为什么地址,就把它初始化为该地址,否则就把它初始化为NULL。...作为函数参数的数组名 通过前面的学习我们知道,数组名的值就是指向数组第一个元素的指针。所以当一个数组名作为参数传递给一个函数时,此时传递给函数的是一份该指针的拷贝。...声明数组参数   对于把数组名当作参数的函数,因为调用函数时实际传递的是一个指针,所以函数的形参实际上是个指针,所以以下两个声明都是正确的: int strlen (char *string );...int strlen( char string[]);   值得注意的是第一种声明无法知道数组的长度,所以函数如果需要知道数组的长度,它必须作为一个显式的参数传递给函数。...下面的两个声明都是使p2指向a2的第一个整型元素: int *p2=&a2[0][0]; int *p2=a2[0]; 作为函数参数的多维数组 作为函数参数的多为数组名的传递方式和一维数组相同

    1.3K30

    iOS开发--我与面试官有个约会

    观察者是用cfrunloopobservecreate来创建的,我们设置监听它的所有属性,该方法还有一个传入函数指针的参数,那我们就可以传入一个方法,这个方法就是监控runloop状态的改变。...block是将函数及其上下文封装起来的对象 block指向成一个名为__方法名_block_impl_0的结构体。并传入了参数,函数指针,关于block的描述,局部变量。最终强转为一个函数指针。...在添加弱引用变量时,最终会调用weak_register_no_lock(),它根据hash算法进行查找,若查找的位置已经有了当前对象对应的弱引用数组,就把新的变量添加到该数组中,若无对应的弱引用数组,...在对象调用dealloc的时候,内部会最终会调用weak_clear_no_lock方法,它会更加当前指针查找弱引用表,把当前对象对应的弱引用都拿出来得到一个数组,遍历该数组的所有弱引用指针,分别置为nil...将小于基准数的数字移到基准数左边,大于它的移动到右边。对于基准数两边的数组,不断重复以上过程。直到每个子集只有一个元素。即为全部有序。 定义两个指针i,j。i指向头部,j指向尾部。

    2.6K40

    一篇读懂 C 指针

    ,它指向一个函数,这个函数返回一个指针,该指针指向另一个指针,它是一个指向 char 的只读指针。”...# 函数的形参声明 在 C 语言中,数组不能被整体操作,也就是说,不能直接将一个数组赋值给另一个数组,或者将数组作为参数传递给其他函数。那么,如果我们想把一个数组传递给函数,该怎么做呢?...当数组作为参数传递给函数时,默认传递的就是指向数组的指针,所以在函数内部通过指针修改的和调用方是同一个数组。...一种场景是,如果函数需要改变调用者传入的指针本身,使其指向新的内存区域,可以使用“指向 T 的指针的指针”,即(T **)作为参数。...从前面的例子可以看到,双指针主要出现在以下两种场景: 动态数组的动态数组,即在多级数据结构中使用动态内存分配 通过参数返回指针,需要在函数内部修改指针本身 双指针的多层间接引用可能让代码显得复杂难懂,但只要理解为什么要这样做

    13510

    C语言的灵魂——指针

    为什么指针是强类型的? **因为,**我们不仅使用指针来存储内存地址,同时也用来解引用他所存储的地址所对应的内容,这样我们就能访问并且修改这些地址对应的值了。...当编译器看到数组作为函数参数的时候,他不会拷贝整个数组,而是仅仅创建一个同名的指针,我们这里就是创建了一个整型指针,编译器只是拷贝了主调函数的数组首元素地址。...多维数组作为参数传给函数 (是几维数组,使用数组名作为指针就返回几维度-1的指针) (例如:一维数组返回指向整型的指针,二维数组返回指向一维数组的指针,三维数组返回指二维数组的指针…) 多维数组作为函数参数的时候...void*p = malloc(n*sizeof(int)); 我们不能解引用一个void指针,通常需要将它转化为一个特定类型的指针,然后再使用它。...函数指针可以被用来作为函数参数,接收函数指针的这个函数,可以回调函数指针所指向的那个函数, 就是一个函数作为参数传递给另外一个函数。

    95410

    C指针基础概览

    **mypp拥有两个解引用符,第一个解引用符去除mypp中存储的myp的地址,第二个解引用符取出myp中存放的x值,对mypp的二次解引用操作会将变量x的内存取出,并使用参数“%d”指定了该内容的大小为...其奥秘在于,声明一个指针,需要指定它指向的数据类型。C语言声明指针的格式通常为 “指向数据的类型* 变量名”。...15 程序中mysum函数接受2个参数,第一个参数是数组长度,第二个参数是指向数组的指针,目前没有较好的检查C语言的数组访问越界问题,所以最好的办法就是把数组的长度直接传给被调用的函数。...函数指针 函数指针 C语言中的数据变量无论是在程序栈还是堆中,都拥有自己的内存地址,函数也一样,函数的代码也需要调入内存才能够被执行,它们在内存中也拥有自己的起始地址,因此可以定义指针指向函数,存储函数的起始地址...文件指针及操作函数 C语言通常用一个指针变量指向一个文件,该指针称为文件指针,通过文件指针就可以对它指向的文件进行各种操作。

    1.1K20

    第七节(指针)

    函数在处理数组时,会查看每个元素的值。当函数发现这个特殊的值时,就意味着到达数组的末尾。这个方法的缺点是,必须预留一个值作为数组末端的指示符,在储存实际数据时不太灵活。...另一个方法相对灵活和直接,也是我采用的方法:将数组大小作为实参传递给函数。数组大小就是一个简单的int值。因此,需要给函数传递两个实参:一个是指向数组首元素的指针,一个是指定该数组元素个数的整数。...这里只有一个新内容,即函数的第1个形参: intnum_array[],它表明第1个参数是指向int类型数组的指针,由形参num_array表示。...数组名是指向该数组首元素的指针。通过指针的运算特性,可以很方便地使用指针来访问数组元素。实际上,数组下标表示法就是指针表示法的特殊形式。 本次还介绍了通过传递指向数组的指针来将数组作为参数传递给函数。...&data[0]和data 11:如果要给函数传递一个数组,有哪两种方式让函数知道已到达数组的末尾? 一种方法是,把数组的长度作为参数传递给函数。

    20140

    【C++】C++ 引用详解 ⑦ ( 指针的引用 )

    ; 如 : 创建一个动态数组或调整现有数组的大小 , 在函数中需要一个指向指针的指针作为参数 , 以便修改原始指针 ; void createArray(int **arr, int size) {...= &new_value; // 修改指针值 } 传递多维数组 : C 语言中 , 数组名本质上是指向数组第一个元素的指针 , 传递多维数组到函数中通常需要传递一个指向指针的指针 , 即二级指针...; 如果将 函数 的形参类型 设置为 引用 类型 , 也能达到 间接赋值 的效果 ; 引用 实际上是 把 间接赋值 的三个条件的后两个条件进行了合并 , C++ 编译器遇到引用 , 还是需要将 引用...还原为 C 语言中的 取地址 传入函数 , 在函数内部使用指针访问实参 ; 3、代码示例 - 指针的引用 该 函数 的 参数 是 一级指针的引用 , 使用该参数时 可以当做 一级指针使用 , 其效果...*& p) 调用该 一级指针 的 引用 , 可以直接访问 一级指针 , 不需要使用 * 符号 ; 因此 这里 直接为 一级指针 进行内存分配 ; 如果此处是二级指针 , 需要先试用 * 符号 取出二级指针指向的一级指针

    38220

    指针(二)

    j) == p[i][j] 8 9在数组的存储结构里就是第i行的第j个元素 二、二级指针 指向指针的指针,称为 二级指针 任何数据都有地址,一级指针的值虽然是地址,但是这个地址做为一个数据也需要空间来存放...*pp 得到所指向一级指针的地址,也就是p的值 2 3二级指针的两次解引用 **pp 得到所指向一级指针指向的值 也就是a的值 二级指针和指针数组 二级指针可以直接访问二维数组吗?...,和普通函数相比就是指针函数返回一个指针 函数指针 指向函数的指针 定义格式:类型 (*指针名) (参数) 1int (*p)(int x, int y); 函数指针的调用 1#include<stdio.h...main() 11{ 12 fun(add);//函数地址作为实参 13 return 0; 14} 可以思考下为什么要把一个函数的地址作为参数传递给另一个函数,要知道在C语言中,一个函数内部是可以直接调用其他函数的...,既然可以直接调用,为什么还要用这么麻烦的办法去把函数当做参数来传递呢。

    35340

    独特视角解读JVM内存模型

    把新生成的对象引用压入栈中 10.通过解释器执行保存在方法区中当前类的无参构造函数,并将A对象引用作为隐式参数传入方法,然后对当前实例对象进行初始化 对象实例初始化分为三步: 分配内存,调用对象构造函数进行初始化...好处: 有利于堆碎片的整理,当移动对象池中的对象时,句柄部分只需要更改一下指针指向对象的新地址即可 缺点: 访问对象的实例数据都要经过两次指针传递 另一种设计方式是使对象指针直接指向一组数据,该组数据包括对象实例数据以及指向方法区中类数据的指针...缺点: 移动对象变得更加复杂,它必须在整个运行时数据区中更新指向被移动对象的引用。 为什么虚拟机必须能通过对象引用得到类的元数据?...对于一个实例方法调用而言,参数this总是作为隐式参数传入的,它用来表示调用该方法的对象本身。...每当虚拟机要执行某个需要用到常量池数据的指令时,它都会通过帧数据区中指向常量池的指针来访问它,以前讲过,常量池中对类型,字段和方法的引用在开始时都是符号。

    40120

    指针:这块地方是我的了!

    整点高级的: 函数参数可以是指针,指针参数可以指向任何类型的变量(包括基本数据类型、结构体、数组、函数等)。 使用指针作为函数参数允许函数直接操作传递给它的变量,而无需返回任何值。 好理解吧?...就是给了这块内存一个机器,直接在上面操作了,不需要复制一个新的地方在操作。 当函数参数是指向基本数据类型的指针时,函数可以修改传递给它的变量的值。...通过数组指针,函数可以访问和修改数组中的元素。 modifyArray 函数接收一个指向整数数组的指针(int* arr)。通过该指针,函数可以访问并修改数组的每个元素。...即指向的函数不接受任何参数。 func_ptr_t 是一个新的类型名,它代表了一个指向无返回值、无参数的函数的指针类型。...func_ptr_arg1_t 是一个新的类型名,它代表了一个指向接受一个 uint8_t 类型参数且无返回值的函数的指针类型。

    6710

    【C进阶】——动态内存管理详解 及 经典笔试题解析

    其次:数组在声明的时候,需要指定数组的长度,它所需要的内存在编译时分配。 但是,对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道。...参数void* ptr接收一个指针,这个指针指向我们使用malloc这些动态开辟内存函数分配的内存块,无返回值。...然后返回指向该内存块起始地址的指针。 还要一点需要注意: 我们要知道realloc的第一个参数void* ptr 也可以接收一个空指针,当它接收的是空指针的时候,就相当于malloc了。...",p是数组名,是首字符’h’的地址,将p作为返回值赋给str,那我们是不是就可以通过str访问数组p了,printf(str)就把"hello world"打印出来了。...为什么呢? 数组p是我们在函数内部创建的一个局部的数组,当函数调用结束就被销毁了,数组所在的这块空间就还给操作系统了,那这时候我们再去打印这块空间里的内容,是不是就非法访问内存了。

    17410
    领券