新闻详情

新闻详情

首页 / 资讯中心 / 详情

搞懂C语言的指针(四) 空指针|蒙圈的不止你一个

发布时间:2026/9/26 11:21:25来源:尧图网络
搞懂C语言的指针(四) 空指针|蒙圈的不止你一个
在上一篇我分享了的内容及理解在这里我们会搞懂空指针到底是怎么回事。在学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;以上关于空指针的概念和应用您理解了吗
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

用 OpenClaw 构建数字员工矩阵:TaoToken 统一 Key 接入与钉钉落地配置实践 2026/9/26 12:09:20

用 OpenClaw 构建数字员工矩阵:TaoToken 统一 Key 接入与钉钉落地配置实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
云服务器上的 Hermes Agent 如何通过 MCP 安全操纵本地文件:ngrok 内网穿透配置实战 2026/9/26 12:09:19

云服务器上的 Hermes Agent 如何通过 MCP 安全操纵本地文件:ngrok 内网穿透配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
PHP短网址源码深度解析:从短码生成到部署避坑全指南 2026/9/26 12:09:13

PHP短网址源码深度解析:从短码生成到部署避坑全指南

简介:这是一款基于PHP打造的黑色简洁短网址生成系统,适合站长、个人开发者或营销人员快速搭建自己的短链接服务,解决长链接冗长、点击数据难统计以及广告位管理不便等实际问题。源码包含完整的前后端功能:前端支持普通短链、自定义…

阅读更多 →
OpenClaw对接飞书全指南:本地部署、机器人接入与多维表格联动 2026/9/26 12:09:13

OpenClaw对接飞书全指南:本地部署、机器人接入与多维表格联动

最近很多人在问OpenClaw怎么跟飞书打通,特别是有不少朋友在群里反馈“机器人收到消息不回”“发长消息被截断”“session文件被锁”这类问题。我前前后后折腾了好几个晚上,总算把OpenClaw本地部署、飞书机器人接入、多维表格联动这一套流程完整跑通了。这…

阅读更多 →
Minlo深入测评:开源本地优先笔记工具,极简记录与数据安全兼得 2026/9/26 12:09:13

Minlo深入测评:开源本地优先笔记工具,极简记录与数据安全兼得

第一次看到 Minlo 这个词的时候,我确实愣了几秒钟。它不像常见的英文单词,也没有一眼能读懂的官方译名,翻了几条技术讨论之后才逐渐拼凑出它的样子:Minlo 是一个主打“本地优先”的开源轻量记录工具,全称可理解为 Mini…

阅读更多 →
Linux命名管道FIFO:跨进程通信的轻量方案 2026/9/26 12:09:12

Linux命名管道FIFO:跨进程通信的轻量方案

记得上一篇讲匿名管道的时候,有朋友留言说“管道虽然好用,但只能父子进程玩,换个不相干的进程就抓瞎了”。确实,匿名管道pipe()创建之后,只给出一对文件描述符,子进程能用是因为fork()会天然继承&#xff0…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉