在上一篇我分享了的内容及理解在这里我们会搞懂空指针到底是怎么回事。在学C语言时看到自己写得程序终于通过了编译感到无比兴奋。但是一运行就被一个接一个的segmentation fault搞蒙了。估计这是所有接触过C语言的人的共同遭遇。究其原因无非是你还没有搞懂指针和空指针。那么空指针是什么呢一句话空指针Null Pointer就是不指向任何有效内存地址的指针。因此我觉得当初把Null Pointer翻译成无效指针会更好一点起码不会引起初学者的误解。把一个城市当作内存的话空指针不是指那些没有人住房子而是专门用来指那些在城市里不存在的房子当然那些烂尾楼也可以当作空指针。但是它又是一个常量作为NULL被定义在各种头文件里。比如stddef.h stdio.h stdlib.h string.h time.h wchar.h#define NULL ((void*)0) //这个常量的定义会随着编译器的不同而不同 //现在为了保持C和C的兼容也有的定义为下面的形式 // C compatible: #define NULL 0 // C incompatible: #define NULL (10*2 - 20) #define NULL ((void*)0) // since C23 (compatible with C11 and later) #define NULL nullptr换个说法任何有效的指针都不能成为空指针。其实它和C语言中其他类型的常量没有本质的区别比如整数有常量:016进制有常量:0x00char型有常量:\0。因为指针也有类型所以当把空指针变换成void*char*int* 时就会生成相对类型的空指针。例8:#include int main(void) { void *p 0x0; // 右边为空指针的常量p为空指针 int *q 0x0; // 0x0为整数的常量是否为空指针在(1)(8)(9)可以确认 int n 0; /* A */ printf((A) p [%p]\n, p); // %p的输出会会依存于系统 if(p NULL) // (1) NULL 空指针常量 // printf(OK, integer constant expression 0x0 is a null pointer constant in your computer.\n); else printf(* WARNING\n * Integer constant expression 0x0 may not be with \the value 0\ in your computer.\n * Or, NULL may be incompatible with ISO:C11.\n); /* B */ p (void *)0; // (2) 右边为看指针常量p空指针 // (void *)0 是否为空指针常量通过(3)确认 printf((B) p [%p]\n, p); if(p NULL) // (3) printf(OK, (void *)0 is a null pointer constant in your computer.\n); else printf(* WARNING\n * Integer constant expression 0 may not be with \the value 0\ in your computer.\n * Or, NULL may be incompatible with ISO:C11.\n); /* C */ printf((C) p [%p]\n q [%p]\n, p, q); if(q (int *)p) // (4) printf(OK, any two null pointers shall compare equal [C11 \u00A76.3.2.3, 4; \u00A76.5.9, 6].\n); else printf(* WARNING\n * Either integer constant expression 0x0 or 0 may not be with \the value 0\ in your computer.\n); /* D */ q n; // (5) 右边既不是空指针常量也不是空指针 // 所以q不是空指针 printf((D) q [%p]\n, q); if(q ! NULL) // (6) printf(OK, q is not a null pointer.\n); else printf(* WARNING\n * NULL may be broken.\n); /* E */ p 0x0; // (7) printf((E) p [%p]\n q [%p]\n, p, q); if(q ! p) // (8) printf(OK, q is not a null pointer.\n); else printf(* WARNING\n * Integer constant expression 0x0 may not be with \the value 0\ in your computer.\n); /* F */ printf((F) q [%p]\n, q); if(q ! 0x0) // (9) printf(OK, q is not a null pointer.\n); else printf(* WARNING\n * Integer constant expression 0x0 may not be with \the value 0\ in your computer.\n); return 0; } //执行结果如下 /* (A) p [0x0] OK, integer constant expression 0x0 is a null pointer constant in your computer. (B) p [0x0] OK, (void *)0 is a null pointer constant in your computer. (C) p [0x0] q [0x0] OK, any two null pointers shall compare equal [C11 xc2xa76.3.2.3, 4; xc2xa76.5.9, 6]. (D) q [0x16fdfeb54] OK, q is not a null pointer. (E) p [0x0] q [0x16fdfeb54] OK, q is not a null pointer. (F) q [0x16fdfeb54] OK, q is not a null pointer. */既然空指针是无效指针那么专门定义一个空指针又有什么用呢以简洁为宗旨的C语言当然不会做无用之功。在C语言中空指针的作用基本如下1、初始化尚未被赋予任何有效内存地址的指针变量。例9:#include int main() { //声明一个空指针 int* ptr NULL; // if (ptr NULL) { printf(Pointer does not point to anything); } else { printf(Value pointed by pointer: %d, *ptr); } return 0; }2、用于在访问任何指针变量之前检查其是否为空指针。这样我们可以在与指针相关的代码中进行错误处理例如仅当指针变量不为空时才对其进行解引用。例10:#include #include int main() { //分配一段动态内存 int* ptr (int*)malloc(5 * sizeof(int)); //判断是否分配成功 if (!ptr) { printf(Memory Allocation Failed); exit(0); } free(ptr); return 0; }3、用于在不希望传递任何有效内存地址时将空指针传递给函数参数。例11:#include void foo(int* string) { if (string NULL) { printf(NULL Pointer Passed); return; } printf(Non-Null Pointer Passed); } // int main() { foo(NULL); return 0; }4、空指针用于树、链表等数据结构中表示结束位置。例12:#include #include /* 定义链表节点 */ struct Node { int value; struct Node *next; // 指向下一个节点 }; int main(void) { /* 手动创建三个节点 */ struct Node *n1 malloc(sizeof(struct Node)); struct Node *n2 malloc(sizeof(struct Node)); struct Node *n3 malloc(sizeof(struct Node)); n1-value 1; n2-value 2; n3-value 3; /* 串成一个链表 */ n1-next n2; n2-next n3; n3-next NULL; // 关键NULL 表示“链表到此结束” /* 遍历链表 */ struct Node *p n1; while (p ! NULL) { // 通过判断空指针知道是否结束 printf(%d\n, p-value); p p-next; } /* 释放内存 */ free(n1); free(n2); free(n3); return 0; } //执行结果 /* 1 2 3 *最后说一下空指针和Void指针的区别空指针NULL Pointer通用【万能】指针Void Pointer空指针不指向任何东西它是一个特殊的指针变量一个指向任何类型的指针任何类型的指针变量都可以被设置为空指针只有它才可以被定义为void型所有的空指针都相等Void指针可以是不同空指针在头文件里被定义为一个常量值void指针是一种指针的类型也就是说它是一种数据类型例如: int *ptr NULL;例如: void *ptr;以上关于空指针的概念和应用您理解了吗
企业数字化 ERP 产品动态
相关推荐
农业AI毕业设计实战:小样本水稻病害识别与轻量化部署 简介:本资源是一套完整的农作物病虫害智能识别毕业设计项目,面向计算机、农林信息化及人工智能方向的本科生与初学者,解决农业场景中病害图像分类与模型部署的实际问题。压缩包共56个文件,包含15张示例PNG图像、9个Jupyter Notebo… · 2026/9/26 11:21:26
OpenClaw + ROS 实战:用 TaoToken 统一 Key 为 AI 代理接入机器人身体 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:21:26
Jev 超快决策大脑:让网页 Agent 告别大模型延迟 1. 先搞清楚 Jev 到底在解决什么问题
1.1 网页 Agent 的“决策瓶颈”在哪里 聊 Jev 之前,得先把网页 Agent 的运作方式捋一遍。一个典型的网页 Agent,比如基于 Browser Use 这类方案构建的智能体,它的工作循环大致是这样的:观察当… · 2026/9/26 12:02:14
RK3588交叉编译实战:从hello world到YOLOv5s环境搭建 1. 为什么"交叉编译hello"是RK3588开发绕不开的第一道坎很多人拿到香橙派5之后,第一反应是插电、烧系统、接屏幕,然后在板子上直接写代码编译。这么做在PC上没问题,放到嵌入式板子上就是另一回事了。香橙派5搭载的RK3588是一颗8核A… · 2026/9/26 12:02:08
STM32最小系统四大核心设计原理与实战避坑指南 1. 什么是STM32最小系统?它到底“最小”在哪儿?你拆开一块淘宝上卖9.9包邮的“STM32F103C8T6最小系统板”,看到那块巴掌大的蓝色PCB,上面只有芯片、几个电容、一个晶振、两颗电阻和一个USB转串口芯片——这玩意儿真能跑起来&#… · 2026/9/26 12:02:08
Cursor安全插件链配置指南:用TaoToken统一Key打通代码审计工作流 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:02:08
Linux下使用Docker官方二进制包安装与运维实战 1. 对比包管理器与二进制通用包:什么环境才值得选后者
1.1 两种安装方式的分水岭 大多数人在 Linux 上装 Docker,第一反应就是 apt 或 yum 一把梭。这个思路本身没错, apt install docker.io 或者 yum install docker-ce 在普通场景里确… · 2026/9/26 12:02:01
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46