深入探究C语言中的常量指针与野指针概念及其应用

目录

常量指针(Constant Pointers)

1. 指向常量的指针

2. 常量指针

以下是一个使用const声明常量的示例:

通过修改被const修饰的a的地址,修改a的值

const位置的不同

 指针的应用

利用指针打印数组的几种方式

野指针(Wild Pointers)的产生

野指针(Wild Pointers)的危害

如何避免

学习指针的目的是使用指针解决问题,那什么问题,非指针不可呢?

模拟实现库函数strlen

应用场景


常量指针(Constant Pointers)

在C语言中,const关键字用于声明常量,而野指针则是一种危险的指针类型。下面将详细解释这两个概念及其应用。

常量指针是指指向常量的指针,它不能用来修改所指向的数据。这有助于保护数据不被意外修改,提高程序的安全性和可维护性。

1. 指向常量的指针

当你想阻止通过指针修改数据时,可以使用指向常量的指针。这种指针的类型是指向常量的指针类型,例如 int * const p;。这意味着你不能通过这个指针来修改它所指向的数据。

2. 常量指针

另一种形式是常量指针,即指针本身的值不能被修改,但可以通过该指针修改其指向的数据。这种指针的类型是指向非常量的常量指针类型,例如 const int *p;。这意味着你不能修改指针 p 所指向的数据的值。

以下是一个使用const声明常量的示例:

#include <stdio.h>int main() 
{const int a = 10;//a具有了常属性(不能被修改了)//a本质上还是变量//在C++中,const修饰的变量就是常量//a = 20; 错误,a修改不了//int arr[a]; 错误  a不算常量值printf("%d\n", a);return 0;
}

在这个示例中,我们声明了一个名为a的整型常量,并将其初始化为10。然后我们使用printf函数输出a的值。注意,我们不能修改a的值,否则编译器会报错。

 

通过修改被const修饰的a的地址,修改a的值

int main()
{const int a = 10;//a = 20;//errorint* p = &a;*p = 0;printf("a = %d\n", a);return 0;
//}

 

 const位置的不同

//const 修饰指针变量的时候,放在*的右边
//const 限制的是指针变量本身,指针变量不能再指向其他变量了
//但是可以通过指针变量,修改指针变量指向的内容int main()
{int a = 10;int b = 20;int* const p = &a;//一但指向a就不能指向b了//p = &b;//error*p = 100;//修改*p却可以printf("a = %d\n", a);return 0;
}//const 修饰指针变量的时候,放在*的左边
//限制的是指针指向的内容,不能修改指针指向的内容
//但是可以修改指针变量本身的值(修改指针变量的指向)int main()
{int a = 10;int b = 20;int const* p = &a;//一但指向a就不能指向b了p = &b;//OK//*p = 100;//errorprintf("a = %d\n", a);return 0;
}//int const* const p = &a
//*两边都加上const 就都改不了了int main()
{int a = 10;int b = 20;int const* const p = &a;//一但指向a就不能指向b了//p = &b;//error//*p = 100;//errorprintf("a = %d\n", a);return 0;
}

 指针的应用

 利用指针打印数组的几种方式

//用指针打印数组int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", *p);p++;}return 0;
}//另一种方法int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", *(p+i));}return 0;
}//利用指针的关系运算打印数组int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;//等于 &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);while (p < arr + sz){printf("%d ", *p);p++;}return 0;
}//指针-指针的前提是,两个指针指向同一个空间int main()
{int arr[10] = { 0 };printf("%zd ", &arr[9] - &arr[0]);//9return 0;
}

 野指针(Wild Pointers)的产生

野指针通常产生于**未初始化的指针指针越界访问以及指向已释放内存的指针**。具体如下:

1. 未初始化的指针:定义指针变量时,如果没有进行初始化,那么该指针的值是随机的,可能指向任意的内存地址。这种情况下,如果尝试通过这个指针去读取或写入数据,可能会导致程序崩溃或其他不可预期的行为。

2. 指针越界访问:当指针超出了它所指向的数据结构(如数组)的边界时,就会发生越界访问。例如,一个指向大小为10的数组的指针,如果尝试访问数组的第12个元素,就会造成越界。

3. 指向已释放内存的指针:当一块内存被释放后,原有的指针如果继续指向这块内存,而没有置空或者重新赋值,这个指针就变成了所谓的“悬挂指针”或“野指针”。

为了避免野指针的产生和影响,应当总是在声明指针时对其进行初始化,并在释放指针指向的内存后立即将指针置为NULL,同时确保指针在其有效作用域内使用。

代码如下:

//未初始化指针,产生的野指针int main()
{int* p;//p是一个局部变量,不初始化的默认存的是随机值*p = 20;//报错 printf("%d \n", p);return 0;
}//数组越界,产生的野指针int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i <= sz; i++){printf("%d ", *p);p++;}return 0;
}//指针指向的空间释放,产生的野指针int test()
{int a = 10;return &a;
}
int main()
{int* p = test();printf("%d \n", *p);return 0;
}

野指针(Wild Pointers)的危害

野指针的危害主要体现在以下几个方面:

1. 触发段错误:当野指针指向一个不可访问的内存地址时,尝试对其进行解引用操作可能会导致段错误,这是因为程序试图访问一个非法的内存区域。

2. 数据损坏:如果野指针指向了一个正在被其他部分的程序使用的内存空间,并且通过这个野指针修改了该内存空间的内容,那么可能会导致数据损坏,甚至程序崩溃。

3. 内存泄漏:在某些情况下,野指针可能导致内存泄漏。例如,如果一个野指针指向了一块已经分配但未被释放的内存,而这块内存又在其他地方被重复分配,就会造成内存泄漏。

4. 调试困难:野指针的存在可能会使得程序的调试变得非常困难,因为它们可能在程序的任何地方引发错误,而且这些错误可能不会立即显现,增加了查找和修复问题的难度。

 如何避免

为了避免野指针带来的危害,可以采取以下措施:

1. 初始化指针:在声明指针变量时,应当对其进行初始化,避免其成为一个野指针。

2. 及时置空:当一个指针不再使用时,或者它所指向的内存空间已经被释放时,应该将其置为NULL,以防止其成为野指针。

3. 谨慎解引用:在使用指针前,应当确保它指向的是一个有效的内存地址,避免对无效地址进行解引用操作。

4. 使用智能指针:在一些支持智能指针的编程语言中,可以使用智能指针来自动管理内存,减少野指针的产生。

        总的来说,野指针是C/C++编程中的一个常见问题,它们可能导致程序不稳定、数据损坏和内存泄漏等严重问题。因此,理解野指针的危害并采取适当的预防措施是非常重要的

 学习指针的目的是使用指针解决问题,那什么问题,非指针不可呢?

 两个数的交换

void swap(int* pa, int* pb)
{int tmp = *pa;*pa = *pb;*pb = tmp;
}int main()
{int a = 10;int b = 20;printf("交换前:%d %d\n", a, b);swap(&a, &b);printf("交换前:%d %d\n", a, b);return 0;
}

 模拟实现库函数strlen

模拟实现库函数strlenint my_stelen(char* str)
{int count = 0;while (*str!='\0'){count++;str++;}return count;
}int main()
{char arr[] = "abcdef";int len = my_stelen(arr);printf("%d ", len);return 0;}

应用场景

  • 常量指针:当你想保护某些数据不被修改时,可以使用常量指针。例如,在函数参数中传递一个指向常量的指针,这样在函数内部就不能修改这个数据。
  • 野指针:避免使用未初始化的指针和已经释放的内存地址的指针,以减少程序出错的风险。确保在使用指针之前进行适当的初始化,并在不再需要时将其置为NULL。

希望对你有帮助~加油各位!!

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

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

相关文章

必应聊天在当前安全搜索设置下不可用

使用Bing必应搜索引擎&#xff0c;想用必应AI聊天功能会提示&#xff1a;必应聊天在当前安全搜索设置下不可用。 当安全搜索设置设置为“严格”时&#xff0c;不支持必应聊天。 那么怎么修改安全搜索设置呢&#xff1f; 点击右上角的菜单图标&#xff0c;在下拉菜单里点击安全…

权威的健康养生与医学基础知识科普学习信息汇总

目录 1 关于健康与食物营养的权威网址1.1 世界卫生组织&#xff08;World Health Organization: WHO&#xff09;1.2 美国国家卫生研究院 (National Institutes of Health: NIH)1.3 澳大利亚政府健康门户 (Healthdirect)1.4 国际食品信息委员会 (International Food Informatio…

存量为王,持牌消金押注MGM获客

来源 | 镭射财经&#xff08;leishecaijing&#xff09; 存量&#xff0c;已成为消费金融公司运营的王道。 行业十年扩张&#xff0c;跑马圈地难以为继&#xff0c;取而代之的则是一场刀刃向内的运营变革。特别是近几年&#xff0c;消金公司不约而同地将目光聚焦到存量盘活&a…

【Midjourney】内容展示风格关键词

1.几何排列(Geometric) "Geometric" 是一个与几何有关的词汇&#xff0c;通常用于描述与形状、结构或空间几何特征相关的事物。这个词可以涉及数学、艺术、工程、计算机图形学等多个领域。 使用该关键词后&#xff0c;图片中的内容会以平面图形拼接的方式展示&#…

Apache Shiro <= 1.2.4反序列化漏洞攻击 CVE-2016-4437 已亲自复现

Apache Shiro < 1.2.4反序列化漏洞攻击 CVE-2016-4437 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 在 1.2.5 之前的 Apache Shiro 中&#xff0c;当未为“记住我”功能配置密钥时&#xff0c;远程攻击者可以通过未指定…

Spring Retry机制详解

介绍 Spring框架提供了Spring Retry能让在项目工程中很方便的使用重试。 使用 1、引入pom <dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>1.3.2</version></depen…

obsidian阅读pdf和文献——与zotero连用

参考&#xff1a; 【基于Obsidian的pdf阅读、标注&#xff0c;构建笔记思维导图&#xff0c;实现笔记标签化、碎片化&#xff0c;便于检索和跳转】 工作流&#xff1a;如何在Obsidian中阅读PDF - Eleven的文章 - 知乎 https://zhuanlan.zhihu.com/p/409627700 操作步骤 基于O…

武忠祥2025高等数学,基础阶段的百度网盘+视频及PDF

考研数学武忠祥基础主要学习以下几个方面的内容&#xff1a; 1.微积分:主要包括极限、连续、导数、积分等概念&#xff0c;以及它们的基本性质和运算方法。 2.线性代数:主要包括向量、向量空间、线性方程组、矩阵、行列式、特征值和特征向量等概念&#xff0c;以及它们的基本…

VASP安装教程

目录 前言 正文 1. 准备好安装包 VASP 5.4.4 2. VASP安装前的准备 Install GNU Compiler 3. VASP安装 提取并修补 修改文件 编译&#xff0c;构建VASP的std、gam和ncl 修改路径 运行vasp 前言 接上一章&#xff0c;今天我们来讲VASP的安装。 正文 1. 准备好安装…

RK3568平台 of 操作函数获取设备树节点

一.of函数概述 Linux内核给我们提供了一系列的函数来获取设备树中的节点或者属性信息&#xff0c;这一系列的函数都有一个统一的前缀 ”of“ &#xff0c; 所以在很多资料里面也被叫做OF函数。 Linux 内核使用device_node 结构体来描述一个节点&#xff0c;此结构体定义在文件…

设计模式三(原型模式)

在开发过程中&#xff0c;创建多个数据相同的对象&#xff0c;每次new都开销比较大&#xff0c;在这里可以使用对象克隆&#xff0c;以先创建的原型对象为模板进行对象的复制。这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当直接创建对象的代价比较…

Python初学者学习记录——python基础综合案例:数据可视化——折线图可视化

一、案例介绍 效果一&#xff1a;2020年印美日新冠累计确诊人数 效果二&#xff1a;全国疫情地图可视化 效果三&#xff1a;动态GDP增长图 数据来源&#xff1a; 本案例数据全部来自《百度疫情实时大数据报告》&#xff0c;及公开的全球各国GDP数据 使用的技术&#xff1a; E…

C++爱好者的科目四易错点总结

科目四易错点总结 在科目四考试中&#xff0c;一部分内容是可以通过刷题快速掌握的&#xff0c;一部分内容缺因易混淆而降低我们的准确率&#xff0c;本文主要对后者进行总结&#xff0c;期待大家补充与指正。 注&#xff1a; 本文不是全部的知识点总结处 本文不是权威机构 本文…

张维迎《博弈与社会》笔记(3)导论:一些经济学的基础知识

这篇的主要内容介绍了经济学的基础知识吧。 经济学、社会学、心理学的区别 经济学与社会学的区别与共同点 经济学一般是从个人的行为出发解释社会现象&#xff08;from micro to macro&#xff09;。社会学的传统方法则是从社会的角度来解释个人的行为&#xff08;from macro…

硕士毕业论文如何体现自己的工作量

一、工作量是什么 工作量就是你在科研过程中做的所有工作量的体现&#xff0c;包括你对背景的调查&#xff0c;对问题的发现&#xff0c;你做的实验&#xff0c;提出的创新点。 notice&#xff1a;任何别人做的实验&#xff0c;提出的模型&#xff0c;都不能算是你的工作量。…

uniapp+vue3+ts --微信小程序tab导航可以上下滚动选中选项组件代码

uniappvue3ts --微信小程序tab导航可以上下滚动选中选项组件代码 废话不多说&#xff0c;直接上代码。 组件代码&#xff1a; <template><view class"scroll-tabs-container"><view class"radiusz bg-white pt-[10rpx] z-[999]" :class&…

文件包含漏洞长度截断

长度截断 文件漏洞的利用方式什么是长度截断通过实操理解00截断对版本要求更高一点&#xff0c;而长度截断则是利用了windows的系统漏洞&#xff0c;就是windows文件名&#xff08;就是文件名后缀之后&#xff09;之后如果有空格&#xff0c;或者是点都会被忽略掉&#xff0c;也…

Oracle报错:ORA-08002: sequence CURRVAL is not yet defined in this session

问题 直接查询序列的当前值&#xff0c;然后报了这个错误。 SELECT HR.EMPLOYEES_SEQ.CURRVAL; ORA-08002: sequence CURRVAL is not yet defined in this session解决 ORA-08002错误是Oracle数据库中的一个常见错误&#xff0c;它表示在当前会话中未定义序列的CURRVAL值。这…

Python tkinter (6) —— Listbox控件

Python的标准Tk GUI工具包的接口 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— Button标签 Python tkinter (3) —— Entry标签 Python tkinter (4) —— Text控件 Python tkinter (5) 选项按钮与复选框 目录…

【并发编程】volatile原理

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程 ⛺️稳重求进&#xff0c;晒太阳 volatile原理实现是内存屏障&#xff0c;Memory Barrier 对volatile变量的写指令后会加入写屏障。对volatile变量的读指令前会加入读屏障 如何…