【C语言】初阶指针(指针及其类型以及野指针)
简单不先于复杂,而是在复杂之后。
目录
1. 指针是什么?
2. 指针和指针类型
2.1 指针+-整数
2.2 指针的解引用
3. 野指针
3.1 野指针成因
3.2 如何规避野指针
1. 指针是什么?
指针理解的两个要点:
1. 指针是内存中最小单元的编号,也就是地址。
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量。
总结:指针就是地址,口语中说的指针通常是指针变量。
int main() { int a = 10;//a是整型变量,占用4个字节的内存空间 int* pa = &a;//pa是一个指针变量,用来存放地址的 //取地址时取的是第一个字节的地址return 0; }
总结:
指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理。)
- 一个小的内存单元多大?
---1byte
- 如何编址?
经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。
对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是1或者0;
那么32根地址线产生的地址就会是:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
...
11111111 11111111 11111111 11111111
总结:
1. 指针是用来存放地址的,地址是唯一标识一块地址空间的。
2. 指针的大小在32位平台是4个字节,在64位平台是8个字节。
C语言的
%zu
是用来格式化输出size_t
类型数据的格式控制符。size_t是C标准库中定义的一个无符号整型类型,用于表示内存空间大小和数组索引等非负整数值。在C语言中,sizeof操作符用于计算指定类型或表达式的大小(即占用的字节数),并返回一个size_t类型的值。
需要注意的是,
%zu
只能用于格式化输出size_t
类型的值,不能用于其他类型的数据。如果把一个非
size_t
类型的数据使用%zu
格式控制符进行输出,可能会导致输出结果不正确,甚至导致程序崩溃。
2. 指针和指针类型
变量有不同的类型,整型、浮点型等。
指针也有类型。
当有这样的代码:
结论:指针类型决定了指针在被解引用的时候访问几个字节
1. 如果是int*的指针解引用访问4个字节
2. 如果是char*的指针,解引用访问1个字节
在这段代码中,整型指针变量
pa
和字符型指针变量pc
所指向的地址是相同的,即它们都指向变量a
的内存地址。这是因为在C语言中,变量在内存中的存储方式是连续的,而不同类型的指针变量只是指向这些内存地址的方式不同。
在这段代码中,变量
a
在内存中的存储方式是以4个字节为一个单位进行存储,因此它的地址是一个整型地址。当将变量
a
的地址赋给整型指针变量pa
时,pa
所指向的地址与a
的地址是相同的,因为它们都是整型地址。当将变量
a
的地址强制转换为字符型指针类型并赋给字符型指针变量pc
时,pc
所指向的地址也与a
的地址相同,这是因为强制类型转换只改变了指针变量的解释方式,而并没有改变指针变量所指向的地址。因此,虽然整型指针变量和字符型指针变量的类型不同,但它们所指向的地址是相同的。
2.1 指针+-整数
总结:指针的类型决定了指针向前或向后走一步(+1-1操作)有多大,也就是指针的步长。
2.2 指针的解引用
总结:
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:char* 的指针解引用就只能访问一个字节,而int* 的指针解引用就能访问四个字节。
3. 野指针
概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)。
3.1 野指针成因
1. 指针未初始化
int main() { int* p;//没有初始化,就意味着没有明确的指向 //一个局部变量不初始化的话,放的是随机值:0xcccccccc*p = 10;//非法访问内存,这里的p就是野指针return 0; }
2. 指针越界访问
int main() { int arr[10] = { 0 }; int* p = arr;//&arr[0] int i = 0; for (i = 0; i <= 10; i++) { *p = i; p++; } //当指针指向的范围超出数组arr的范围时,p就是野指针 return 0; }
3. 指针指向的空间释放(动态内存开辟时讲解)
int* test() { int a = 10; return *a; } int main() { int*p = test();return 0; }
3.2 如何规避野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放时及时置NULL
- 避免返回局部变量的地址
- 指针使用之前检查有效性
零地址禁止访问,指针没有指向有效空间。
这段代码有一个明显的问题,就是在函数test()中声明的变量a是一个局部变量,在函数执行完毕后将被销毁。
因此,返回该变量的地址是不安全的,因为该地址将指向一块已经被销毁的内存。
这将导致指针变量p所指向的地址变成了一个野指针,可能会引发不可预测的错误,这是一种非常危险的行为。
如果想要正确地使用返回指针,可以考虑使用动态内存分配函数malloc()来分配一块内存,并将变量的值存储在该内存块中,然后返回该内存块的地址。
动态内存分配在之后的博客会有所体现。
这样可以确保返回的地址始终有效,并且可以安全地使用指针变量。
int main() { int a = 0; int* p = &a; *p = 20; //null -> 0int* p2 = NULL; *p2 = 100;//errint* p3 = NULL;if (p3 != NULL) { *p3 = 100;//ok }return 0; }
相关文章:

【C语言】初阶指针(指针及其类型以及野指针)
简单不先于复杂,而是在复杂之后。 目录 1. 指针是什么? 2. 指针和指针类型 2.1 指针-整数 2.2 指针的解引用 3. 野指针 3.1 野指针成因 3.2 如何规避野指针 1. 指针是什么? 指针理解的两个要点: 1. 指针是内存中最小…...

UDS统一诊断服务【六】访问时序参数0X83服务
文章目录前言一、访问时序参数服务介绍二、数据格式2.1 请求报文2.2 子功能2.3 响应三、举例前言 本文介绍UDS统一诊断服务的访问时序参数0X83服务,希望能对你有所帮助 一、访问时序参数服务介绍 这个服务我目前在项目中没怎么用到过,先来看看ISO14229…...

Linux应用编程(文件属性与目录)
本章将会讨论如下主题内容。 ⚫ Linux 系统的文件类型; ⚫ stat 系统调用; ⚫ 文件各种属性介绍:文件属主、访问权限、时间戳; ⚫ 符号链接与硬链接; ⚫ 目录; ⚫ 删除文件与文件重命名。 一、Linux 系统中…...

第十四届蓝桥杯嵌入式详解
目录 第一部分 客观试题(15 分) 不定项选择(1.5 分/题) 第二部分 程序设计试题(85 分) 2.1 STM32CubeMX初始化配置 2.1.1 配置GPIO 2.1.2 配置ADC 2.1.3 配置RCC 2.1.4 配置定时器TIM 2.1.5 配置ADC1、AD…...

新建论文三线表模板,一键格式刷
论文三线表模板写在最前面①表设计,新建表格样式②三线表上下线③三线表标题线④设置表格居中⑤设置表头格式容易出错的步骤写在最前面 论文写完啦,准备调整格式 之前建模也是三线表,但只能基于该文档模板,所以重新设置一下。 如…...

攻防世界-web2(逆向加密算法)
打开链接是PHP源码 给了一串密文,并对这串密文进行了一系列操作加密,注释里说解密$miwen就是flag 在此我们先介绍一些PHP内置函数: strrev(string): 反转字符串 strlen(string): 返回字符串的长度 substr(string, start, length): 返回字符…...

C语言学习1--------Visual Studio集成开发环境的搭建
C语言学习1--------Visual Studio集成开发环境的搭建适合初学者适用集成开发环境下载 Visual Studio 2019安装 Visual Studio 2019安装工作负载为C自定义安装位置激活 Visual Studio适合初学者适用集成开发环境 建议初学者适用最新的——Visual Studio 2019为集成开发环境。 部…...

腾讯云轻量应用服务器搭建网站教程(WordPress为例)
腾讯云轻量应用服务器搭建WordPress网站教程,先安装WordPress应用镜像,然后远程连接轻量应用服务器获取WP用户名和密码,域名DNS解析到轻量服务器IP地址,登陆WordPress后台管理全过程,腾讯云百科来详细说下腾讯云轻量服…...
mac上的PCB设计软件现状
Altium Designer是一款商业化的电路板设计软件,目前没有Mac版本。但是,MacOS上有一些类似Altium Designer的电路板设计软件,以下是一些常用的软件: Eagle:Eagle是一款商业化的电路板设计软件,具有强大的功能…...
【面试题】JavaScript 你常用的 函数有哪些呢? (12个)
大厂面试题分享 面试题库 前后端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 web前端面试题库 VS java后端面试题库大全 本文收集了 12 个在日常开发中非常常用的函数,有些可能很复杂,有些可…...

Java集合——Set接口学习总结
一、HashSet实现类 1.常用方法 增加:add(E e)删除:remove(Object o)、clear()修改:查看:iterator()判断:contains(Object o)、isEmpty()常用遍历方式:Set<String> set new HashSet<String>()…...

2023最全的自动化测试入门基础知识(建议收藏)
1)首先,什么是自动化测试? 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的过程一步步执行测试,得到实际结果与期望结果的比较。…...

【RabbitMQ】SpringBoot整合RabbitMQ、实现RabbitMQ五大工作模式(万字长文)
目录 一、准备 1、创建SpringBoot项目 2、添加配置信息 3、创建配置类 二、RabbitMQ的配置类里创建队列 三、RabbitMQ的配置类里创建交换机及绑定队列 四、SpringBoot整合RabbitMQ入门案例 1、生产者 2、消费者 四、SpringBoot里实现RabbitMQ五大工作模式 1、简单模式…...
ES6(函数扩展、数组扩展)
一、 函数扩展 1. 参数可以默认 ES5调用函数:如果给参数设置默认需要进行判断 ES6可以直接给参数设置默认 //ES5 function log(x, y) {//两种判断方法(传统分支判断、利用逻辑符)if (typeof y undefined) {y World;}//y y || World;cons…...

postman汉化教程
文章目录1. 下载对应版本的postman2.下载对应版本的汉化包2.1. github下载地址 : (9.12.2)2.2 百度网盘(9.12.2)3. 打开postman安装位置4. 压缩包解压到/resources目录下5. 重启postman即可汉化成中文了1. 下载对应版本的postman …...
java day8
第8章 数据结构8.1 超越数组8.2 java数据结构8.2.1 Iterator8.2.2 位组8.2.3 链表8.2.4 遍历数据结构8.2.5 堆栈8.1 超越数组 java类库的java.util包中有一组数据结构,它们让您能够更灵活地组织和操纵数据。 8.2 java数据结构 8.2.1 Iterator 接口Iterator提供了…...

口令暴力破解--Telnet协议暴力破解、数据库暴力破解与远程桌面暴力破解
Telnet协议暴力破解 Telnet Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。要开始一个telnet会话,必须输入用户名和密码来登录服务器。而一般服务器不会对用户名…...

[译]什么是SourceMap
原文链接: https://web.dev/source-maps/使用 SourceMap 来提升 web 调试体验。今天,我们要讨论的是 SourceMap,这是现代 Web 开发中至关重要的工具,它能够显著地简化调试工作。在本文中,我们将探讨 SourceMap 的基础知识…...
saga模式、Seata saga模式详解
文章目录 一、前言二、SAGA模式0、saga论文摘要1、什么是长事务?2、saga的组成3、saga的两种执行场景1)forward recovery2)backward recovery4、saga log5、saga协调(saga实现方式)1)SAGA - Choreography 策略2)SAGA - Orchestration 策略3)如何选择三、Seata saga模式…...
java开发工程师碰到技术难题怎么办?我来聊聊我的做法
最近公司遇到了一个技术难题。这一周基本上都在加班解决这个问题,头发也掉了不少,但问题还没有解决。我写这篇文章,主要是想看看看我文章的同学们是否有类似的经验或者是自己的一些想法。让我们看一下这个问题的一个具体情况。 我们的公司是…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...