【C语言】指针详解(三)

1.指针运算

指针的基本运算有三种,分别是:
指针+-整数
⭐指针-指针
⭐指针的关系运算

1.1指针 + - 整数

因为数组在内存中是连续存放的,只要知道第一个元素的地址,顺藤摸瓜就能找到后面的所有元素。

int arr[10]={1,2,3,4,5,6,7,8,9,10}

 

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int *p = &arr[0];
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for(i=0;i<sz;i++)
	{
		printf("%d ", *(p + i));//p+i就是指针+整数
	}
	return 0;
}

运行结果如下:

1.2指针-指针

指针-指针得到的是两个指针中间的元素个数。

需要注意的是两个相减的指针必须是指向同一块连续空间的。

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];
	int* q = &arr[9];
	printf("%d", q - p);
	return 0;
}

指针q指向arr数组的第10个元素,指针p指向arr数组的第一个元素,为同一块连续空间,所以q-p得到的是两个指针中间的元素个数9

注意这种用法是错误的,如果我们使用两个指针相减,但是它们两个不指向同一片连续空间,如下:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];
	int* q = &arr[9];
	char* r = 'w';
	printf("%d", q - r);
	return 0;
}

 指针q指向arr数组的第10个元素,指针r指向字符w,不为同一块连续空间,所以q-r得到的值是无意义的,每次运行结果都不尽相同,我们无法估计会得到一个怎样的值。

第一次运行结果:

第二次运行结果:

2.野指针

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

 2.1野指针成因

野指针的成因多种多样,在这里我们列举几种常见的野指针成因:

2.1.1.指针未初始化

int main()
{
	int* p;//指针未初始化
	*p = 20;
	return 0;
}

上述代码就犯了一个严重的错误,即使用了未初始化的指针,此时指针p指向一片我们为止的空间,我们进行了指针操作使得指针p修改了所指向地址的四个字节的数据,这有可能造成严重的后果,在写代码时我们一定要避免使用未初始化的指针。

2.1.2指针越界访问

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];
	int i = 0;
	for(i=0;i<=10;i++)
	{
		*p = 0;
		p++;
		//arr数组中只有十个变量,循环有十一次,当我们进行到第十一次时已经越界访问了,此时的指针p为野指针
	}
}

 arr数组中只有十个变量,循环有十一次,当我们进行到第十一次时已经越界访问了,此时的指针p为野指针

2.1.3指针指向的空间被释放

int *test()
{
	int n = 100;
	return &n;
}

int main()
{
	int* p = test();
	printf("%d", *p);
	return 0;
}

 上述代码看似好像没问题,实际上已经出现了野指针的问题,变量n定义在函数test中,所以它是一个局部变量,我们知道局部变量会在函数调用结束时被销毁即结束生命周期,此时我们想要打印的*p其实已经被销毁了,此时的指针p指向一个被释放的空间所以指针p是野指针。

2.2如何规避野指针

2.2.1指针初始化

如果明确知道指针指向哪里就直接赋值地址,如果不知道指针应该指向哪里,可以给指针赋值NULL,NULL是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的,读写该地址会报错。

初始化如下:

int main()
{
	int n = 100;
	int* p = &n;	//1.如果知道指针指向哪里就赋值地址
	int* q = NULL;	//2.不知道指针指向哪里就让它指向NULL
}

2.2.2小心指针越界

一个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是越界访问。

2.2.3指针变量不再使用时,及时置NULL,指针使用之前检查有效性

当指针变量指向一块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的一个规则就是:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL。


我们可以把野指针想象成野狗,野狗放任不管是非常危险的,所以我们可以找一棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。


不过野狗即使拴起来我们也要绕着走,不能去挑逗野狗,有点危险;对于指针也是,在使用之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直接使用,如果不是我们再去使用。

 

2.2.4避免返回局部变量的地址

如造成野指针的第3个例子,不要返回局部变量的地址。

 以上便是我为大家带来的指针详解(三)的内容,若有不足,望各位大佬在评论区指出,谢谢大家!可以留下你们点赞、收藏和关注,这是对我极大的鼓励,我也会更加努力创作更优质的作品。再次感谢大家!  

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

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

相关文章

Python to_numeric函数参数解读与最佳实践!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python中的to_numeric函数是pandas库提供的一个强大而灵活的工具&#xff0c;用于将数据转换为数字类型。本文将深入探讨to_numeric函数的各种参数和用法&#xff0c;通过丰富的示例代码帮助大家更全面地理解和运…

Web自动化测试工具的优势分析

Web自动化测试工具在现代软件开发中扮演着关键的角色&#xff0c;帮助团队确保Web应用程序的质量和稳定性。然而&#xff0c;选择合适的Web自动化测试工具对项目的成功至关重要。本文将介绍Web自动化测试工具优势是什么! 1. 自动化执行 Web自动化测试工具能够模拟用户的行为&am…

算法通关村-番外篇排序算法

大家好我是苏麟 , 今天带来番外篇 . 冒泡排序 BubbleSort 最基本的排序算法&#xff0c;最常用的排序算法 . 我们以关键字序列{26,53,48,11,13,48,32,15}看一下排序过程: 代码如下 : (基础版) class Solution {public int[] sortArray(int[] nums) {for(int i 0;i < n…

接口测试学习笔记

文章目录 认识urlhttp协议接口规范Postman实现接口测试设计接口测试用例使用软件发送请求并查看响应结果Postman 自动关联Postman如何提交multipart/form-data请求数据Postman如何提交查询参数Postman 如何批量执行用例单接口测试Postman 断言Postman参数化 接口测试自动化requ…

【笔记】Spring是什么

什么是spring&#xff1f; Spring的基础知识铺垫 IOC AOP<-Spring->容器->生态 先说你的认知&#xff0c;总-分结构 spring是一个基础的框架&#xff0c;同时提供了Bean的容器&#xff0c;用来方便装载具体的Bean对象&#xff0c;之前在使用对象的时候必须自己new&…

C语言操作符详解+运算符优先级表格

目录 前言 一、操作符是什么&#xff1f; 二、操作符的分类 三、算术操作符 四、逻辑操作符 五、比较操作符 六、位操作符 七、赋值操作符 八、其他操作符 九、运算符优先级表格 总结 前言 在编写程序时&#xff0c;最常用到的就是操作符&#xff0c;本文将详细的介绍…

STM32的以太网外设+PHY(LAN8720)使用详解(7):以太网数据接收及发送测试

0 工具准备 1.野火 stm32f407霸天虎开发板 2.LAN8720数据手册 3.STM32F4xx中文参考手册 4.Wireshark1 以太网数据接收测试 1.1 以太网数据接收测试&#xff08;轮询&#xff09; 我们在主循环内轮询RX DMA描述符标志位查看是否接收到了数据&#xff0c;如果接收到了则将数据…

在nodejs中使用讯飞星火大模型3.0的demo

需求&#xff1a; 在nodejs引入讯飞星火大模型的api接口, 思路 看了一下官方文档 api连接为一个WebSocket Secure&#xff08;WSS&#xff09;连接&#xff0c;具体思路如下&#xff1a; 引入 crypto 和 ws 模块&#xff0c;分别用于生成加密签名和创建 WebSocket 连接。&am…

27. 过滤器

Filter(过滤器)简介 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截&#xff0c;从而在 Servlet 进行响应处理的前后实现一些特殊的功能。在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序&#xff1a;Filter, FilterChain, FilterConfigFi…

PHP笔记

文章目录 PHP一、什么是PHP二、PHP集成环境的安装三、WampServer四、PHP基础PHP标准格式php注释变量的定义传值替换变量的作用域变量的检测与删除static静态变量进制转换响应头字符串边界定位符字符串函数常量的定义三元表达式 五、基础文件引入点函数参数类型约束以及严格模式…

OpenAI 官方 Prompt 工程指南:写好 Prompt 的六个策略

其实一直有很多人问我&#xff0c;Prompt 要怎么写效果才好&#xff0c;有没有模板。 我每次都会说&#xff0c;能清晰的表达你的想法&#xff0c;才是最重要的&#xff0c;各种技巧都是其次。但是&#xff0c;我还是希望发给他们一些靠谱的文档。 但是&#xff0c;网上各种所…

Postman接口测试之Post、Get请求方法

一、基础知识 1.HTTP的五种请求方法&#xff1a;GET&#xff0c; POST &#xff0c;HEAD&#xff0c;OPTIONS&#xff0c; PUT&#xff0c; DELETE&#xff0c; TRACE 和 CONNECT 方法。 GET请求&#xff1a;请求指定的页面信息&#xff0c;并返回实体主体。&#xff08;通常用…

“用户名不在 sudoers文件中,此事将被报告” 解决方法

原因 当普通用户需要安装文件时&#xff0c;无法用yum install ** -y直接安装时&#xff0c;采用sudo yum install **; 但是发现提示“用户名不在 sudoers文件中&#xff0c;此事将被报告” 解决方法。 这是因为该普通用户不在sudoers文件中&#xff0c;所以要找到该文件&am…

SpringIOC之BeanFactoryResolver

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

2024年软件测试工程师如何从功能测试转成自动化测试?

前言 接触了太多测试同行&#xff0c;由于多数同行之前一直做手工测试&#xff0c;现在很迫切希望做[<u>自动化测试</u>](javascript:;)&#xff0c;其中不乏工作5年以上的同行。 从事软件自动化测试已经近十年&#xff0c;接触过底层服务端、API 、Web、APP、H5…

Ethercat 读从站状态报文分析

涉及的从站寄存器&#xff1a;Register AL Status 0x0130:0x0131 。 1&#xff0c;发送报文 1&#xff09;IgH dmesg看到的报文 [18773.590655] geshifei ec_master_send_datagrams 1059: Adding datagram datagram->index0 [18773.590656] EtherCAT DEBUG 0: frame siz…

机器学习---推荐系统案例(二)

四、推荐系统---模型训练 1、模型训练代码 模型训练代码参照scala文件&#xff1a;Recommonder.scala 1.Logger.getLogger("org.apache.spark").setLevel(Level.ERROR) 2.val conf new SparkConf().setAppName("recommonder").setMaster("local[*…

《成才》期刊投稿方式发表要求

《成才》杂志是国家新闻出版总署批准&#xff0c;面向国内外公开发行的教育期刊&#xff0c;以“大教育视野、新理念成才”为办刊宗旨&#xff0c;全面贯彻党的教育方针&#xff0c;理论联系实际&#xff0c;开展教育科学研究和人才培养研究&#xff0c;交流科技成果&#xff0…

TrustZone之示例用例——加密文件系统

移动设备如智能手机包含大量个人数据。如果设备丢失或被盗&#xff0c;用户会关心这些数据的机密性。这就是为什么大多数最新的设备支持文件系统加密的原因。TrustZone 可以作为保护这些数据的解决方案的一部分。 存储在外部闪存中的数据是加密的。在启动时&#xff0c;设备对用…

React学习计划-React16--React基础(二)组件与组件的3大核心属性state、props、ref和事件处理

1. 组件 函数式组件&#xff08;适用于【简单组件】的定义&#xff09; 示例&#xff1a; 执行了ReactDOM.render(<MyComponent/>, ...)之后执行了什么&#xff1f; React解析组件标签&#xff0c;找到了MyComponent组件发现组件是使用函数定义的&#xff0c;随后调用该…