第十一讲:指针(3)

第十一讲:指针(3)

  • 1.字符指针变量
    • 1.1存储一个字符
    • 1.2存储一个字符串
    • 1.3一个有趣的面试题
  • 2.数组指针变量
    • 2.1什么是数组指针变量
    • 2.2数组指针变量的初始化
  • 3.二维数组传参的本质
  • 4.函数指针变量
    • 4.1介绍函数指针变量
    • 4.2 两段有趣的代码
      • 4.2.1代码1
      • 4.2.2代码2
    • 4.3typedef关键字
  • 5.函数指针数组
  • 6.转移表
    • 6.1一般写法
    • 6.2函数指针数组写法

1.字符指针变量

1.1存储一个字符

我们当然可以使用指针来存放一个字符变量,使用方法如下:
在这里插入图片描述

1.2存储一个字符串

那么如果我们用指针存放字符串会发生什么呢?

结论:
1.指针存放字符串时存放的时一个字符串首元素的地址
2.直接使用指针存放字符串时,这个字符串被称为常量字符串,此时字符串的值不能被改变


int main()
{char* pa = "abcdef";   //此时abcdef就是一个常量字符串//pa中存储的是首元素a的地址,证明如下:printf("%c\n", *pa);  //此时打印出的是a//*pa = 'c';  如果想要改变pa的值,程序会崩溃,但是并不会报错//所以我们不如将上面的代码表示如下const char* pb = "abcd";//*pb = 0;   此时如果再想改变pb的值,程序就会报错return 0;
}

1.3一个有趣的面试题

在这里插入图片描述
这个面试题的结果为:
在这里插入图片描述
原因如下:
str3和str4指向的是同一个常量字符串,常量字符串会存储再内存中的常量区,它的地址是确定的,而使用str1和str2初始化数组时,就会开辟不同的内存块

2.数组指针变量

2.1什么是数组指针变量

类比于
整形指针变量(int * pa),存放的时整形变量的地址,能够指向整形数据
浮点型指针变量(float * pb),存放的是浮点型变量的地址,指向浮点型数据
那么数组指针变量应该是:
存放的是数组的地址,能够指向数组的指针变量

指针变量的表示方法如下:
在这里插入图片描述
pa先和*进行结合,说明pa是一个指针变量,指向的是一个大小为5的数组。所以pa是一个指针,指向一个数组,称为数组指针

2.2数组指针变量的初始化

在这里插入图片描述
如果要存放个数组的地址,就得存放在数组指针变量中
数组指针解析:
在这里插入图片描述

3.二维数组传参的本质

结论:
二维数组传参,传入的是二维数组中首个一维数组的地址

我们用代码和图像来进一步理解二维数组传参的本质:


//二维数组传参的本质 (打印二维数组的每一个元素)
Print(int(*pa) [3], int r, int c)  //二维数组传参的本质是传入了首个一维数组的地址,而首个一维数组的类型是int [3],
{                                   //所以接受的指针类型是int (*)[3]的类型for (int i = 0; i < r; i++){for (int j = 0; j < c; j++){printf("%d ", (*(pa + i))[j]); //这里的(*(pa + i))[j]相当于*(*(pa+i)+j)相当于pa[i][j]}printf("\n");}
}int main()
{int arr[2][3] = { {1,2,3}, {2,3,4} };Print(arr, 2, 3);return 0;
}

在这里插入图片描述
在这里插入图片描述
当然,二维数组进行传参时,也可以用二维数组来接受:

Print(int arr[2][3], int r, int c)

4.函数指针变量

4.1介绍函数指针变量

类比于数组指针变量(用来存放数组的地址),函数指针变量是用来存放函数的地址的,对于函数的地址的理解:
在这里插入图片描述
我们可以看出来,函数名其实就是函数的地址,Add == &Add,为了将函数的地址存下来,就要使用函数指针变量,使用方法如下:


//函数指针的使用
int Add(int x, int y)
{return x + y;
}int main()
{int a = 2;int b = 3;//(int x, int y)中x和y写不写都可以int (*Pa)(int, int) = Add; //将Add函数的地址存储在函数指针变量中,Add和&Add等价printf("%d\n", Pa(a, b));  //在使用时,pa(a,b)和(*pa)(a,b)等价return 0;
}

函数指针类型解析:
在这里插入图片描述

4.2 两段有趣的代码

4.2.1代码1

(*(void (*)())0)();

对于上述代码的解释如下:
在这里插入图片描述

4.2.2代码2

void (*signal(int , void(*)(int)))(int);

在这里插入图片描述

4.3typedef关键字

typedef是用来类型重命名的,可以将复杂的类型简单化,具体使用方法如下:


//typedef关键字
typedef unsigned int uint;    //1.使用关键字定义普通类型的名称
typedef int* pa;              //2.使用关键字定义指针类型的名称
typedef int(*ppa)[4];         //3.使用关键字定义数组指针的名称
typedef int(*pppa)(int, int); //4.使用关键字定义函数指针变量名称int Add(int x, int y)
{return x + y;
}int main()
{uint a = 3;  //关键字的使用printf("%d\n", a);pa p_a = &a;*p_a = 4;printf("%d\n", a);int arr[4] = { 1,2,3,4 };ppa p_arr = &arr;for (int i = 0; i < 4; i++){printf("%d ", *((*p_arr) + i));}printf("\n");pppa p_add = Add;int ret = p_add(2, 3);printf("%d", ret);return 0;
}

那么此时我们就可以简化代码2,将其转换成:

void (*signal(int , void(*)(int)))(int);typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);

5.函数指针数组

函数指针数组是存放函数指针的数组,那么函数指针数组如何使用呢?


//函数指针数组的使用
int Add(int x, int y)
{return x + y;
}int main()
{int (*pa[3])(int, int) = { Add };int ret = pa[0](2, 3);printf("%d", ret);return 0;
}

6.转移表

函数指针的用途:转移表
举例:计算器的一般实现

6.1一般写法


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:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \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;
}

显然,这个方法比较啰嗦,不好用

6.2函数指针数组写法


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 (*pa[5])(int, int) = { 0, add, sub, mul, div };do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);if (input >= 1 && input <= 5){printf("请输入两个操作数:");scanf("%d %d", &x, &y);int ret = pa[input](x, y);printf("%d\n", ret);}else if (input == 0){printf("退出程序!");break;}elseprintf("输入的值非法,重新输入:");} while (input);return 0;
}

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

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

相关文章

内容安全(AV)

防病毒网关&#xff08;AV&#xff09;简介 基于网络侧 识别 病毒文件&#xff0c;工作范围2~7层。这里的网关指的是内网和外网之间的一个关口&#xff0c;在此进行病毒的查杀。在深信服中就有一个EDR设备&#xff0c;该设备就是有两种部署&#xff0c;一个部署在网关&#xf…

Java----数组的定义和使用

1.数组的定义 在Java中&#xff0c;数组是一种相同数据类型的集合。数组在内存中是一段连续的空间。 2.数组的创建和初始化 2.1数组的创建 在Java中&#xff0c;数组创建的形式与C语言又所不同。 Java中数组创建的形式 T[] 数组名 new T[N]; 1.T表示数组存放的数据类型…

FPGA学习笔记(1)——Vivado和HLS

1 Vivado设计 1.1 FPGA基本知识 Xilinx Atrix-7使用6输入LUT结构&#xff08;0-63&#xff09;CLB&#xff1a;可配置逻辑块Slice&#xff1a;每个CLB包含2个Slice(包含查找表LUT和8位寄存器REG)布线池&#xff1a;围绕在CLB周围&#xff0c;衔接FPGA的资源调度I/O块&#xf…

vivado Spartan-7 配置存储器器件

下表所示闪存器件支持通过 Vivado 软件对 Spartan -7 器件执行擦除、空白检查、编程和验证等配置操作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列非易失性存储器 进行擦除、空白检查、编程和验证。赛灵…

带EXCEL附件邮件发送相关代码

1.查看生成的邮件 2.1 非面向对象的方式&#xff08;demo直接copy即可&#xff09; ​ REPORT Z12. DATA: IT_DOCUMENT_DATA TYPE SODOCCHGI1,IT_CONTENT_TEXT TYPE STANDARD TABLE OF SOLISTI1 WITH HEADER LINE,IT_PACKING_LIST TYPE TABLE OF SOPCKLSTI1 WITH HEADER LIN…

在做题中学习(57):寻找数组的中心下标

724. 寻找数组的中心下标 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;前缀和后缀和 思路&#xff1a;要看一个数是不是中心下标&#xff0c;就看他前面数的和 与 后面数的和 相不相等。 1.i前面数的和&#xff0c;是[0,i-1] 的前缀和&#xff0c;i后面数的和&am…

快递物流查询:如何实现快递批量查询?这些技巧助你轻松应对

在日常生活和工作中&#xff0c;我们经常需要查询快递物流信息&#xff0c;尤其是当面对大量的快递包裹时&#xff0c;逐一查询无疑会耗费大量的时间和精力。这时&#xff0c;实现快递批量查询就显得尤为重要。本文将为你介绍办公提效工具一些实现快递批量查询的技巧&#xff0…

国内有哪些知名的网络安全厂商?

首先就是360&#xff0c;这个我相信大家并不陌生了吧&#xff0c;你的电脑装过360么&#xff1f; 360在个人终端服务那是妥妥的扛把子&#xff0c;但是在企业服务里虽然有他们的身影却略显不足。 第二个就是深信服&#xff0c;网络安全的老牌大佬&#xff0c;业务覆盖了全球5…

【数据分析】 JupyterNotebook安装及使用简介

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 在数据分析中&#xff0c;一般用Pycharm编辑代…

18 分页:介绍

目录 简单例子 页表存在哪里 列表中究竟有什么 分页&#xff1a;也很慢 内存追踪 小结 在解决大多数空间管理问题上面&#xff0c;操作系统有两种方法&#xff1a; 第一种就是将空间分割成不同长度的分片&#xff0c;类似于虚拟内存管理中的分段&#xff0c;但是这个方法…

MySQL45讲(一)(40)

回顾binlog_formatstatement STATEMENT 记录SQL语句。日志文件小&#xff0c;节约IO&#xff0c;但是对一些系统函数不能准确复制或不能复制&#xff0c;如now()、uuid()等 在RR隔离级别下&#xff0c;binlog_formatstatement 如果执行insert select from 这条语句是对于一张…

win10禁止自动更新的终极方法

添加注册表值 1.运行&#xff0c;输入regedit 2.打开注册表编辑器依次进入以下路径“计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings”。 3.在Settings项中&#xff0c;新建DWORD&#xff08;32位&#xff09;值(D)&#xff0c;重命名为以下命名“Fl…

vuex核心概念-getters

除了state之外&#xff0c;有时我们还需要从state中派生出一些状态&#xff0c;这些状态是依赖state的&#xff0c;此时会用到getters。

2023版brupsuite专业破解安装

安装教程&#xff0c;分两部分&#xff1a; 1、安装java环境、参考链接JAVA安装配置----最详细的教程&#xff08;测试木头人&#xff09;_java安装教程详细-CSDN博客 2、安装2023.4版本brupsuite&#xff1a;参考链接 2023最新版—Brup_Suite安装配置----最详细的教程&…

实体同城商家短视频获客,3天直播课,玩转实体商家私域,引爆门店增长

课程内容&#xff1a; 实体同城3天直播课【资料】 实体商家获客第一天 .mp4 实体商家获客第二天上.mp4 实体商家获客第二天,mp4 实体商家获客第三天.mp4 实体商家获客第4天.mp4 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x…

数据结构----二叉树

博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1. 树型结构 1.1 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上…

对Windows超融合S2D的一些补充

先说一个不知道算不算BUG的例子&#xff0c;下面这个存储池是用两台服务器各2块10G建立的&#xff0c;除去系统保留的部分&#xff0c;显示还有13G可用。 但如果使用其新建虚拟磁盘会显示可用的空间为0 然后我又各增加了一块10G硬盘进池&#xff0c;变成了可用空间为30.5GB …

如何理解VMware中的网络模式(NAT、桥接、仅主机)

目录 Ⅰ.NAT模式 Ⅱ.仅主机模式 Ⅲ.桥接模式 Ⅰ.NAT模式 NAT模式&#xff1a;将物理机的网卡作为虚拟交换机的上线链路&#xff0c;将vmware的私有网络转成可以上网的地址进行网络访问&#xff0c;因此在NAT模式下虚拟机是可以访问外部网络的&#xff08;图一&#xff09; …

springboot整合redis多数据源(附带RedisUtil)

单数据源RedisUtil(静态) 单数据源RedisUtil,我这里implements ApplicationContextAware在setApplicationContext注入redisTemplate,工具类可以直接类RedisUtil.StringOps.get()使用 package com.vehicle.manager.core.util;import com.alibaba.fastjson.JSON; import lombok.e…

uni-segmented-control插件使用

dcloud插件市场 前端/uniapp 1.HBuildX打开目标项目 2.进入dcloud插件市场下载目标插件 3.看到如下提示(已经可以在目标项目中使用插件啦) 4.项目正式使用