玩转指针(3)

一、字符指针变量

字符指针变量(如char* p)的两种赋值方式

①将字符类型地址赋值给字符指针变量
int main()
{char a = 'w';char* p = &a;*p = 'm';return 0;
}
②将常量字符串赋值给字符指针变量
常量字符串的介绍:用" "引起来的就是常量字符串,常量字符串存放在只读数据区,这块区域的内容是可以用的,但是不能被修改的。在这里插入图片描述
一道关于字符指针变量的面试题

在这里插入图片描述
在这里插入图片描述

二、数组指针变量

①何为数组指针变量

字符指针变量(如char * p),p中存放的是字符变量的地址,p指向的是字符;整型指针变量(如int * p),p中存放的是整型变量的地址,p指向的是整型。同理,数组指针变量存放的是数组的地址(&数组名),它指向的是数组。

在这里插入图片描述

小练习:正确书写数组指针变量

在这里插入图片描述

②数组指针变量的使用

在这里插入图片描述

但这种写法不常见,通常不会这么写

③区分指针数组与数组指针

三、二维数组传参的本质

①二维数组的数组名

二维数组的每一行可以看做是一个一维数组,即二维数组是由一维数组组成的数组。二维数组的首元素就是它的第一行,因此二维数组的数组名就是数组第一行的地址。

②二维数组中的元素在内存中是连续存放的

在这里插入图片描述

③二维数组传参

二维数组传参时,实参写数组名,形参既可以写成数组的形式(此时二维数组的行的大小可以省略),也可以写成指针的形式。
a、形参写成指针的形式

在这里插入图片描述

b、形参写成数组的形式

在这里插入图片描述

c、补充
arr[i]==*(arr+i)
arr[i][j]==* (*(arr+i)+j) 。

四、函数指针变量

①函数地址的介绍:

数组有地址,变量(如int a)也有地址,那么函数有地址吗?答案是有的。函数的地址是存放在函数指针变量中的。&(函数名)与函数名均表示函数的地址,两者没有区别。 这点与数组不同:&(数组名)表示取出整个数组的地址,数组名表示数组首元素的地址。

在这里插入图片描述

② 函数指针变量的创建

函数指针变量是用来存放函数的地址
int Add(int x, int y)
{return x + y;
}int main()
{int(*pa)(int, int) = Add;//或者写成int(*pa)(int x,int y)=Add;//*表示pa是指针变量(函数指针变量),存放的是函数Add的地址。pa指向的函数的返回类型为int,函数的两个参数也是int类型//pa的类型是int(*)(int, int)//*pa表示通过pa中Add的地址,调用Add函数int ret1 = (*pa)(3, 5);printf("%d\n", ret1);//8//一般调用Add函数的方式int ret2 = Add(3, 5);//这里的Add是函数名,也就是函数的地址。pa中存放的也是函数的地址,故可以将这里的Add换成paret2 = pa(3, 5);return 0;
}
总结:可以通过函数名(函数的地址)来调用函数,也可以通过对函数指针变量解引用来调用函数。

五、typedef关键字

①作用

用于对变量类型(如int、int*)重新命名,将复杂类型的名字简单化。
//比如觉得unsigned int这个类型比较复杂,那么就可以使用typedef将该类型重命名为unit 
typedef unsigned int unit;
int main()
{unsigned int a = 1;//等价于unit a=1;return 0;
}

②typedef关键字的使用

typedef int* ptr_t;
int main()
{ptr_t a;//等价于int* a;return 0;
}

③typedef在重命名数组指针类型和函数指针类型时,稍微有点不同

a.typedef在重命名数组指针类型
typedef int(*parr)[5];//将数组指针类型int(*)[5]重命名为parr
//typedef int(*)[5]  parr    这种写法是错误的
int main()
{int arr[5] = { 0 };int(*p)[5] = &arr;//数组指针p的类型是int(*)[5]parr m = &arr;return 0;
}
b.typedef重命名函数指针类型
typedef int (*pf)(int, int);//将函数指针类型int (*)(int, int)重命名为pf
//typedef int (*)(int, int)  pf   这种写法是错误的int Add(int x, int y)
{return x + y;
}
int main()
{int (*p)(int, int) = Add;//p是函数指针变量,它的类型是int (*)(int, int)pf p2 = Add;return 0;
}

六、函数指针数组

①函数指针数组是用来存放函数指针或者函数的地址。(函数指针也是用来存放函数的地址,但函数指针只能存放一个函数的地址,而函数指针数组可以存放多个相同类型函数的地址)

②函数指针数组该怎么写呢?

先写出函数指针变量,然后对函数指针变量进行使当的修改,就是函数指针数组。
int Add(int x, int y)
{return x + y;
}int Sub(int x, int y)
{return x - y;
}int Mul(int x, int y)
{return x * y;
}int Div(int x, int y)
{return x / y;
}
int main()
{int(*p)(int, int) = Add;//p是函数指针变量,p所指向的函数的返回类型是int,函数的两个参数的类型也是intint(* p1[4])(int, int) = { Add,Sub,Mul,Div };//p1是函数指针数组的数组名,数组有4个元素,每个元素的类型都是int(*)(int,int)return 0;
}

③函数指针数组的使用

int Add(int x, int y)
{return x + y;
}int Sub(int x, int y)
{return x - y;
}int Mul(int x, int y)
{return x * y;
}int Div(int x, int y)
{return x / y;
}int main()
{int(*p1)(int, int) = Add;int(*p2)(int, int) = Sub;int(*p3)(int, int) = Mul;int(*p4)(int, int) = Div;//p1、p2、p3、p4是四个函数指针变量,分别存放四个函数的地址,比较麻烦。//观察到这四个函数的类型是一样的,因此可以使用函数指针数组来存放四个函数的地址int(*p[4])(int, int) = {Add,Sub,Mul,Div};//p是函数指针数组的数组名,数组有4个元素,每个元素都是int(*)(int,int)类型//p[0]=Add,p[1]=Sub,p[2]=Mul,p[3]=Divfor (int i = 0; i < 4; i++){printf("%d\n", p[i](6, 3));}return 0;
}

七、转移表

/*设计一个简单的计算器,实现整数的加减乘除*/
int Add(int x, int y)
{return x + y;
}int Sub(int x, int y)
{return x - y;
}int Mul(int x, int y)
{return x * y;
}int Div(int x, int y)
{return x / y;
}
void menu()
{printf("*****    1.Add   2.Sub   *****\n");printf("*****    3.Mul   4.Div   *****\n");printf("*****    0.exit          *****\n");
}
int main()
{int input = 0;int x = 0, y = 0, ret = 0;do{menu();printf("请选择:");scanf("%d", &input);int(*p[5])(int, int) = { 0,Add,Sub,Mul,Div }; //转移表if (input >= 1 && input <= 4){printf("请输入两个操作数:");scanf("%d %d", &x, &y);ret = p[input](x, y);printf("%d\n", ret);}else if (input == 0){printf("退出计算器\n");}else{printf("输入错误,请重新输入\n");}} while (input);return 0;
}

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

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

相关文章

以Flask为基础的虾皮Shopee“曲线滑块验证码”识别系统部署

以Flask为基础的虾皮Shopee“曲线滑块验证码”识别系统部署 一、验证码类型二、简介三、Flask应用 一、验证码类型 验证码类型&#xff1a;此类验证码存在两个难点&#xff0c;一是有右侧有两个凹槽&#xff0c;二是滑块的运动轨迹不是直线的&#xff0c;而是沿着曲线走的&…

STM32通过HAL库编码方式,在烧写一次程序后,单片机在仿真器上识别不到

在将项目从裸机移植到rtt过程中&#xff0c;总体调试跑不通ADC&#xff0c;进行了单独调试&#xff0c;新程序烧写进单片机后&#xff0c;仿真器再也识别不到单片机。一遍遍检查后发现HAL库没有配置完全。 SYS需要设置成 Serial Wire&#xff0c;忘记设置就成了No Debug,写这么…

基于nodejs+vue的水产品销售管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

如何在 macOS(MacBook Pro、Air 和 iMac)上恢复未保存的 Word 文档

Microsoft Word 在许多用户中很受欢迎&#xff0c;并且有多种用途。无论是为学校写论文、在办公室写报告还是其他许多事情。但是不保存文档并丢失数据可能是您可能面临的最可怕的噩梦。但是&#xff0c;也有几种方法可以在 macOS 上恢复未保存的 Word 文档。 用户在 Windows P…

wpf中如何访问控件和生成使用事件?

实际上对于初次使用wpf的同学来说&#xff0c;尤其是有winform编程经验的童鞋来说&#xff0c;最需要解决的就是快速掌握访问控件的方法以及生成和使用事件。这样才能让页面具有最起码的交互性。下面我们来分别讲述。 文章原出处&#xff1a;https://blog.csdn.net/haigear/ar…

网络原理(4)——网络层(IP)、数据链路层

1. IP 协议 基本概念&#xff1a; 主机&#xff1a;配有 IP 地址&#xff0c;但是不进行路由控制的设备 路由器&#xff1a;即配有 IP 地址&#xff0c;又能进行路由控制 节点&#xff1a;主机和路由器的统称 IP 协议报头格式 1) 4 位版本&#xff1a;实际上只有两个取值&…

C语言题目之单身狗2

文章目录 一、题目二、思路三、代码实现 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、题目 二、思路 第一步 在c语言题目之打印单身狗我们已经讲解了在一组数据中出现一个单身狗的情况&#xff0c;而本道题是出现两个单身狗的情况。根据一个数…

9.C++程序中的选择语句

选择语句一共分为两种&#xff1a;条件语句和开关语句 其中条件语句叫if语句&#xff0c;常见的形式为&#xff1a;if ... else ... ; 再复杂一些为if... else if ... else ... ; 开关语句又叫switch语句&#xff0c;类型于开关的使用形式常见的有 switch (var) case : ... b…

tauri中加载本地文件图片或者下载网络文件图片后存储到本地,然后通过前端页面展示

有一个需求是需要将本地上传的文件或者网络下载的文件存储到本地&#xff0c;并展示在前端页面上的。其实如果只是加载本地文件&#xff0c;然后展示还是挺简单的&#xff0c;可以看我的文章&#xff1a;tauri程序加载本地图片或者文件在前端页面展示-CSDN博客 要想实现上述需…

JS 历史简介

目录 1. JS 历史简介 2. JS 技术特征 1. JS 历史简介 举例&#xff1a;在提交用户的注册信息的时候&#xff0c;为避免注册出现错误后重新填写信息&#xff0c;可以在写完一栏信息后进行校验&#xff0c;并提示是否出现错误&#xff0c;这样会大大提高用户提交的成功率&…

gradle镜像配置

当我们在Android Studio中新建项目或者打开已有项目时&#xff0c;会下载gradle文件&#xff0c;当使用官方的下载源时很慢&#xff0c;经常会下载失败&#xff0c;国内我们可以使用腾讯或者阿里的镜像&#xff0c;一般下载速度很快。 一、gradle下载地址 官网地址&#xff1…

C语言指针系列2——加深理解

大家&#xff0c;今天讲的知识点是一块儿一块儿的&#xff0c;所以大家要好好学习喔~ 话不多说&#xff0c;开始正题 关键字&#xff1a;const &#xff08;三种用法&#xff09; 1. int* const p; 2. int const* p; 3. const int* const p; 首先我们要了解一下const&#xff…

【计算机组成原理】实验一:运算器输入锁存器数据写实验

目录 实验要求 实验目的 主要集成电路芯片及其逻辑功能 实验原理 实验内容及步骤 实验内容 思考题 实验要求 利用CP226实验箱上的K16&#xff5e;K23二进制拨动开关作为DBUS数据输入端&#xff0c;其它开关作为控制信号的输入端&#xff0c;将通过K16&#xff5e;K23设定…

【学习笔记】SSL/TLS证书安全机制之证书透明

1、概念 CT - Certificate Transparency&#xff0c;证书透明 2、Trying to Solve 如果意外的 CA 为我们的域名颁发证书&#xff0c;我们是不可见&#xff0c;这就是证书透明&#xff08;CT&#xff09;要解决的问题 3、How CT Works 任何CA机构颁发的所有证书的公共登记处&…

西门子1200PLC模拟量指令读出来的值好像不太对劲的样子

问题&#xff1a;模拟量指令读出来的值好像不太对劲的样子 各位高手看看&#xff0c;是不是哪里错了&#xff0c;传感器4-20ma的规格&#xff0c;我取值0-27648&#xff0c;我要换算成N,后面范围是0-200&#xff0c;但是值为什么都是小数点啊&#xff0c;而且和实际的压力怎么看…

使用宝塔部署项目在win上

项目部署 注意&#xff1a; 前后端部署项目&#xff0c;需要两个域名&#xff08;二级域名&#xff0c;就是主域名结尾的域名&#xff0c;需要在主域名下添加就可以了&#xff09;&#xff0c;前端一个&#xff0c;后端一个 思路&#xff1a;访问域名就会浏览器会加载前端的代…

VMware虚拟机Centos操作系统——配置docker,运行本地打包的镜像,进入conda环境(vmware,docker新手小白)

1.docker-centos运行sudo yum install -y yum-utils报错 遇到问题 解决&#xff1a; 进入/etc/yum.repos.d目录下找到 CentOS-Base.repo&#xff0c;执行下面两个命令&#xff1a; cp CentOS-Base.repo CentOS-Base.repo.backupvi CentOS-Base.repo 进入后改成&#x…

恶意Bot流量识别分析实践

1、摘要 随着互联网的发展&#xff0c;自动化工具和脚本&#xff08;Bots&#xff09;的使用越来越普遍。虽然一些善意 Bots 对于网站的正常运行和数据采集至关重要&#xff0c;但恶意 Bots 可能会对网站带来负面影响&#xff0c;如爬取敏感信息、恶意注册、刷流量等。因此&am…

11. Map和Set

一、二叉搜索树 1. 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根…

基于JAVA+SpringBoot+Vue的健身房管理系统1

基于JAVASpringBootVue的健身房管理系统1 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈喽…