“指向指针的指针”的应用场景

结合以下博文来看。

值传递与地址传递的区别_天糊土的博客-CSDN博客

二维数组数和指针操作的理解_天糊土的博客-CSDN博客

“指针+1”的理解_天糊土的博客-CSDN博客

多重指针操作_天糊土的博客-CSDN博客_多重指针

二重指针的应用场景

(1)用指针的指针指向指针数组。

(2)用指针的指针取二维数组的元素。

(3)在子函数中修改主函数传过来的指针的指向。

代码示例

(1)用指针的指针指向指针数组(这里用p指向了a)

//用二重指针指向指针数组#include<stdio.h> 
int change(char **p)//此函数将每个字符串的字符都改成‘c’
{int i, j;for (i = 0; i < 5; i++){for (j = 0; *(*(p + i) + j) != '\0'; j++){*(*(p + i) + j) = 'c';printf("%c", *(*(p + i) + j));}printf("\n");}return 0;
}int main(void)
{char *a[5] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };change(a);//这里的a是数组的字母,它表示a[0]的地址,则*a表示a[0]//而a[0]是字符指针,*a[0]才表示字符串“hello”中的第一个字符‘h’return 0;
}

(2)用指针的指针取二维数组的元素

/*
#include<stdio.h//错误的做法
int change(char **p)
{int i, j;for (i = 0; i < 5; i++){for (j = 0; *(*(p + i) + j) != '\0'; j++){printf("%c", *(*(p + i) + j));}printf("\n");}return 0;
}//若希望赋值,则不能使用指针的指针,要使用数组进行运算。
int change(char p[][10])
{int i, j;for (i = 0; i < 5; i++){for (j = 0; p[i][j] != '\0'; j++){p[i][j] = 'c';printf("%c", p[i][j]);}printf("\n");}return 0;
}int main(void)
{char a[5][10] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };change(a);return 0;
}*/#include<stdio.h> 
int change(char **p)
{int i, j;for (i = 0; i < 5; i++){for (j = 0; *(*(p + i) + j) != '\0'; j++){*(*(p + i) + j) = 'c';printf("%c", *(*(p + i) + j));}printf("\n");}return 0;
}int main(void)
{char a[5][10] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };char *b[5] = { a[0],a[1],a[2],a[3],a[4] };//这样做读取和写入操作都是可以的。change(b);return 0;
}

(3)在子函数中修改主函数传过来的指针的指向

比如主函数申明一个指针变量,且不为其分配指向空间(只是指向NULL),然后取该指针变量的地址传参给子函数;然后在子函数里根据需要申请一片空间;对传参解引用后得到原来的指针变量,且把该指针变量指向刚才申请的空间(修改了原来指针的指向,这是本质);从而实现不确定返回值个数的编程方法(这是应用)。

例子1:

#include<stdio.h>
int find(char *s, char src, char **rt)//从s中查询出src字符所在的位置并在rt中返回。
{int i = 0;while (*(s + i)){if (*(s + i) == src)//只会出现一次满足条件,此时将此地址给*rt,即p{* rt = s + i;//这里修改了p的指向}i++;}return 0;}int main(void)
{char a[10] = "zhuyujia";char *p=NULL;find(a, 'y', &p);//改变p的指向,在子函数中实现printf("%s", p);getchar(); getchar();return 0;
}/*
//补充:
打印指针的时候,会把指针所指向的内容以及至字符串末位的内容都打印出来
#include<stdio.h>
int main(void)
{char a[10] = "abcdefgff";char* p = &a[6];printf("%s", p);//会打印gffgetchar(); getchar();return 0;
}
*/

例子2: 

#include <stdlib.h>
#include <time.h>
#include<stdio.h>
/*当然有必须使用二级指针才能解决的情况,如,某个函数的功能是
返回某个问题的计算结果,但是结果数据是不确定个数的值,所以
在调用此函数时不知道事先应分配多少空间来保存返回的数据,此时
的处理办法就是传递一个没有分配空间的指针的指针(地址)进去,
让函数自己根据计算的结果分配足够的空间来保存结果,并返回,
调用者使用了结果后,由调用者负责内存的释放,即,大家可能听说
过的"谁使用(调用)谁释放"之类的话,如下面的代码:*///返回不定结果个数的计算函数
//参数int **pResult  保存返回数据的指针的指针
//参数int &count     保存返回的结果个数
void Compute2(int **pResult, int &count)
{//使用随机数来模拟计算结果数的个数srand(time(NULL));count = rand() % 10;//控制个数在10个以内*pResult = new int[count];//*pResult相当于主函数传来的pResult指针,//这里就修改了主函数中的pResult指向,因为还是//指针,因此可以指向新开辟的空间for (int i = 0; i < count; i++){(*pResult)[i] = rand();//给结果随即赋值}
}//返回不定结果个数的计算函数(此函数不能返回数据)
//参数int *pResult   为保存返回数据的指针
//参数int &count     为保存返回的结果个数
void Compute1(int *pResult, int &count)
{//使用随机数来模拟计算结果数的个数srand(time(NULL));count = rand() % 10;//控制个数在10个以内pResult = new int[count];for (int i = 0; i < count; i++){pResult[i] = rand();//给结果随即赋值}
}int main(void)
{int *pResult = NULL;//待获取结果的指针,这里没有分配空间大小,因为不知道返回结果的个数//具体返回的个数在在子函数中确定,此时指针pResult指向也改变了//这就间接的说明“在子函数中修改主函数传来的指针”的意图//具体的应用就在于返回个数不确定的场景,这是后面编程的一个体会点int count = 0;//返回结果的个数/*Compute1(pResult,count);//pResult为指针,第二个参数使用引用传递,//使用这个函数时,在函数内部分配的内存的指针并没有返回到主函数中for ( int i = 0 ; i < count ; i++ )printf("第 %d 个结果为 : %d\n",pResult[i]);//执行了Compute1()函数后,pResult的值还是为NULLdelete [] pResult;pResult = NULL;*///&pResult为指针的地址(即指针的指针),第二个参数使用引用传递Compute2(&pResult, count);for (int i = 0; i < count; i++)printf("第 %d 个结果为 : %d\n", i, pResult[i]);delete[] pResult;pResult = NULL;getchar();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

su root 和su - root 的区别

前几天&#xff0c;在一次项目中&#xff0c;犯了一个很低级的错误&#xff0c;但是没弄明白是什么问题。情况是这样的&#xff0c;我们在做灾备&#xff0c;重启系统化&#xff0c;以root用户权限&#xff0c;通过 su oracle &#xff0c;进去后&#xff0c;oracle的rac 无法正…

弹出框

<!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta http-equiv"Content-Type" content"text/html; charsetgb2312" /> <title>AlertBox 弹出层&#xff08;信息提示框&#xff09;效果&l…

一些Base64编码/解码及数据压缩/解压方面的知识

一.Base64编码/解码 一般用到的是Delphi自带的单元EncdDecd,当然还有第三方提供的单元或控件,其中我所接触到的认为比较好的有Indy的TIdMimeEncode / TIdMimeDecode组件,以及RjMime单元. 在这里主要想讲讲如何才能获得最好的编码/解码性能,EncdDecd提供了EncodeStream/DecodeSt…

easyUI 绑定右键菜单在数据行上显示

easyUI的显示数据的div都有一个样式,如下图 所有的表格都有一个datagrid-cell的样式那么这个时候我们就可以利用jquery来做时间的绑定了 下面是主要的js代码: /*绑定右键*/$(".datagrid-cell").live(contextmenu,function(e){//显示快捷菜单$(#mm).menu(show, {left:…

值传递与地址传递的区别

以下内容源于网络资源的学习与整理&#xff0c;欢迎交流。 总结 值传递&#xff0c;只是把原参的复制品传给形参&#xff0c;在子函数中修改这个形参&#xff0c;不会改变主函数中的原参。 地址传递&#xff0c;由于形参和原参表示同一个内容&#xff0c;在子函数中修改形参&a…

交叉编译器arm-linux-gcc

(一)交叉编译器简介 在一种计算机环境中运行的编译程序&#xff0c;能编译出在另外一种环境下运行的代码&#xff0c;这个编译过程就叫交叉编译.简单地说&#xff0c;就是在一个平台上生成另一个平台上的可执行代码. (二)体系结构与操作系统 (1)常见的体系结构有ARM结构、x86结…

web前端细解cookie那些事

web前端细解cookie那些事&#xff0c;在互联网时代&#xff0c;IT行业飞速发展&#xff0c;带动了web前端开发行业的兴趣。由于行业新兴起时间不久&#xff0c;专业人才缺乏&#xff0c;薪资待遇较高&#xff0c;已成为众多IT学子选择就业的首选&#xff0c;今天就为分享一些有…

一个很好的机器学习普及网站

1.介绍svm等算法深入浅出的网站 Free Mind 2.关于聚类算法的普及 A tutorial on Clustering Algorithm(中文翻译) 模糊聚类的应用--目标分割 exlusive clustering&#xff08;比如K-means) hierarchy clustering&#xff1a;先将 n 个样品各看成一类&#xff0c; 然后规定类与…

字符串处理示例--列车车次查询.sql

--列车车次信息数据表CREATE TABLE tb(col varchar(100))INSERT tb SELECT 1434/1/2/14UNION ALL SELECT "10653(85707)"UNION ALL SELECT "32608/7(83212/1)"UNION ALL SELECT "50057&#xff08;)"UNION ALL SELECT "T888&#xff08;备&…

查找算法的总结

声明&#xff1a;以下内容来源于网络资料的学习和整理 一、查找技术分类 1、静态查找表技术&#xff08;顺序查找、二分查找、分块查找&#xff09; 2、动态查找表技术&#xff08;二叉查找树&#xff09; 3、哈希表技术&#xff08;哈希表技术&#xff09; 二、查找技术说明…

一个C程序的编译过程(Linux环境下Gcc)

一 以下是C程序一般的编译过程&#xff1a; 从图中看到&#xff1a; 将编写的一个c程序&#xff08;源代码 &#xff09;转换成可以在硬件上运行的程序&#xff08;可执行代码 &#xff09;&#xff0c;需要进行编译阶段 和链接这两个阶段。 其中&#xff0c; 1. 编译阶段先通…

python3 django连接mysql 数据库

详情参考&#xff1a; https://blog.csdn.net/weixin_33127753/article/details/89100552 https://imshusheng.com/python/216.html 报错环境 python3.6&#xff0c;django2.2&#xff0c;PyMySQL0.9.3……django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or…

redis 主从复制 [转]

一、Redis的Replication&#xff1a; 这里首先需要说明的是&#xff0c;在Redis中配置Master-Slave模式真是太简单了。相信在阅读完这篇Blog之后你也可以轻松做到。这里我们还是先列出一些理论性的知识&#xff0c;后面给出实际操作的案例。 下面的列表清楚的解释了Redis…

动态查找表之二叉搜索树

一、二叉搜索树&#xff08;BST&#xff09; 二叉搜索树&#xff08;二叉排序树&#xff09;定义如下&#xff1a; &#xff08;1&#xff09;一棵空树&#xff1b; &#xff08;2&#xff09;或者不是空树&#xff1a; 1&#xff09;若左子树不空&#xff0c;则左子树上所有…

Mysql数据导入导出

导出导入数据库导出mysqldump方法mysqldump -u用户名 -p密码名 database [table]> 目标文件导入mysql -uroot -prootuse databasesource 目标文件&#xff1b;PS: 这种方法是导出整个表数据&#xff0c;并且带着建表信息&#xff0c;假如导入的数据库有同名的表&#xff0c;…

2-10 就业课(2.0)-oozie:9、oozie与hue的整合,以及整合后执行MR任务

5、hue整合oozie 第一步&#xff1a;停止oozie与hue的进程 通过命令停止oozie与hue的进程&#xff0c;准备修改oozie与hue的配置文件 第二步&#xff1a;修改oozie的配置文件&#xff08;老版本的bug&#xff0c;新版本已经不需要了&#xff09;这一步我们都不需要做了 修改ooz…

Screen Painter 程序设计

一、Screen 的创建及维护, TCode:SE51 输入程序名称&#xff0c;单击【建立】&#xff0c; 程序1000为SAP预留屏幕号&#xff0c;屏幕号必须定义1000外的其他数字&#xff0c;且最多不超过四位&#xff0c; 本例定义屏幕为SAP预留屏幕号为&#xff1a;100 * 属性设置&#xff1…

完全图解VS2017安装过程并演示VS2017创建Linux项目和调试

VS2017个人免费版即社区官方下载地址为&#xff1a;https://download.microsoft.com/download/D/1/4/D142F7E7-4D7E-4F3B-A399-5BACA91EB569/vs_Community.exe 这是一个很小的在线下载安装器。VS2017安装变得人性化了&#xff0c;根据组件的分类&#xff0c;供安装用户选择&…

spring--打印hello--注解component--自动创建对象

1.创建 GroupId----项目目录&#xff08;com.javaspring&#xff09; Artifactid---项目名称(spring01qiuckstart) Version--版本默认 2.默认打开的pom.xml文件 编辑---编写spring核心项目依赖 <?xml version"1.0" encoding"UTF-8"?> <project …

菜鸟学数据库(四)——超键、候选键、主键、外键

这些年的一些经历告诉我&#xff0c;很多初学者搞不清超键、候选键等&#xff0c;被数据库中的各种键搞的一头雾水。下面就跟大家一起聊聊数据库中的那些键。 首先看看各种键的定义&#xff1a; 超键(super key):在关系中能唯一标识元组的属性集称为关系模式的超键 候选键(ca…