【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)

					  男儿不展风云志,空负天生八尺躯。——《警世通言·卷四十》

Alt

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述
上篇回顾:上篇我们通过数组名为切入口引出数组与指针间的关系,本篇将介绍不同类型的指针变量在不同场景中的使用

文章目录

    • **字符指针变量**
    • **数组指针变量(指针数组,这里需要注意偏正)**
    • 数组指针的初始化
    • **二维数组传参的本质**
    • **函数指针变量**
    • **函数指针数组**
    • **转移表**
    • **typedef 关键字**


请添加图片描述

字符指针变量

对于字符和字符串,C语言统一使用char类型来表达式。对此字符指针变量有两种表示方法:

  1. 第一种: char ch='a'; char *p=&ch;
  2. 第二种: const char *pstr="Hellow world";

问题:关于const char *pstr="Hellow world"是将整个字符串放到字符指针里面了吗?

解释:本质是字符串"Hellow world"首字符(H)的地址放到字符指针变量pstr中.

面试题<剑指offer>

int main()
{
char str1[] = "hellow world";
char str2[] = "hellow world";
const char *str3 = "hellow world";
const char *str4 = "hellow world";
if(str1 ==str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");	
if(str3 ==str4)printf("str3 and str4 are same\n");else	printf("str3 and str4 are not same\n");
return 0;
}
结果:
str1 and str2 are not same 
str3 and str4 are same

解释:

str3str4指向的是一个同一个常量字符串。C/C++会把常量字符串储存到单独的一个内存区域(常量区),当多个指针指向同一个字符串时,实际是指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时就会开辟不同的内存块,更直白说就算将常量字符串从常量区拷贝一份到数组中,那么在数组初始化时就会在栈中开辟不同的内存块。

使用指针初始化的"hello world"是一个常量字符串,str3指向首字符地址,但该地址在于进程的text段,text段可以保存常量还可以执行代码,是不允许可写权限,只有可读、可执行权限(了解即可)

char *p="hellow";
p[1]='d';//*(p+1)='d';//出现段错误

数组指针变量(指针数组,这里需要注意偏正)

  • 整形指针变量:int *p(存放的是整形变量的地址,能够指向整形数据的指针)
  • 字符指针变量char *p(存放的是字符或字符串首元素的地址,能够指向字符或者字符串数据的指针)

依次类推

数组指针变量:存放的是数组的地址,能够指向数组的指针变量

那个是数组指针变量?那个是指针数组变量?
int *p1[10];
int (*p2)[10];

:[]的优先级高于*。

  • p1和[]结合形成一个数组,指向数组中int *类型的元素,是指针数组。

  • p2和 *加上了()保证了p2先和 *结合形成一个指针,指向一个大小为10个整形的数组指向一个多大的数组),是数组指针(存放的是数组的地址)

数组指针的初始化

int (*p) [10] = &arr;
|     |    |
|     |    |
|     |    []:p指向数组的元素个数
|     p:数组指针变量名
int:p指向的数组的元素类型

二维数组传参的本质

请添加图片描述

二维数组是由多个一维数组组成的,也是连续存放数据。这样说明:二维数组的每个元素都是一个一维数组,根据数组名是数组首元素的地址这个规则,二维数组的数组名表示是第一行的地址(一维数组的地址)

对此第一行的地址的类型是数组指针类型int(*)[5]。意味着跟一维数组传参本质一样,也是传递地址,传递的是第一行这个一维数组的地址

小总结:二维数组传参,形参的部分可以采用数组或者指针形式

void test1(int nums[][5]);//数组类型
void test2(int (*nums)[5]);//指针类型
int main()
{int nums[][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};test1(nums);test2(nums);return 0;
}

函数指针变量

函数指针变量:存放函数地址的,通过函数的地址来调用函数

问题:那么如何得到函数的地址呢?

void test();
int main()
{printf("&test==%p",&test());printf("test==%p",test());return 0;
}
结果:
&test==00991253
test==00991253

通过输出的结果:函数是有地址的,函数名就是函数的地址,&函数名的方式也可以获得函数的地址

void (*pf1)() = &test;
void (*pf2)() = test;

函数指针变量初始化

int    (*pf3)        (int x, int y)|        |           ------------|        |                 ||        |     pf3指向函数的参数类型和个数的交代|    函数指针变量名pf3指向函数的返回类型int (*) (int x, int y) //pf3函数指针变量的类型

函数指针变量的使用(通过函数指针调用指针指向的函数)

int Add(int x,int y)
{return x+y;
}
int main()
{int (*p)(int x,int y)=Add;//如果需要存放多个函数地址,需要使用到函数指针数组printf("%d\n",(*p)(a,b));printf("%d\n",p(a,b));return 0;
}

说明:p(a,b)(*p)(a,b)效果是相同的,因为函数名本身就是函数指针变量


函数指针数组

如果我们需要把多个函数的地址存在数组中,函数名是一个函数指针变量,就需要利用到指针数组和函数配合了

存放函数的地址的指针数组

int (*)()(类型的函数指针):
void (*p[3])(void x,void y)={Add,Sub};方便理解:
p[] = x;
void (*x)(void x,void y)={Add,Sub};

说明:p先和[]结合,说明p是数组,数组的内容void (*)()类型的函数指针。


转移表

函数指针数组的用途:转移表

比如:使用函数指针数组实现计算器

实现函数功能

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 = 0, y = 0;//操作数int input = 0;//选择功能//前面加个0,方便输入数字得到相对函数功能int (*computer[5])(int x,int y) = {0,add,sub,mul,div };do{mune();scanf("%d", &input);if (0 < input && input <= 4){printf("输入两个操作数\n");scanf("%d %d", &x, &y);int ret = (*computer[input])(x, y);printf("结果为%d\n", ret);}else if (input == 0){printf("退出计算机\n");}else{printf("非法输入\n");}} while (input);return 0;
}

说明:根据函数指针数组的结构,我们可以通过两个部分,选择数组中函数,并且为调用函数选择函数参数。

缺点:这么好用的东西也有他自己的美中不足,不知道你有没有发现,这些函数的功能的参数部分,返回值类型是一样的,如果需要使用函数指针算组,建议需要实现的函数参数部分和返回值类型保持一致。


typedef 关键字

typedef:用于类型重命名的(将复杂的类型进行简单化)(typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换)

语法:typedef 类型(自定义取名)

例子:

typedef int it;
typedef int *  intt;
对于数组指针和函数指针有一些区别
typedef int(*part)[5];//数组指针类型int (*)[5]
typedef int (*part)(int;)//函数指针类型 int (*)(int);

关于typedef相关的知识点,这里只是简单介绍。比如:在使用typedef遇到const对象就可能会出现问题如果大家对typedef这个知识点感兴趣,可以参考这份资料:typedf

这里就简单分享一个typedef遇到const的陷阱

typedef char* Ptr
int compare(const Ptr e1 , const Rtr e2)

说明:typedef它不是简单的字符串替换,先分析const Ptr意味着Ptr整体被const赋予了常量性,那么typedef以后应该是char * const e1保证Ptr指针本身的常量性、不能修改指针本身。


请添加图片描述

谢谢大家的观看,这里是个人笔记,希望对你学习C有帮助。

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

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

相关文章

公链系统开发全指南: 从规划到实施

在区块链技术的迅速发展和应用推广下&#xff0c;公链系统的开发成为了当前数字资产领域的热门话题。从规划到实施&#xff0c;公链系统的开发过程需要经历多个步骤&#xff0c;下文将详细介绍每个步骤。 第一步: 规划和设计 市场调研: 分析市场需求和竞争情况&#xff0c;确定…

阿里云服务器ECS经济型e实例和u1实例哪个好?

阿里云服务器ECS经济型e实例和通用算力型u1实例有什么区别&#xff1f;如何选择&#xff1f;ECS经济型e实例是共享型云服务器&#xff0c;通用算力型u实例是企业级独享型云服务器&#xff0c;e实例性价比高&#xff0c;现在2核2G3M带宽一年99元&#xff0c;云服务器u1价格相对要…

轻松找回误删文件,告别企业数据丢失,如何有效利用teamOS二级回收站,提升数据管理效率

在数字化时代&#xff0c;我们越来越依赖电子文件来记录和管理重要信息。 然而&#xff0c;伴随着这种便利的同时&#xff0c;误删或恶意操作导致的文件丢失也成为了一个令人头疼的问题。 那么本文就来谈一谈&#xff0c;企业网盘如何解决误删、甚至恶意删除的问题。 可道云…

【Qt常用控件】—— 输入类控件

目录 1.1 Line Edit 1.2 Text Edit 1.3 Combo Box 1.4 Spin Box 1.5 Date Edit & Time Edit 1.6 Dial 1.7 Slider 1.1 Line Edit QLineEdit是Qt中的一个控件&#xff0c;用于 接收和显示单行文本输入。 核心属性 属性 说明 text 输⼊框中的⽂本 inputMask 输⼊…

如何启用启用WordPress调试模式

最近我们的WordPress网站在访问时&#xff0c;经常出现打不开的现象&#xff0c;我们向主机提供商Hostease咨询后&#xff0c;他们提到这是由于WordPress的某个插件导致的问题&#xff0c;我们在将插件版本升级至最新后&#xff0c;这个问题就消失了。为了方便后续的检查&#…

光透过率检测仪解析

TH-SGT1便携式隧道光透过率检测仪是一种用于快速、准确地测量隧道内光透过率的设备。它的主要特点是便携性和易用性&#xff0c;方便用户进行现场检测和监测。 这种检测仪通常结合了光电测量技术和现代便携式设计&#xff0c;使得用户可以在各种环境下方便地进行光透过率的测量…

python标识符

Python标识符是由用户根据需要自定义的&#xff0c;用于命名变量、函数、类、模块等对象的名称。 命名规则如下&#xff1a; 1. 组成字符&#xff1a;标识符由字母、数字和下划线组成&#xff0c;不能包含其他特殊字符或汉字。 2. 起始字符&#xff1a;标识符必须以字母或下划…

金铲铲无限金币-罗小黑最新

罗小黑最新&#xff0c;下载自测。 记得查看注意事项。 获取链接&#xff1a;https://pan.baidu.com/s/1mRuQPAqWXv6oeihQ5fsn0w?pwdd0s3 提取码&#xff1a;d0s3 --来自百度网盘超级会员V1的分享

学习Rust的第10天:枚举和模式匹配

今天我们来看看一个类似的概念 enums 。 Enums: We saw that in Rust, enums are data types that list possible values, giving a simple and type-safe mechanism to describe alternatives. We looked at how to create enums and use them to represent similar possibili…

【iOS开发】(六)react Native 路由嵌套传参与框架原理(完)20240423

【iOS开发】(六)react Native 路由嵌套传参与框架原理&#xff08;完&#xff09;20240423 感谢拉钩教育的教学。 &#xff08;五&#xff09;我们介绍了四种路由导航&#xff0c;这一节我们介绍他们的嵌套传参和框架的整体原理。到这里&#xff0c;大家已经能用RN框架进行一些…

今心成长之路与人格频率学苑十年发展

在过去的十年里&#xff0c;今心老师以其非凡的人生经历和对人格频率学的深入探索&#xff0c;为无数人带来了巨大的鼓舞力量。他的成长之路充满坎坷与传奇&#xff0c;而人格频率学也在这十年间得到了长足的发展。      今心老师的少年时期颠沛流离&#xff0c;但他凭借坚…

【FMEA软件】FMEA,到底是给谁看的?

免费试用FMEA软件-免费版-SunFMEA FMEA&#xff0c;即故障模式与影响分析&#xff0c;是一种预防性的质量工具&#xff0c;广泛应用于各种行业&#xff0c;尤其是制造业和高科技领域。它的目的是在产品设计或过程设计阶段&#xff0c;通过系统地分析和识别潜在的故障模式&…