void指针作为函数参数

我们知道,函数传址可以产生副作用,如一级指针做函数参数可以对一个普通变量产生副作用:

int x = 0; void demo(&x);#include <stdio.h> #include <malloc.h> void demo(int* p); main() { int x = 0; demo(&x); printf("%d\n",x);//11 getchar(); } void demo(int* p) { *p = 11; // 操作p的目标对象,可以产生副作用 p = (int*)malloc(sizeof(int));// 操作自身,作为本函数的临时变量,不影响主调函数 *p = 22; } printf("%d\n",x);

如果需要对一个一级指针产生产生副作用,需要将一级指针的地址传递给被调函数,所以,被调函数需要一个二级指针用做函数参数:

#include <stdio.h> #include <malloc.h> void demo(int** p); main() { int x = 0; int* p = &x; *p = 11; demo(&p); printf("%d %d\n",x,*p);//11 22 getchar(); } void demo(int** p) { *p = (int*)malloc(sizeof(int));// 操作p的目标对象,可以产生副作用 **p = 22; p = NULL; // 操作自身,作为本函数的临时变量,不影响主调函数 }

我们知道,单链表的节点通常存储在堆上,所以节点通常用指针指向,对于不带头节点的单链表,相关操作时可能会修改到头节点(一个一级指针),所以相关操作的一些函数就需要一个二级指针做函数参数来产生副作用:

#include <stdio.h> #include <malloc.h> struct Node{ int data; struct Node *next; }; void listInsert(struct Node **head,int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; if(*head!=NULL) newNode->next = *head; *head = newNode;// 头节点为实节点 } void listPrint(struct Node *head) { while(head!=NULL) { printf("%d ",head->data); head = head->next; } printf("\n"); } void listDel(struct Node *head); // 略 int main() { struct Node *head = NULL; for(int i=1;i<11;i++) listInsert(&head,i); listPrint(head); getchar(); }

我们知道,指针数组是指一个元素是一级指针的一维数组,数组名做右值时在一定的上下文中(数组名不是操作符&、sizeof的操作数时)是一个指向数组首元素的指针,而指针数组的元素又是指针,所以指针数组名在一定的上下文中等同于一个二级指针。

#include <stdio.h> #include <malloc.h> void test(int **p) { // ++p,p是一个指针,其偏移的地址或字节数以目标类型(这里是int*)的内存大小为步长 // p解引用:*p做左值产生副作用 *++p = (int*)malloc(sizeof(int)); **p = 11; } main() { int* arr = {0}; // 静态数组 int** p = arr; test(arr); printf("%d\n",*arr); // 11 printf("%d\n",arr); // 11 getchar(); }

如何理解++p,关键在于理解p的目标类型是int*。

p是*(p+i)的语法糖,其自身类型是int*,目标类型是int。

以上数组arr是静态分配的静态数组,也可以动态分配堆内存,形成一个动态指针数组,其元素再在堆内存上动态分配一维数组,便可以在逻辑上形成一个动态二维数组:

void指针作为函数参数

#include <stdio.h> #include <malloc.h> int** demo(int row,int col) { // the 2D array variable is declared to be `int **` (a pointer to an int *) // a dynamically allocated array of dynamically allocated int arrays // (a pointer to pointers to ints) int **two_d_array; int i; // allocate an array of N pointers to ints // malloc returns the address of this array (a pointer to (int *)'s) two_d_array = (int**)malloc(sizeof(int *) * row); // for each row, malloc space for its column elements and add it to // the array of arrays for (i = 0; i < row; i++) { // malloc space for row i's M column elements two_d_array = (int*)malloc(sizeof(int) * col); } return two_d_array; } /* * initialize a 2D array * arr: the array * rows: number of rows * cols: number of columns */ void init2D(int **arr, int rows, int cols) { int i,j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { arr = (i+1)*(j+1); } } } void print(int **arr, int rows, int cols) { int i,j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { printf("%d ",arr); } printf("\n"); } } int main() { int row,col; row = 3; col = 4; int **two_d_array = demo(row,col); init2D(two_d_array, row,col); print(two_d_array,row,col); int *arr; for(row=0;row<3;row++) arr = (int*)malloc(sizeof(int)*4); init2D(arr,3,4); print(arr,3,4); getchar(); }

ref

https://diveintosystems.org/book/C2-C_depth/arrays.html

本文【void指针作为函数参数】由作者: 自旋锁 提供,本站不拥有所有权,只提供储存服务,如有侵权,联系删除!
本文链接:https://www.cuoshuo.com/blog/4120.html

(0)
上一篇 2023-03-09 08:06:02
下一篇 2023-03-09 08:17:02

相关推荐

  • avx指令集对游戏的影响

    在CPU的一代一代“进化”中,除了频率、缓存乃至核心结构的变化外,有一个不太起眼的升级经常会被小伙伴们忽略,就是“扩展指令集”。指令集很多小伙伴大概耳熟,它就是指挥CPU工作的指令。不过扩展指令集又是什么?对我们使用有什么影响呢? 用一个简单的例子来说,如果说指令集是让CPU理解“9×9就是9个9连加”这种基本常识并进行计算的话,扩展指令集就可以看做是乘法口…

    2023-03-19
    000
  • outlook发邮件抄送那里填什么,outlook无法发送邮件

    OUTLOOK使用技巧6-密件抄送 快速启用“密件抄送” 有时根据需要您希望将某份邮件秘密抄送给某些同事,这时您可以启用“密件抄送”: 1.按下 Ctrl + N新建电子邮件; 2.点击“选项”>“密件抄送”,可在显示的“密件抄送”框中指定秘密接收此邮件的人员,其他收件人看不到此框中的人员: 快速切换界面 有时您需要不断在“邮件”和“日历”等界面之间进…

    2023-03-19
    000
  • wince 软件 很难找(wince车载软件集合)

    车载现在的电动汽车除了是电动的以外,还有一个名字是智能汽车,在智能上除了辅助驾驶之外,最大的智能可能要属车载大屏,或者往细了说是娱乐,现在的汽车上基本上是在智能上卷了起来,既然是智能那就一定有系统,今天就来看看现在主流的一些车载OS。 1、WinCE系统: Windows CE操作系统是在PC Windows操作系统基础上研发而来的车载OS,对硬件要求不高,…

    2023-03-18
    100
  • ps教程零基础(ps入门教程自学图解)

    什么是PS: PS指Photoshop,是由Adobe Systems开发和发行的图像处理软件。 Photoshop的专长在于图像处理,而不是图形创作。图像处理是对已有的位图图像进行编辑加工处理以及运用一些特殊效果,其重点在于对图像的处理加工;图形创作软件是按照自己的构思创意,使用矢量图形来设计图形。 平面设计是Photoshop应用最为广泛的领域,无论是图…

    2023-03-14
    200
  • sql数据库开发是什么,sql数据库常用命令

    SQL 是一种非常常见但功能强大的工具,它可以帮助从任何数据库中提取、转换和加载数据。 数据查询的本质在于SQL。 随着公司和组织发现自己处理的数据量迅速增加,开发人员越来越需要有效地使用数据库来处理这些数据。 所以想要深入数据领域,SQL是必须的! 要掌握这门语言,你需要知道如何使用一些命令——其中大部分命令都基于一些基本命令。 对于整篇文章,我使用的是一…

    2023-03-15
    700
  • windows正在启动后无信号 win7正在启动然后黑屏

    我们在使用电脑的过程中,难免会出现硬件或者系统、软件的故障,而近期有一个网友称自己的电脑出现了一个故障,那就是开机之后显示器黑屏无信号输入,但电脑主机一直在运行,其实出现了这个故障,原因众多,我们需要一一排查还可以解决问题,下面装机之家分享一下开机之后显示器黑屏无信号输入,但电脑主机一直在运行的解决方法。 据了解,该网友的显示器黑屏,并提示了无信号输入,显示…

    2023-03-20
    000
  • coreldraw快捷键用不了,coreldraw哪个好用

    关于对象选择在Coreldraw中选择工具只有一个,看似简单,学问大着呢,请看: 1. 按空格键可以快速切换到“挑选”工具 2. 按shift键并逐一单击要选择的对象,可连续选择多个对象 3. 选定隐藏在一系列对象后面的单个对象,按住 ALT ,然后利用“挑选”工具单击最前面的对象,直到选定所需的对象。 4. 圈选若干个对象:利用“挑选”工具沿对角线拖动鼠标…

    实用教程 2023-03-14
    300
  • 二分法查找是什么意思

    引入: 二分法思想无处不在,我们经常玩的猜数字游戏,0-99的范围,最多需要多少次我就可以猜对呢? 使用二分法思想,最多仅仅需要7次就可以查找到。 二分法查找是非常恐怖的,以2的倍数缩小范围。所以时间复杂度O(logn) 局限性: 1.针对二分法查找的数据必须是有序的。 2.二分法查找依赖于顺序表结构,也就是数组。因为二分法需要随机访问元素,也就是O(1)的…

    2023-03-12
    400
  • 电脑的时间如何进行gps授时(手机有gps为什么不能授时)

    按照我们自己常说的观点,GPS卫星授时就是给需要时间的设备提供GPS卫星上的准确时间,也就把GPS卫星上的时间通过某种GPS授时设备传输/同步到其他设备上的过程。当然GPS卫星授时的时间也不是完全一致,会出现一定的误差,但是GPS卫星授时还是目前相对获得准确时间的方式之一。 如果按照百度百科的更学术解释是,GPS卫星授时是针对自动化系统中的计算机、控制装置等…

    2023-03-13
    600
  • 电脑的发展史简单介绍100字_电脑的发展史简介

    计算机的发展历史可以追溯到古希腊时期,当时已经有一些机械计算器。 但是,真正意义上的计算机是在 20 世纪初期诞生的。1936 年,英国数学家 Alan Turing 发明了第一台逻辑机器,从而奠定了计算机科学的基础。 1940 年代,第二次世界大战期间,计算机被广泛用于军事计算。1943 年,美国科学家设计了第一台大型电子计算机,称为 ENIAC,它被用于…

    2023-03-13
    500

发表回复

登录后才能评论
返回顶部
错说博客上线啦!