指针进阶(详解)

这篇具有很好参考价值的文章主要介绍了指针进阶(详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

在开始这篇之前,前面有两篇指针初阶,如果需要的话可以去看看哟!指针初阶1,指针初阶2

一.字符指针

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

对于一个字符串,那么指针又该如何指向呢?

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

毫无疑问p里存的是地址,那它存了abcdefg的所有地址吗?当然不是,因为它根本存不下(一个指针在32为机器下只有4个字节,如果不太明白可以看看指针初阶)。实际上,它存的是首字符a的地址。字符串在内存里是连续存放的,所以只需要找到首元素地址就可以啦。ps:这和数组很像,事实上处理字符串时也可以按照下标来处理。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

追加一个小知识:字符串可以直接使用%s打印是因为它有\0作为结束标志。但如果全部是整数的话,没有结束标志就只能通过下标挨个打印。

一道面试题

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

首先,str1和str2是两个数组,需要开辟两个空间,而数组名代表首元素地址,空间不同首元素地址自然不同,故str1!=str2。但是str3和str4是指针变量,里面存的都是h的地址并且hello,bite是一个常量字符串永远不能被改变。所以此时编译器就会认为既然都一样且没法被改变,那么就只会开辟一个空间,str3和str4都指向同一空间,故str3==str4。(可以理解为编译器的一种规定)

二.指针数组

存放整形的数组->整形数组,存放字符的数组->字符数组,存放指针的数组->指针数组。

1.一次打印多个字符串

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

我们如何打印呢?很简单,因为数组内每个元素存的都是各个字符串首元素地址,所以我们只需要依靠首元素地址就能打印出所有字符串。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm
指针进阶(详解),# c语言进阶,面试,数据结构,jvm

2.模拟二维数组

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

它的打印需要使用两个for嵌套,因为它不能像字符串那样打印一串,这里其实也就是用一维数组模拟二维数组(但不同的是二维数组每一行每一列都是连续存放的,而这里每一行不一定连续)

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm
指针进阶(详解),# c语言进阶,面试,数据结构,jvm

三.数组指针

1.定义

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm
指针进阶(详解),# c语言进阶,面试,数据结构,jvm

追加个小知识:【】的优先级高于*所以别忘了加括号哦。

ps:如果pa先与*结合就说明是个指针,如果先于【】结合就说明是个数组。

pps:这里的&arr是整个数组的地址,也就是如果+1的话是跳过整个数组。注意与数组名区分开。

2.应用

1.强行使用

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

这样写实际上很别扭,当然实际上一般也没人会怎么写。所以它的真正作用体现在二维数组里。

2.正常使用

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

一些练习

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

四.函数指针

指向函数的指针。

一段代码

首先,函数名=&函数,故函数名就是函数地址(如果需要验证的话,写一个函数再用%p输出就可以了,这里就不再累述了)

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

分析这个指针的构成,首先是一个指针故pf应该先与*结合,其次指向一个函数,后面就应该接上(参数),最后该函数是int类型,故再前面写上int。将这3个部分串起来就是如上指针。

接下来使用pf指针调用Add函数。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

首先对pf进行解引用,解引用后就是原函数。也就是*pf=Add,接下来是传参(参数1,参数2),这样就完成了调用功能。实际上,在调用时前面的星号是没有作用的,因为如我们平常调用函数Add(2,3),pf里存的本身就是Add,所以不需要解引用。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

代码一

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

这道题的关键就是把0当成地址来看。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

该代码是一次函数调用,调用0地址处的函数

ps:以上代码出自c语言缺陷与陷阱

代码二

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

依然从名字signal入手。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

1.该代码是一次函数的声明。
2.声明的函数名字是signal
3.参数有两个,第一个是int类型,第二个是函数指针类型
4.signal函数的返回值是一个函数指针

五.函数指针数组

数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组,比如:int arr[10];数组的每个元素是int。那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

使用:简单的计算器

int add(int a, int b){
	return a + b;
}
int sub(int a, int b){
	return a - b;
}
int mul(int a, int b){
	return a * b;
}
int div(int a, int b){
	return a / b;
}
int main()
{
	int x, y;
	int input = 1;
	int ret = 0;
	do{
		printf("*************************\n");
		printf("*** 1:加法      2:减法***\n");
		printf("*** 3:乘法      4:除法*** \n");
		printf("**********0.退出*********\n");
		printf("*************************\n");
		printf("请选择:");
		scanf("%d", &input);
		switch (input){

		case 1:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = add(x, y);
			printf("ret = %d\n", ret);
			break;
		case 2:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = sub(x, y);
			printf("ret = %d\n", ret);
			break;
		case 3:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = mul(x, y);
			printf("ret = %d\n", ret);
			break;
		case 4:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = div(x, y);
			printf("ret = %d\n", ret);
			break;
		case 0:
			printf("退出程序\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

这个代码很简单就不多说了。实际上我们可以看到这个代码很冗长繁琐,如果在之后我们需要给计算器添加新的功能的话,毫无疑问case会加长,我们能不能有一种方法避免这种写法呢?

int add(int a, int b){
	return a + b;
}
int sub(int a, int b){
	return a - b;
}
int mul(int a, int b){
	return a * b;
}
int div(int a, int b){
	return a / b;
}
int main()
{
	int x, y;
	int input = 1;
	int ret = 0;
	int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //使用数组去除冗长的调用
	while (input)
	{
		printf("*************************\n");
		printf("*** 1:加法      2:减法***\n");
		printf("*** 3:乘法      4:除法*** \n");
		printf("**********0.退出*********\n");
		printf("*************************\n");
		printf("请选择:");
		scanf("%d", &input);
		if (0 == input){
			printf("退出程序。\n");
			break;
		}
		if ((input <= 4 && input >= 1)){
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = (*p[input])(x, y);
		}
		else
			printf("输入有误\n");
		printf("ret = %d\n", ret);
	}
	return 0;
} 

使用函数指针数组的前提是所有的函数类型都相同,都是两个参,参数类型都是int,返回值都是int。

六.指向函数指针数组的指针

其实本质上就是一个数组指针,只不过这个数组的类型是一个函数指针类型数组。

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

要分辨类型,需要先看与哪个操作符结合。

一些练习

指针进阶(详解),# c语言进阶,面试,数据结构,jvm

七.回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个 函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

应用例子qsort函数,由于篇幅比较大,将其放到了下一篇博客里qsort函数

指针进阶(详解),# c语言进阶,面试,数据结构,jvm文章来源地址https://www.toymoban.com/news/detail-808776.html

到了这里,关于指针进阶(详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言完整版笔记(初阶,进阶,深刨,初阶数据结构)

    1.初阶: 1.1C语言初阶易忘知识点速记 2.进阶:  1.2C语言进阶易忘点速记 3.深剖: 2.1C语言重点解剖要点速记 2.2C语言重点解剖操作符要点速记   2.3C语言重点解剖预处理要点速记 2.4C语言重点解剖指针和数组要点速记 2.5C语言重点解剖内存管理函数要点速记 4.数据结构:

    2024年02月16日
    浏览(36)
  • 【数据结构】C语言结构体详解

    目录 前言 一、结构体的定义 二、定义结构体变量 三、结构体变量的初始化 四、使用typedef声明新数据类型名 五、指向结构体变量的指针 总结 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 📣如需转

    2024年02月04日
    浏览(46)
  • 【数据结构】C语言队列(详解)

    前言: 💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥 ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--C语言实现队列 目录 一.队列概念及结构 1.1队列的概念 1.2队列的结构 二.队列的实现 2.1头文件 2.2链式队列的结构定义 2.3队列接口的定义 2.4初始化队列 2.5判断队列

    2024年02月10日
    浏览(44)
  • 数据结构(C语言)——顺序表详解

    数据结构是计算机存储和组织数据的方式。常用的数据结构有:数组(Array)、栈(Stack)、队列(Queue)、链表(Linked List)、树(Tree)、图(Graph)、堆(Heap)等;而数据结构又可以通过逻辑结构与物理结构进行分类,逻辑结构是指数据元素之间的逻辑关系,也就是数据元

    2024年04月16日
    浏览(38)
  • 【数据结构】队列---C语言版(详解!!!)

    队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 先进先出FIFO (First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 入队列 :进行插入操作的一端称为队尾 出队列 :进行删除操作的一端称

    2024年02月10日
    浏览(50)
  • 【数据结构】栈---C语言版(详解!!!)

    栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。栈中的数据元素遵守 后进先出LIFO (Last In First Out)的原则。 压栈 :栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈 :栈的删除

    2024年02月10日
    浏览(38)
  • 【C语言进阶(五)】指针进阶详解(上)

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C语言学习分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多C语言知识   🔝🔝 本篇文章将讲解以下几个方面内容: 字符指针 数组指针 指针数组 数组传参和指针传参 函数指针 在这之前先温故一下指针的概念

    2024年02月12日
    浏览(56)
  • 数据结构-循环队列详解(c语言版)

    目录 一、什么是循环队列? 二、特点 三、基本运算 四、代码实现  1、初始化 2、入队 3、出队 4、队满? 5、队空?  6、输出队列 7、队列大小 8、获取队首元素 五、队列应用场景 六、完整代码 1、完整代码 2、运行结果 七、总结 前言 相比于链队列, 循环队列 有着内存固

    2024年01月20日
    浏览(55)
  • C语言——指针详解(进阶)

    前言: 学完 C语言初阶 后,应该对指针有了初步的了解,下面学习进阶的内容,让我们更快的掌握C语言指针。 指针的概念: 指针就是一个变量,用来存放地址,地址与内存空间一一对应 指针的大小是固定的4/8个字节(32位平台/64位平台) 指针是有类型的,指针的类型决定

    2024年02月16日
    浏览(35)
  • 追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构

        😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主! 😘博主小留言:哈喽! 😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不

    2023年04月17日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包