指针进阶(上)

news2024/11/15 23:46:56

二级指针

       二级指针是用来存放一级指针地址。

如何使用和解引用呢?

#include <stdio.h>

int main()
{
	int a = 5;
	int* p = &a;
	int** p2 = &p;
	**p2 = 10;
	printf("%d\n", a);
	return 0;
}

这里的解引用使用两颗星号的原因是:一个星号找到的是一级指针,再使用一个星号就会找到二级指针。

下面是二级指针的拆分说明:

字符指针

       字符指针是存放字符的地址,如果存放字符串的地址就是首元素的地址。字符指针的类型是char*

指针数组

       指针数组是数组还是指针,我们用语文的角度来分析,好孩子这里的主语是孩子,那么指针数组的主语就是数组,顾名思义就是存放指针的数组
这是指针数组的模样:

int* p[10]

如何解读这个代码:
首先p 和[ ]结合,10说明有是个元素,每个元素的类型是int*.

指针数组存放的是数组的地址,那么数组的地址又是怎么表示的?且看下面讲解:

数组名的本质

       一般情况下,数组名表示的就是首元素的地址,例如int arr[10] = {0};这里&arr[0]和arr 是一样的,我们可以验证一下:

但是也有特殊情况,有两种:

sizeof(arr) //这里的arr表示取出整个数组,sizeof 对整个数组进行 arr 的大小计算,arr在这里就不是首元素的地址。
&arr //这里的arr表示取出整个数组,拿到的是整个数组的地址,但是表示的时候还是使用首元素的地址。

那各位可能就有疑惑了,&arr和arr又有什么区别呢?

大家先来看看下面的代码:

这里的加1操作之后得到的地址又是不一样的,因为arr表示首元素的地址,因此加一操作后就是跳过一个元素,&arr取出的是整个数组,加一操作后跳过的是整个数组,所以它们在进行运算的时候会有所不同。

一维数组传参的本质

       在没有使用指针的时候,一维数组在进行传参时,我们都会去使用数组来接收:

void test(int arr[])  
{
    ...
}

int main()
{
    int arr[10]={0};
    test(arr);    //arr本质就是数组首元素的地址
    return 0;
}

在学习指针后,我们就可以使用指针来接受数组:

void test(int* parr)  
{
    ...
}

int main()
{
    int arr[10]={0};
    test(arr);    
    return 0;
}

有了指针之后,我们也可以通过指针来访问数组:

这里我特意圈出来两个东西是 想说明:parr[i] 和 *(parr+i) 这两个是没有区别的,[ ] 和 * 都能起到解引用的作用。

既然大家对数组名已经有所了解了,那么我们也可以使用指针数组来模拟二维数组:

解释一下代码,每个数组名变成了指针数组的元素,第一个[ ]是表示第几个元素,第二个方括号是这个元素中的第几个数字。
当然也可以这样来解引用:

*( *( p + i ) + j)

这里有一个小练习:

#include <stdio.h>

int main()
{
	char str1[] = "hello world!";
	char str2[] = "hello world!";
	const char* str3 = "hello world!";
	const char* str4 = "hello 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 和 str2 中,“hello world!" 是这两个不同的数组存放的字符串的,因此这一个字符串被拷贝了两份分别放在str1 和 str2 这两个数组里面,即str1 和 str2 所保留的地址是不一样的;在str3 和 str4 这里时,"hello world!“就是作为一个常量,在计算机里相同的常量只会留下一份,这样也可以节省空间,所以str3 和 str4 他们所指向的都是同一个“hello world!”,这样的话,str3 和 str4 他们所保存的地址是一样的。

数组指针

       什么是数组指针,到底是数组,还是指针,我们来类比一下:整型指针是存放整型地址的指针,浮点型指针是存放浮点型的指针,字符指针是存放字符地址的指针…那么数组指针就是存放数组地址的指针,是指向数组的指针变量。
简单说明一下数组指针的样子:

int (*p)[10]

这里为什么要用()将* 和 p 括起来,因为 [ ] 的优先级要高于 * 的,所以要先保证 * 和 p 相结合。

我们来解读一下上面代码的意义:

我们去掉变量名,剩下的int (*) [10] 就是指针的类型。

二维数组的传参本质

       二维数组的数组名也是跟一维数组的数组一样,都是表示首元素的地址,那对于二位数组来说,首元素是什么呢?二维数组的首元素是一行的地址。
在这里插入图片描述

大家来看一下应用吧:

函数指针

       函数指针顾名思义就是指向函数的指针,存放的是函数的地址。

int (*p) (int,int) = Add;

如何解读:

首先我们先来看一下函数名和取地址函数有什么不同:

结果显而易见,&Add和Add没有任何区别。也就是说函数名其实表示的是这个函数的地址。

如何使用,其实很简单,就是更正常的函数传参一样,大家来看看代码吧:

这里解不解引用都没问题的,因为上面我们就知道函数名可以代表函数的地址。

函数指针数组

       函数指针数组是数组,存放的是函数指针。

int ( *p[4] )(int , int) = {Add, Sub, Mul, Del};

如何解读这条代码:

那么这到底有什么作用呢?大家来看看下面的转移表:

转移表

利用函数指针数组实现计算器功能。

#include <stdio.h>

void menu()
{
	printf("****************************************\n");
	printf("*****     1.加法       2.减法      *****\n");
	printf("*****     3.乘法       4.除法      *****\n");
	printf("*****     0.退出              **********\n");
	printf("****************************************\n");
}

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 Del(int x, int y)
{
	return x / y;
}

void Tran(int n)
{
	printf("请输入两个操作数:");
	int x, y;
	scanf("%d %d", &x, &y);
	int (*pf[5])(int, int) = { 0,Add,Sub,Mul,Del };
	int ret = pf[n](x, y);
	printf("%d\n", ret);
}

       利用函数指针数组就是我们的代码变得简洁,如果一个一个去输入的话,代码会显得过于臃肿,在以后设计代码程序时,我们也可以利用一些巧妙的方法来去使我们的代码更加轻便。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python初学者学习记录——python基础综合案例:数据可视化——动态柱状图

一、案例效果 通过pyecharts可以实现数据的动态显示&#xff0c;直观的感受1960~2019年世界各国GDP的变化趋势 二、通过Bar构建基础柱状图 反转x轴和y轴 标签数值在右侧 from pyecharts.charts import Bar from pyecharts.options import LabelOpts# 构建柱状图对象 bar Bar()…

介绍docker

一&#xff1a;介绍docker&#xff1a; Docker 并没有单独的图形界面&#xff0c;它主要通过命令行来进行管理和操作 1、 docker ps&#xff1a;显示正在运行的容器。 docker images&#xff1a;显示本地的镜像。 docker run&#xff1a;创建并启动一个新容器。 docker stop&a…

台灯学生用哪个牌子好?学生用护眼台灯品牌推荐

晚上学习&#xff0c;有台灯肯定比没台灯好。只要是盏合格的、能用的台灯&#xff0c;都能给你一个稳定又亮堂的环境。但是有些不合格的台灯会给眼睛带来伤害&#xff0c;尤其是学习负担比较重的学生。那有哪些台灯是学生用着比较好用的呢&#xff1f; 一、学生使用护眼台灯的…

2-2 动手学深度学习v2-损失函数-笔记

损失函数&#xff0c;用来衡量预测值和真实值之间的区别。是机器学习里面一个非常重要的概念。 三个常用的损失函数 L2 loss、L1 loss、Huber’s Robust loss 均方损失 L2 Loss l ( y , y ′ ) 1 2 ( y − y ′ ) 2 l(y,y^{\prime})\frac{1}{2}(y-y^{\prime})^{2} l(y,y′)21…

Unity3d Shader篇(三)— 片元半兰伯特着色器解析

文章目录 前言一、片元半兰伯特着色器是什么&#xff1f;1. 片元漫反射着色器的工作原理2. 片元半兰伯特着色器的优缺点优点&#xff1a;缺点&#xff1a; 3. 公式 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数…

计算机毕业设计 基于SpringBoot的线上教育培训办公系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

centos7的git使用方法

下载git yum install git git克隆 git clone https...(图片中复制的内容) git提交到远程仓库 git add filename git commit -m "提交日志" git push git首次使用要配置邮箱和用户名 查看提交日志 git log 查看当前提交状态 git status

74HC154D-LED

一、引脚说明 1-11 13-17 &#xff1a;输出端。&#xff08;outputs (active LOW)&#xff09; 12&#xff1a;Gnd电源地 &#xff08;ground (0 V)&#xff09; 18-19&#xff1a;使能输入端、低电平有效 (enable inputs (active LOW)) 20-23&#xff1a;地址输入端 (addr…

ctfshow-web1~10-WP

web1 右键查看源码就能看到flag web2 打开网页提示无法查看源代码,右键也使用不了,那我们就在url前面加上view-source: view-source:http://83a83588-671e-4a94-9c6f-6857f9e20c2f.chall.ctf.show/ 访问后即可获得flag web3 右键源码也没看到信息,去查看一下请求头和响应…

私募证券基金动态-24年1月报

成交量&#xff1a;1月日均7,280.98亿元 2024年1月A股两市日均成交7,280.98亿元&#xff0c;环比下降5.40%、同比下降7.85%。1月整体22个交易日&#xff0c;无单日交易日成交金额过万亿&#xff0c;单日交易日最低成交金额为6,120.22亿元&#xff08;1月15日&#xff09;&…

【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费

作者推荐 【动态规划】【状态压缩】【2次选择】【广度搜索】1494. 并行课程 II 本文涉及知识点 动态规划汇总 LeetCode1928. 规定时间内到达终点的最小花费 一个国家有 n 个城市&#xff0c;城市编号为 0 到 n - 1 &#xff0c;题目保证 所有城市 都由双向道路 连接在一起…

问题:淘宝网禁止出售保护动植物及其制品,以下哪种饰品可不以在淘宝上出售?() #学习方法#其他

问题&#xff1a;淘宝网禁止出售保护动植物及其制品,以下哪种饰品可不以在淘宝上出售&#xff1f;() A&#xff0e;钻石 B&#xff0e;玳瑁饰品 C&#xff0e;象牙饰品 D&#xff0e;犀牛角饰品 参考答案如图所示

vue3(笔记)

组合式Api setup-----相当于beforeCreate, create生命周期 reactive–定义状态 对象形式 响应式原理 toRefs— Pinia &#xff08;只有state、getters和actions&#xff09; 更加简洁的语法&#xff0c;完美支持Vue3的Composition api 和 对TypesCcript的完美支持

Vue3入门到实战笔记05--路由

使用路由需要做的事情&#xff1a; 1.确定好导航区、展示区 2.请来路由器 3. 制定路由的具体规则&#xff08;什么路径、对应着什么组件&#xff09; 4. 形成一个一个的.vue 1、 基本使用步骤 在cmd窗口安装: npm i vue-router在src当中创建一个router文件夹&#xff0c;并在…

docker之程序镜像的制作

目录 一、每种资源的预安装&#xff08;基础&#xff09; 安装 nginx安装 redis 二、dockerfile文件制作&#xff08;基础&#xff09; 打包 redis 镜像 创建镜像制作空间制作dockerfile 打包 nginx 镜像 三、创建组合镜像&#xff08;方式一&#xff09; 生成centos容器并…

苹果证书过期有什么影响

引言 苹果证书是一种数字签名&#xff0c;用于验证应用程序的身份和完整性。然而&#xff0c;若该证书过期&#xff0c;将会对用户和开发者带来一定的影响。在本文中&#xff0c;我们将详细介绍苹果证书过期的原理和影响&#xff0c;并提供一些解决方法。 苹果证书的原理 苹…

CleanMyMacX4.14.6如何清理mac垃圾内存

一直以来&#xff0c;苹果电脑的运行流畅度都很好&#xff0c;但是垃圾内存多了磁盘空间慢慢变少&#xff0c;还是会造成卡顿的。这篇文章就告诉大家电脑如何清理垃圾内存&#xff0c;电脑如何清理磁盘空间。 一、电脑如何清理垃圾内存 垃圾内存指的是各种缓存文件和系统垃圾…

C语言之找单身狗

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a; 我要学编程(ಥ_ಥ)-CSDN博客 题目&#xff1a; 在一个整型数组中&#xff0c;只有一个数字出现一次&#xff0c;其他数组都是成对出现的&#xff0c;请找出那个只出现一次的数字。…

IF=82.9!高分文献解读|吉西他滨联合顺铂化疗激活肿瘤免疫新机制

鼻咽癌&#xff08;nasopharyngeal carcinoma, NPC&#xff09;是一种发生于鼻咽部上皮细胞的恶性肿瘤&#xff0c;且高发于中国。吉西他滨联合顺铂&#xff08;GP&#xff09;化疗作为鼻咽癌的一种全球标准治疗方案&#xff0c;然而治疗的具体机制目前尚不清楚。中山大学肿瘤防…