初阶指针(详解)

news2024/11/27 4:27:50

目录

前言

一   指针是什么

计算机又是如何编址的?

总结

二   指针和指针类型

指针+-整数

总结:

指针的解引用

 总结

三   野指针

概念

 野指针的成因

1. 指针未初始化

 2. 指针越界访问

 3. 指针指向的空间被释放

如何规避野指针

四   指针运算

 指针+-整数

指针-指针

指针的关系运算

总结


前言

前边我们已经简单了解过了指针这一概念,现在我们对指针的初阶使用进行详细讲解,使大家能更好的了解指针。


一   指针是什么

在计算机科学·中,指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值,由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象的称为指针。意思是通过它能找到以它为地址的内存单元。

指针是一个变量,用于存放内存单元的地址(编号)

 代码演示:

#include<stdio.h>
int main()
{
	int a = 8;//创建变量a内存储开配一个整形空间存放a的数据
	int* p = &a;//p是指针变量,int* 是类型名,使用&(取地址符)a把变量a的地址存放到指针变量p中
	return 0;
}

 通过调试我们也可以发现p中存放的数据就是a的地址,*是解引用操作符,那么*p就是取出p中地址对应的数据。

 每个单元都有自己对应的编号,那么问题来了,一个单元是多大的内存?(上文图示中也可以看出每个单元是一个字节的大小

计算机又是如何编址的?

以32位机器为例,假设计算机中存在32根地址线,每根地址线可以发出一个信号(正电/负电),即0和1。

那么就会产生一下可能:

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

                      ……

11111111  11111111  11111111  11111111

总共可以产生2的32次方种个地址(电信号),每个地址标识一个内存单元(1byte),换算下来也就是4GB的空间进行编址。同样在64位机器中也是如此,可以自主计算。

讲到这里我们就明白:

32位机器上,地址是32个0和1组成的二进制序列,那么一个地址就要用到4个字节的空间来存储(1个字节等于8个二进制位),所以一个指针变量在32位机器中大小是4个字节。

那么64位机器中就是64根地址线,由64个0和1组成的二进制序列,那么一个地址就要用到8个字节的空间来存储,所以一个指针变量在64位机器中大小是8个字节。

总结

指针是用来存放地址的,地址是唯一标示一块地址空间的。

指针的大小在32位机器中是4个字节,在64位机器中是8个字节。

二   指针和指针类型

前边我们了解到,变量有自己的类型:整形,浮点型,字符型等,那么指针有没有变量类型呢?准确的来说:有的。

int a=8;
p=&a;

 上述代码,将a的地址取出存放到p中,这里我们知道p是一个指针变量,那他的类型是什么呢?

指针变量的类型可以分为以下几种:

char*  p1=NULL;
int*   p2=NULL;
float* p3=NULL;
long*  p4=NULL;
double* p5=NULL;
short* p6=NULL;

 通过上述代码我们可以看出,指针的定义方式是“type+*”,其实char*类型的指针是为了存放char类型变量的地址。short*类型的指针是为了存放short类型变量的地址。int*类型的指针是为了存放

 int类型变量的地址。

那么指针类型的意义是什么呢?这里大家想必也会更加清楚了。

指针+-整数

int main()
{
	int n = 9;
	char* p1 = (char*)&n;
	int* p2 = &n;

	printf("%p\n", &n);     //0000007731CFF904
	printf("%p\n", p1);     //0000007731CFF904
	printf("%p\n", p1 + 1); //0000007731CFF905  
	printf("%p\n", p2);     //0000007731CFF904
	printf("%p\n", p2 + 1); //0000007731CFF908

	return 0;
}

通过这段码代码我们可以更直观的看到,char*类型的指针加1地址增加了1,而int*类型的指针加1之后地址增加了4。

总结:

指针的类型决定了指针向前或者向后走的距离有多大

指针的解引用

int main()
{
	int n = 0X11223344;
	char* p1 = (char*)&n;
	int* p2 = &n;
	*p1 = 0;
	*p2 = 0;
	return 0;
}

 运行这段代码,通过调试我们观察n在内存中的变化。

 总结

 指针的类型决定了对指针解引用的时候有多大的权限(能操作几个字节)。例如上图:char*的指针解引用就只能访问一个字节,而int*的指针解引用就能访问四个字节。

三   野指针

概念

野指针就是指针指向的位置是未知的(随机的,不确定的,没有明确的)

 野指针的成因

1. 指针未初始化

int main()
{
	int* p;//局部变量指针未初始化,默认为随机值
	*p = 20;
	return 0;
}

 2. 指针越界访问

int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 11; i++)
	{
		//当指针指向的范围超出数组arr的范围时,p就变成了野指针
		*(p++) = i;
	}
	return 0;
}

 3. 指针指向的空间被释放

动态内存开辟后续会讲,这里简单提一下。

如何规避野指针

1. 指针初始化

2. 注意指针越界

3. 指针指向空间释放及时置NULL

4. 指针使用之前检查有效性
 

四   指针运算

 指针+-整数

上文以及做过讲解这里不再进行详讲

int main()
{
	float a[5];
	float* p;
	for (p = &a[0]; p < &a[5];)
	{
		*(p++) = 0;//进行操作时要注意操作符优先级,不确定可以使用括号确定操作顺序
	}

	return 0;
}

 这里进行操作时需要注意操作符的优先级。

指针-指针

int main()
{
	int arr[5] = { 0 };
	printf("%d", &arr[4]-&arr[0]);//输出结果为4
	return 0;
}

 为什么是4呢?

 

 如上图所示,指向arr[0]的指针与指向arr[4]的指针之间有四个元素,它们进行相减得到的就是它们之间相差的元素个数(它们相差的结果存在正负)。

注意:指针-指针的前提是两个指针指向同一块空间。

指针的关系运算

我们知道地址是有大小的

指针的关系运算就是比较指针的大小

int main()
{
	float a[5];
	float* p;
	for (p = &a[5]; p > &a[0];)
	{
		*--p = 0;
	}

	return 0;
}

 这段代码的作用就是将数组中5个元素初始化为0(从后往前)。

那么这样简化代码可以吗?

for (p = &a[4]; p >= &a[0]; p--)
	{
		*p = 0;
	}

 这段代码会使p指向arr[0]前边的空间。

 这段简化后的代码在大多数的编译器上都是可以顺利进行的,但是我们应该避免这样写,因为标准并不保证它可行。

标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但不允许与指向第一个元素之前的那个内存位置的指针进行比较。


总结

好了,本期指针初阶内容到此结束,下期会对指针的内容进行部分扩展补充,感谢阅读!

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

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

相关文章

iMazing2.16.9中文最新版iOS设备管理器下载教程

iMazing2.16.9是一款兼容Win和Mac的iOS设备管理软件。iMazing能够将音乐、文件、消息和应用等数据从任何 iPhone、iPad 或 iPod 传输到 Mac 或 PC 上。iMazing轻松管理和备份您的 iOS 设备,无需使用 iTunes&#xff0c;iMazing以自己的方式管理 iPhone。让备受信赖的软件为您传…

遗传算法(附简单案例及matlab详细代码)

作者&#xff1a;非妃是公主 专栏&#xff1a;《智能优化算法》 博客地址&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 专栏推荐序一、生物进化二、遗传算法原…

华为OD机试真题 Java 实现【按身高和体重排队】【2022Q4 100分】,附详细解题思路

一、题目描述 某学校举行运动会&#xff0c;学生们按编号(1、2、3…n)进行标识&#xff0c;现需要按照身高由低到高排列&#xff0c;对身高相同的人&#xff0c;按体重由轻到重排列&#xff1b; 对于身高体重都相同的人&#xff0c;维持原有的编号顺序关系。请输出排列后的学生…

全闪SDS三节点EC(4+2:1)性能挑战测试

前段时间咱们存储圈在讨论一下全闪SDS性能挑战&#xff1a; 三节点集群&#xff0c;用EC&#xff08;42:1&#xff09;&#xff0c;性能目标是&#xff1a;4KB随机读写7:3&#xff0c;达到100万IOPS&#xff0c;平均时延0.5ms&#xff0c;P99时延1ms。硬件配置&#xff1a;网络…

菜鸟的刷题之路之二叉树

&#x1f495;“成功不是终点&#xff0c;失败不是终结&#xff0c;勇气才是启程的第一步。”&#x1f495; &#x1f43c;作者&#xff1a;不能再留遗憾了&#x1f43c; &#x1f386;专栏&#xff1a;菜鸟的刷题之路&#x1f386; &#x1f697;本文章主要内容&#xff1a;将…

GORM---创建

目录 模型定义使用Create创建记录一次性创建多条数据批量插入数据时开启事务默认值问题 模型定义 定义一个PersonInfo结构体。 type PersonInfo struct {Id uint64 gorm:"column:id;primary_key;NOT NULL" json:"id"UserName string gorm:"co…

路径规划算法:基于狮群优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于狮群优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于狮群优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法狮群…

Prometheus+Grafana(外)监控Kubernetes(K8s)集群(基于containerd)

一、实验环境 1、k8s环境 版本v1.26.5 二进制安装Kubernetes(K8s)集群(基于containerd)—从零安装教程&#xff08;带证书&#xff09; 主机名IP系统版本安装服务master0110.10.10.21rhel7.5nginx、etcd、api-server、scheduler、controller-manager、kubelet、proxymaster021…

在 Ubuntu 20.04 上安装 Nginx

保证以 sudo 用户身份登录&#xff0c;并且你不能运行 Apache 或者 其他处理进程在80端口和443端口。 安装 Nginx Nginx 在默认的 Ubuntu 源仓库中可用。想要安装它&#xff0c;运行下面的命令&#xff1a; sudo apt update sudo apt install nginx 一旦安装完成&#xff0…

Redis高级数据结构之Bitmaps

Bitmaps的介绍 现代计算机使用二进制位作为信息存储的基本单元。一个字节&#xff08;Byte&#xff09;等于8个二进制位&#xff08;bit&#xff09;。合理的使用位能有效提高内存使用率和开发效率。位是最小信息单位&#xff0c;可以表示两个状态之一。字节是更大的单位&…

虚拟机搭建

Linux(CentOS-7.6-x64位)基础配置, 虚拟机平台VmWare15 CentOS-7.6-x64镜像下载&#xff1a; https://www.aliyundrive.com/s/72Xg449t6i8 提取码: 32rm VmVare15安装包下载带序列号&#xff1a;VmVare15安装包下载带激活序列号资源-CSDN文库 点击关闭&#xff0c;点击完成&…

深入理解Jar文件:创建、使用和多版本控制

&#x1f9d1;‍&#x1f4bb;CSDN主页&#xff1a;夏志121的主页 &#x1f4cb;专栏地址&#xff1a;Java基础进阶核心技术专栏 目录 &#x1f35b; 一、创建JAR文件 &#x1f35c; 二、安装和使用清单文件 &#x1f35d; 三、创建可执行的JAR文件 &#x1f360; 四、多版…

微信小程序开发实战 ②②(全局数据共享)

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; 微信小程序 &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f4…

网络安全大厂面试题合集+

以下为网络安全各个方向涉及的面试题&#xff0c;星数越多代表问题出现的几率越大&#xff0c;祝各位都能找到满意的工作。 注&#xff1a;本套面试题&#xff0c;已整理成pdf文档&#xff0c;但内容还在持续更新中&#xff0c;因为无论如何都不可能覆盖所有的面试问题&#xf…

近年GDC服务器分享合集(三): 《Sky光·遇》实现百万在线:一种云原生的扩容方法

如今&#xff0c;游戏行业对于云原生技术的使用越来越广泛。特别是那些拥有海量玩家在线的游戏&#xff0c;使用云原生技术可以轻松做到高可用、弹性扩容和降低成本。在GDC 2022上&#xff0c;来自《Sky光遇》项目的工程师分享了相关的经验——《《Sky光遇》实现百万在线&#…

黑马Redis视频教程高级篇(一:分布式缓存)

目录 分布式缓存 一、Redis持久化 1.1、RDB持久化 1.1.1、执行时机 1.1.2、RDB原理 1.1.3、小结 1.2、OF持久化 1.2.1、AOF原理 1.2.2、OF配置 1.2.3、AOF文件重写 1.3、RDB与AOF对比 二、Redis主从 2.1、搭建主从架构 2.1.1、集群结构 2.1.2、准备实例和配置 …

基于springboot汽车站车辆运管系统java+vue

本汽车站车辆运管系统管理员可以管理个人中心&#xff0c;业务管理&#xff0c;站务管理&#xff0c;人力资源管理&#xff0c;办公司管理&#xff0c;财务管理。因而具有一定的实用性。本站是一个B/S模式系统&#xff0c;采用springboot框架&#xff0c;MYSQL数据库设计开发&a…

模型的细分和简化

​ 细分 本质为引入更多三角形 loop细分 对于新的顶点如何计算&#xff1a;下图中白点位置计算 对于旧的顶点位置计算 Catmull-Clark细分 对于非四边形的图形细分方法&#xff1a;不断将非四边形进行细分即可 下图中橙色&#xff1a;非四边形面的重心坐标&#xff1b;紫色&…

程序员必须了解的消息队列之王-Kafka

1. Kafka概述 1.1 定义 Kafka 是由 Apache 软件基金会开发的一个开源流处理平台。 Kafka 是一个分布式的基于发布/订阅模式的消息队列&#xff08;Message Queue&#xff09;&#xff0c;主要应用于大数据实时处理领域。 1.2 消息队列 1.2.1 传统消息队列的应用场景 1.2.2 为什…

路径规划算法:基于共生生物优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于共生生物优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于共生生物优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…