【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");
    else
    	printf("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.mfbz.cn/a/569279.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue项目启动npm install和npm run serve时出现错误Failed to resolve loader:node-sass

1.常见问题 问题1&#xff1a;当执行npm run serve时&#xff0c;出现Failed to resolve loader: node-sass&#xff0c;You may need to install it 解决方法&#xff1a; npm install node-sass4.14.1问题2&#xff1a;当执行npm run serve时&#xff0c;出现以下错误 Fa…

ADC内部运行原理

1以一个简单的外置ADC为例讲解 1在外部由地址锁存和译码经行去控制通道选择开关//去控制外部那一条IO口输入&#xff0c;输入到比较器 2逐次逼近寄存器SAR每次从三态锁存缓冲器读取值在由DAC&#xff08;数模转换成模拟电压&#xff09;在输入到比较器当io信号和DAC信号几乎一样…

JWT原理解析

一、概述 虽然现在很多的开发框架会支持JWT的使用&#xff0c;但是对JWT还是没有一个详细的了解&#xff0c;有很多疑惑&#xff1a; JWT比之前的session或者token有什么好处&#xff1f;JWT的构成元素是什么&#xff1f;JWT从生成到使用的详细流程&#xff1f; 二、 JWT 2…

华为数通方向HCIP-DataCom H12-821题库(多选题:321-340)

第321题 关于OSPF的命令描述,不正确的是: A、stub区域和totally stub区域配置了no-summary参数 B、OSPFv2和OSPF v3配置接口命令的区别是OSPF V2可以使用network命令,而OSPFv3直接 C、在接口上使能stubrouter命令用来配置次路由器为stub路由器,stub路由器可以与非stub路由 …

AUTOSAR-COMStack-003_SignalGroup如何发送接收

1. Ref Ref.1 AUTOSAR_RS_Main.pdf Ref.1 AUTOSAR_RS_Features.pdf Ref.2 AUTOSAR_SRS_COM.pdf Ref.3 AUTOSAR_SWS_COM.pdf 2. 为什么要使用Signal Group&#xff1f; 2.1 Traceabilty [RS_PO_00004] AUTOSAR shall define an open architecture for automotive software.…

debian和ubuntu的核心系统和系统命令的区别

Debian和Ubuntu虽然有很深的渊源&#xff0c;都是基于Debian的发行版&#xff0c;但它们在核心系统和系统命令上还是有一些差别的。以下是一些主要的不同之处&#xff1a; 1. 发布周期&#xff1a; - Debian&#xff1a; Debian项目采用滚动发布模型&#xff0c;持续更新&a…

【数据结构(邓俊辉)学习笔记】向量03——无序向量

文章目录 0.概述1.元素访问2.置乱器3.判等器与比较器4.无序查找4.1 判等器4.2 顺序查找4.3 实现4.4 复杂度 5. 插入5.1 算法实现5.2 复杂度分析 6. 删除6.1 区间删除6.2 单元删除6.3 复杂度 7. 唯一化7.1 实现7.2 正确性7.3 复杂度 8. 遍历8.1 实现8.2 复杂度 9. 总结 0.概述 …

vue3引入图片 无法使用require, vue3+vite构建项目使用require引入包出现问题需要用newURL来动态引入图片等静态资源

在vue3中 require引入图片的本地资源报错Uncaught (in promise) ReferenceError: require is not defined <template> <img :src"imageSrc" alt"My Image"> </template> <script> import imageSrc from /assets/image.png; export…

多媒体技术如何为地震体验馆增添更多真实元素?

近年来&#xff0c;为提升公众安全意识&#xff0c;众多体验式科普展馆纷纷崭露头角&#xff0c;其中地震体验馆尤为引人瞩目&#xff0c;成为学校安全教育的热门场景&#xff0c;接下来&#xff0c;我们就深入探索一下&#xff0c;这种运用了多媒体技术的地震体验馆&#xff0…

有哪些好用的电商API接口(京东|天猫|淘宝商品详情数据接口)

此API目前支持以下基本接口&#xff1a; 如何获取此API测试权限&#xff1f; item_get 获得淘宝商品详情item_get_pro 获得淘宝商品详情高级版item_review 获得淘宝商品评论item_fee 获得淘宝商品快递费用item_password 获得淘口令真实urlitem_list_updown 批量获得淘宝商品上…

云计算中的过度授权:安全隐患与应对策略

云计算凭借其弹性、可扩展等优势&#xff0c;已经成为诸多企业组织拓展业务的重要基础设施之一。然而&#xff0c;与传统IT架构相比&#xff0c;云计算环境的安全管理也面临着新的挑战。过度授权 (Overprivileging) 便是云安全领域亟待解决的主要问题之一&#xff0c;本文将带领…

开源模型应用落地-LangChain高阶-知识图谱助力记忆增强

一、前言 通过langchain框架调用本地模型&#xff0c;使得用户可以直接提出问题或发送指令&#xff0c;而无需担心具体的步骤或流程。langchain会自动将任务分解为多个子任务&#xff0c;并将它们传递给适合的语言模型进行处理。 本篇通过使用 ConversationKGMemory 组件&#…

MySQL简解

文章目录 1. MySQL框架2. 执行流程2.1. 连接池&#xff1a;2.2. SQL 前端(SEVER)2.2.0. 查询缓存2.2.1. SQL 接口2.2.2. SQL 解析器2.2.3. SQL 执行器2.2.4. INNODB 中读写操作 2.3. 数据的保存形式 3.其他重要概念3.1. 索引3.1.1. 简单概念3.1.2. 索引优化&#xff1a;1. Usin…

【复现代码——环境配置】

目录 一、复现代码举例二、创建环境——选择一个Python版本2.1 创建基本环境2.1.1 基于AutoDL2.1.2 基于PyCharm 2.2 终端激活环境2.3 退出环境2.4 删除环境 三、PyTorch安装3.1 查看cuda3.2 安装PyTorch 四、其他依赖安装4.1 tensorboardX4.2 matplotlib4.3 medpy4.4 visdom4.…

stable-diffusion-webui安装与使用过程中的遇到的error合集

stable-diffusion-webui1.9.2踩坑安装 1. 安装过程1.1 stable-diffusion-webui1.2 在win11或win10系统安装&#xff0c;需修改两个启动脚本1.2.1 修改webui-user.bat1.2.2 修改webui.bat 1.3 双击 webui-user.bat 启动脚本1.3.1 no module xformers. Processing without on fre…

实体书营销:“三三裂变”,实操细节分享……

实体书营销:“三三裂变”,实操细节分享 一、实验结果 “三三裂变”的实验,结果比较好。就是我们大概有300人报名,但实际行动的只有109人,大概有103人都完成了三个人的目标,也就是说我们通过109人裂变了475人,利润率是1:4.5左右,整个裂变的效率还是可以的,也就是说: …

阿赵UE学习笔记——30、HUD简单介绍

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎&#xff0c;这次来学习一下HUD的基础使用。 一、 什么是HUD HUD(Head-Up Display)&#xff0c;也就是俗称的抬头显示。很多其他领域里面有用到这个术语&#xff0c;比如开车的朋友可能会接触过&#xf…

后端工程师——Java工程师岗位要求

在国内,Java 程序员是后端开发工程师中最大的一部分群体,其市场需求量也是居高不下,C++ 程序员也是热门岗位之一,此二者的比较也常是热点话题,例如新学者常困惑的问题之一 —— 后端开发学 Java 好还是学 C++ 好。读完本文后,我们可以从自身情况、未来的发展,岗位需求量…

适用于手机蓝牙的热敏晶体FA1612AS

EPSON推出的一款1612小尺寸无源热敏晶体:FA1612AS。FA1612AS的额定频率为38.4Mhz的晶体单元&#xff0c;采用无铅材料&#xff0c;符合ROHS标准&#xff0c;内置热敏电阻&#xff0c;可用于移动电话&#xff0c;蓝牙等。热敏晶体FA1612AS的产品特性:额定频率:38.4MHZ外部尺寸规…

上海亚商投顾:沪指缩量调整 有色、煤炭等周期股集体大跌

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日缩量调整&#xff0c;午后一度跌近1%&#xff0c;黄白二线走势分化&#xff0c;微盘股指数涨超3%。军…