指针的深入了解2

news2024/11/19 15:32:27

1.const修饰指针

在这之前我们还学过static修饰变量,那我们用const来修饰一下变量会有什么样的效果呢?
我们来看看:

我们可以看到编译器报错告诉我们a变成了一个不可修改的值,我们在变量前加上了const进行限制,但是我们就不能改变a的值了吗?其实不然,我们刚刚学过指针,我们试试用指针能不能将其修改。

演示如下:

int main()
{
	const int a = 10;
	int* pt = &a;
	*pt = 2;
	printf("%d", a);
	return 0;
}

 我们来运行一下看看是不是改变了a的值。结果为:

虽然我们利用指针这个知识绕过a变量进行赋值的操作成功赋值 ,但是我们用const修饰变量就是让其固定,不想被修改,那我们可以怎样让指针也不能修改我们的a的值,其实我们也可以用const修饰指针这样就不能更改变量了。

演示如下:

此时我们用const修饰指针变量pt使其也成为一个不可修改的值,这样就不能通过指针变量来修改a了。但是const有几种修饰指针的情况,第一种就是上述的情况虽然我们限制*pt的值,但是我们可以改变pt的值,例如:

 此时就没有报错,说明此时的pt并没有被限制,被限制的知识*pt。还有一种情况我们将const放在int 后如int const*pt,此时限制的也是*pt那我们怎么限制pt呢?

其实我们只需要在pt的前面加上const即可。

演示如下:

此时编译器再次报错。说明我们成功将pt的值进行了限制,如果我们想让*pt和pt都被限制只需要使用 两个const即可。例如const int *const pt即可。

 2.指针的运算

1.指针的加减
1.指针加,我们来看一串代码
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10, };
	size_t sz = sizeof(arr) / sizeof(arr[0]);
	int* pt = &arr[0];
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *(pt + i));
	}
	return 0;
}

上述代码我们用指针的来完成打印数组的每一个元素。能不能完成我们的任务呢?

 我们通过指针的加i,每次都跳过一个整型。达到找到arr的每一个元素。

2.指针的减,我们也来看一串代码:
int main()
{
	int arr[] = { 1,2,3,4 };
	//我们将它的数子倒着打印出来
	int* pt = &arr[0];
	pt = pt + 3;
	for (int i = 0; i < 4; i++)
	{
		printf("%d ", *(pt - i));
	}
	return 0;
}

我们利用指针的减i来找到元素的地址,并进行解引用操作。

2.指针减指针

我们之前学过strlen库函数我们今天来写一个自己的strlen函数:

演示如下:

int my_strlen( char *pt)
{
	char* pu = pt;
	while (*pt!='\0')
	{
		pt++;
	}
	return pt - pu;
}
int main()
{
	char arr[] = "abcdef";
	int ret=my_strlen(arr);
	printf("%d", ret);
	return 0;
}

其实一维数组的传参就是首元素的地址。

我们来运行一下能不能完成我们的任务:

 3.野指针

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

1.野指针成因
1.未初始化
#include <stdio.h>
int main()
{
int *p; //局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
2.指针越界访问
#include <stdio.h>
int main()
{
 int arr[10] = {0};
 int *p = &arr[0];
 int i = 0;
 for(i=0; i<=11; i++)
{
 //当指针指向的范围超出数组arr的范围时,p就是野指针
 *(p++) = i;
}
 return 0;
}
3. 指针指向的空间释放
#include <stdio.h>
int* test()
{
int n = 100;
return &n;
}
int main()
{
int*p = test();
printf("%d\n", *p);
return 0;
}
2.如何避免野指针
1.指针初始化

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

2. 小心指针越界

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

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

当指针变量指向一块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的一个规则就是:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL。
我们可以把野指针想象成野狗,野狗放任不管是非常危险的,所以我们可以找一棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。
不过野狗即使拴起来我们也要绕着走,不能去挑逗野狗,有点危险;对于指针也是,在使用之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直接使用,如果不是我们再去使用。

谢谢

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

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

相关文章

【Linux】第三十九站:可重入函数、volatile、SIGCHLD信号

文章目录 一、可重入函数二、volatile三、SIGCHLD信号 一、可重入函数 如下图所示&#xff0c;当我们进行链表的头插的时候&#xff0c;我们刚刚执行完第一条语句的时候&#xff0c;突然收到一个信号&#xff0c;然后我们这个信号的自定义捕捉方法中&#xff0c;正好还有一个头…

内网安全:Exchange服务

目录 Exchange服务 实验环境 域横向移动-内网服务-Exchange探针 一. 端口扫描 二. SPN扫描 三. 脚本探针(还可以探针是否有安全漏洞) 域横向移动-内网服务-Exchange爆破 一 .BurpSuite Intruder模块爆破 域横向移动-内网服务-Exchange漏洞 CVE-2020-17144 Exchange R…

【JaveWeb教程】(38)SpringBootWeb案例之《智能学习辅助系统》的详细实现步骤与代码示例(11)过滤器Filter讲解

目录 SpringBootWeb案例10 过滤器Filter2.4 过滤器Filter2.4.1 快速入门2.4.2 Filter详解2.4.2.1 执行流程2.4.2.2 拦截路径2.4.2.3 过滤器链 2.4.3 登录校验-Filter2.4.3.1 分析2.4.3.2 具体流程2.4.3.3 代码实现 SpringBootWeb案例10 过滤器Filter 2.4 过滤器Filter 刚才通…

uniapp组件库Card 卡片 的使用方法

目录 #平台差异说明 #基本使用 #配置卡片间距 #配置卡片左上角的缩略图 #配置卡片边框 #设置内边距 #API #Props #Slot #Event 卡片组件一般用于多个列表条目&#xff0c;且风格统一的场景。 #平台差异说明 AppH5微信小程序支付宝小程序百度小程序头条小程序QQ小程…

UE5在VisualStudio升级后产生C++无法编译的问题

往期的虚幻引擎项目在VS更新后&#xff0c;编译时会报错&#xff0c;这一般出现在VS升级之后&#xff0c;UE对于VC的编译器定位没有更新导致&#xff1b; 有出现如下问题&#xff1a; 问题1&#xff1a; Running I:/EPCI/Epic Games/UE_5.3/Engine/Build/BatchFiles/Build.ba…

研发日记,Matlab/Simulink避坑指南(九)——可变数组应用Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结归纳 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南(四)——transpose()转置函数Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(五)——CAN解包 DLC Bug》 见《研发日记&#xff0c;Matlab/Si…

(bean的创建图)学习Spring的第十天(很重要)

大致框架按如下 第一次细分 bean对象还未创建 操作第一个map 引入BeanFactoryPostProcessor , 即Bean工厂后处理器 , 为Spring很重要的扩展点 BeanFactoryPostProcessor内部的方法 可以对BeaDefinition进行修改 , 也可进行BeanDefinition的注册 ( 原有在xml文件配置的bean…

vue常用指令(v-mode)

一、v-mode 指令 作用: 获取和设置表单元素的值(实现双向数据绑定) 双向数据绑定 单向绑定: 就是把Model绑定到View&#xff0c;当我们用JavaScript代码更新Model时&#xff0c;View就会自动更新。双向绑定: 用户更新了View&#xff0c;Model的数据也自动被更新了&#xff0c;…

Windows提权:第三方应用

目录 向日葵漏洞提权 Teamviewer提权 电脑(服务器)装的第三方应用越多&#xff0c;安全隐患越大 向日葵漏洞提权 已经拿到了webshell权限&#xff0c;这里的权限是普通用户的权限&#xff0c;查看服务进程 tasklist /svc 发现对方主机上存在向日葵的进程 将其上线CS上&am…

项目部署上线过程

写在前面 你应该去喜欢那些&#xff0c;让你觉得自己很美好&#xff0c;由衷感受到幸福的人&#xff0c;而不是那些让你卑微到尘埃里&#xff0c;让你觉得自己很没用的人。 …

第四十一周:文献阅读+GAN存在的问题和改进

目录 摘要 Abstract 文献阅读&#xff1a;基于Transformer的时间序列生成对抗网络 现有问题 提出方法 相关前提 GAN&#xff08;生成对抗网络&#xff09; Transformer 方法论 时间序列处理 TTS-GAN &#xff08;基于Transformer的时间序列生成对抗网络&#xff09;…

【网络基础】网络协议传输层UDP和TCP

UDP 解包和分用 解包&#xff08;解析数据包&#xff09; 捕获数据包&#xff1a;首先&#xff0c;接收端的网络栈捕获UDP数据包。检查目的端口&#xff1a;接收端检查数据包头部的目的端口&#xff0c;以确定哪个应用程序应该接收该数据包。验证校验和&#xff1a;接收端可能…

day33_js

今日内容 0 复习昨日 1 JS概述 2 JS的引入方式 3 JS语法 3.1 变量 3.2 基本数据类型 3.3 引用类型 3.4 数组类型 3.5 日期类型 3.6 运算符(算术运算,逻辑,关系运算,三目运算) 3.7 分支 3.8 循环 3.9 函数(重点) 3 常见弹窗函数 alter,confirm,prompt 0 复习昨日 1 盒子模型 对d…

Kafka(九)跨集群数据镜像

目录 1 跨集群镜像的应用场景1.1 区域集群和中心集群1.2 高可用(HA)和灾备(DR)1.3 监管与合规1.4 云迁移1.5 聚合边缘集群的数据 2 多集群架构2.1 星型架构2.2 双活架构2.2 主备架构2.2.1 如何实现Kafka集群的故障转移2.2.1.1 故障转移包括的内容1. 灾难恢复计划2. 非计划内的故…

【C初阶——基本语法】return关键字

博客简介&#xff1a;本系列博客是C初阶基本语法系列&#xff0c;主要围绕主题对其语法特性进行详谈。 适宜人群&#xff1a;C初学者&#xff0c;可用于C完善补充 作者留言&#xff1a;本博客相关内容如需转载请注明出处&#xff0c;本人学疏才浅&#xff0c;难免存在些许错误&…

前言:穿越迷雾,探索C语言指针的奇幻之旅

各位少年&#xff0c;大家好&#xff0c;我是博主那一脸阳光&#xff0c;今天给大家分享指针&#xff0c;内存和地址的使用&#xff0c;以及使用。 前言&#xff1a; 在编程的世界中&#xff0c;若论灵活多变、深邃神秘的角色&#xff0c;非“指针”莫属。如同哈利波特手中的魔…

netty源码:(59) AbstractNioMessageChannel之read方法

当有客户端连接时&#xff0c;NioEventLoop中的processSelectedKey方法会被调用&#xff0c;这个方法会调用AbstracNioMessageChannel的read方法&#xff0c; 其中调用了doReadMessages方法&#xff0c;它的代码&#xff08;NioServerSocketChannel中&#xff09;如下&#xf…

IDEA 构建开发环境

本博客主要讲解了如何创建一个Maven构建Java项目。&#xff08;本文是创建一个用Maven构建项目的方式&#xff0c;所以需要对Maven有一定的了解&#xff09; IDEA 构建开发环境 一、创建一个空工程二、构建一个普通的Maven模块 一、创建一个空工程 创建一个空的工程 * 设置整…

分布式空间索引了解与扩展

目录 一、空间索引快速理解 &#xff08;一&#xff09;区域编码 &#xff08;二&#xff09;区域编码检索 &#xff08;三&#xff09;Geohash 编码 &#xff08;四&#xff09;RTree及其变体 二、业内方案选取 三、分布式空间索引架构 &#xff08;一&#xff09;PG数…

数字图像处理(实践篇)三十三 OpenCV-Python从立体图像创建深度图实践

目录 一 方案 二 实践 双眼视觉是指人类使用两只眼睛同时观察同一场景,通过左右眼的视差来感知深度。左眼和右眼的视差是由于它们在空间中的位置不同而产生的,这种差异可以被大脑解读为物体的距离和深度。为了从立体图像构建深度图,找到两个图像之间的视差,可以初始化并创…