尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C语言学习笔记(指针)
指针指向变量所使用的内存空间的地址指针变量一个变量专门用来存放另一变量在内存中数据的地址 (即指针)则它称为“指针变量”。我们可以通过访问指针变量达到访问内存中另一个变量数据的目的。(有时为了阐述方便 将指针变量直接说成指针。)指针变量声明格式数据类型指针变量名 [初始地址值];是指针变量指向地址的字符 * 用于告知系统这里定义的是一个指针变量通常跟在类型关键字的后面。比如 char * 表示一个指向字符的指针 float * 表示一个指向 float 类型的值的指针。此外还有指向数组的指针、指向结构体的指针。举例2同一行声明两个指针变量 // 正确 int * a, * b; // 错误 inta, b; //此时a是整数指针变量而b是整数变量取址运算符使用“”符号来表示。作用 取出指定变量在内存中的地址其语法格式如下 变量举例1int num 10; printf(num %d\n, num); // 输出变量的值。 num 10 printf(num %p\n, num); // 输出变量的内存地址。 num 00000050593ffbbc说明 1、在输出取址运算获得的地址时需要使用“%p”作为格式输出符。2、这里num的4个字节每个字节都有地址取出的是第一个字节的地址较小的地址。C语言中的地址包括位置信息(内存编号或称纯地址)和它所指 向的数据的类型信息即它是“ 带类型的地址”。所以一个指针变 量只能指向同一个类型的变量不能抛开类型随意赋值。在没有对指针变量赋值时指针变量的值是不确定的可能系统 会分配一个未知的地址此时使用此指针变量可能会导致不可预料 的后果甚至是系统崩溃。为了避免这个问题通常给指针变量赋初 始值为0(或NULL)并把值为0的指针变量称为 空指针变量。在C语言中针对指针运算还提供了一个取值运算符使用“ * ” 符号表 示。其 作用与相反根据一个给定的内存地址取出该地址对应变量的值。也称为解引用符号。其格式如下*指针表达式其中“ * ”不同于定义指针变量的符号这里是运算符。“指针表达式”用于得到一个内存地址与“ * ”结合以获得该内存地址对应变量的值 运算符与 * 运算符互为逆运算下面的表达式总是成立 int i 5; if (i * (i)) // 正确举例3通过指针变量修改指向内存地址位置上的值int main() { int num 10; int *p num *p 20; printf(num %d\n,num); //num 20 } char ch w; char* pc ch; *pc s; printf(ch %c\n, ch); //ch s return 0问题1 *p的含义是什么? “”和 “*”两个运算符的优先级别相同但按自右而左方向运算。因此*p与a相同即变量a的地址。 如果有 p1 *p;它的作用是将 a (a的地址)赋给 p1 如果p1原来指向 b经过重新赋值后它已不再指向b了而指向了 a。 问题2 *a的含义是什么? 先进行a运算得a的地址再进行*运算。 是一样的它们都等价于变量a。即 2.3 指针的常用运算 *a和*p的作用 *a与 a 等价。指针的常用运算指针本质上就是一个无符号整数代表了内存地址。除了上面提到的取址运算外指针还可以与整数加减、自增自减、同类指针相减运算等。但是规则并不是整数运算的规则。指针与整数值的加减运算格式 指针±整数指针与整数值的加减运算表示指针所指向的内存地址的移动 加向后移动减向前移动。指针移动的单位与指针指向的数据类型有关。数据类型占据多少个字节每单位就移动多少个字节。 通过此操作可以快速定位你要的地址。说明指针p1并不是地址1而是指针p指向数组中的下一个数据。比如int *pp1表示当前地址4指向下一个整型数据。注意只有指向连续的同类型数据区域指针加、减整数才有实际意义。对于长度是 N 的一维数组 a当使用指针 p 指向其首元素后即可 通过指针 p 访问数组的各个元素。其中 a[0]用 *p 表示 a[1]用 *(p1)表示 a[i]用 *(pi)表示指针类型变量也可以进行自增或自减运算如下p 、 p-- 、 p 、--p和–在运算符章节已经讲过这里针对指针的增加或减少指的是内存地址的向前或向后移动针对于数组来说由于数组在内存中是连续分布的。当对指针进行时指针会按照它指向的数据类型字节数大小增加比如int * 指针每 一次 就增加4个字节。当对指针进行–时指针会按照它指向的数据类型字节数大小减少比如 int * 指针每 – 一次 就减少4个字节。两个指针相减通常两个指针都是指向同一数组中的元素才有意义。结果是两个地址之差除以数组元素的长度。不相干的两个变量的地址通常没有做减法的必要。两个指针进行加法是非法的所得结果是没有意义的。指针之间的比较运算比如 、! 、、 、 、 。比较的是各自的内存地址的大小返回值是整数 1 true或 0 false。野指针就是指针指向的位置是不可知 随机性 明确限制的1.指针使用前未初始化 指针变量在定义时如果未初始化其值是随机的此时操作指针就是去访问一个不确定的地址所以结果是不可知的。此时p就为野指针。在没有给指针变量显式初始化的情况下一系列的操作(包括修改指 向内存的数据的值)也是错误的。拓展注意如下的赋值操作也是错误的 int main() { int num 10; int *p; p num; return 0;2.指针越界访问 #include stdio.h int main() { int arr[10] {0}; int *p arr; for (int i 0; i 10; i,p) { *p i; //i10时越界 } return 0; }3.指针指向已释放的空间 #include int *test() { int a 10; return a; } int main() { int *p test(); printf(%d, *p); return 0; }如何避免野指针 1、指针初始化定义指针的时候如果没有确切的地址赋值为指针变量赋一个 NULL 值是好的编程习惯。即 int *p NULL 赋为 NULL 值的指针被称为 空指针NULL 指针是一个定义在标准库中的值为零的常量 #define NULL 0 后面如果用到指针的话再让指针指向具有实际意义的地址然后通过指针的取值符号(*)改变其指向的内容。 2、小心指针越界 3、避免返回局部变量的地址 4、指针指向空间释放及时置NULL 5、指针使用之前检查有效性 if (pa ! NULL){ //进行使用 } if (pa NULL){ //不进行使用 }所谓 数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。因为数组名a保存的是 数组首元素a[0]的地址所以在scanf函数中的输入项如果是数组名不要再加地址符int main() { char arr[10]; scanf(%s, arr); //arr前不应加 puts(arr); return 0; }如果指针变量p的初值为 a[0]则 pi和 ai就是数组元素a[i]的地址或者说它们指向a数组序号为i的元素。 *(ai)或*pi是pi或者ai所指向的数组元素的值即a[i]的值。指向数组元素的指针变量也可以带下标如 p[i]。p[i]被处理成 * (pi)如果p是指向一个整型数组元素a[0]则p[i]代表a[i]。但是 必须弄清楚p的当前值是什么如果当前p指向a[3]则p[2]并不代表 a[2]而是a[32]即a[5]arr 理解为数组的地址而不要理解为数组首元素a[0]的地址一个字符串可以使用一维字符数组表示也可以使用字符指针来表示。字符数组由若干个元素组成每个元素放一个字符字符指针变量中存放的是地址字符串/字符数组的首地址 绝不是将字符串放到字符指针变量中。举例1char str[] hello tom; //使用字符数组 char * pStr hello tom; //使用字符指针一个字符数组因为它有确定的内存地址所以字符数组名是一 个常量。而定义一个字符指针变量时它在指向某个确定的字 符串数据的情况下也可以多次重新赋值
RELATED

相关推荐

3个月从纯前端到独立交付AI产品 | 给前端小白的AI转型路线图(收藏版)

3个月从纯前端到独立交付AI产品 | 给前端小白的AI转型路线图(收藏版)

本文作者分享了从纯前端独立交付完整AI产品的3个月转型经历,涵盖后端基础、数据库设计、AI接入实战、Agent工具调用等关键学习点。通过项目驱动、AI辅助学习的方式,逐步掌握Node.js、Prisma、DeepSeek API等技能,最终实现前端界面、后端API、…

📅 2026/10/10 9:14:56
掌握AI智能体,小白也能月入过万:收藏这份进阶指南!

掌握AI智能体,小白也能月入过万:收藏这份进阶指南!

本文介绍了如何利用AI智能体(Agent)提升工作效率和收入。通过三个真实案例,展示了运营、Java工程师和行政人员如何通过学习和应用AI技术,实现职业突破和薪资增长。文章强调AI不是简单的工具,而是能够自动化工作流程的数…

📅 2026/10/10 9:14:56
智能广播打铃系统实战:定时任务、铃声编辑与方案切换全解析

智能广播打铃系统实战:定时任务、铃声编辑与方案切换全解析

智能广播打铃系统正式版这名字,乍一听就是"定时放个音乐"的事,但真正在校园里部署过的人,都知道事情没那么简单。我见过太多学校,每天早上靠值日老师在广播室掐表按播放键,用音响放同一段MP3,放了…

📅 2026/10/10 9:14:56
MORE NEWS

更多资讯

📰

模拟企业开发环境搭建五天实战:从裸机到可协作可复现环境

看到这个标题,参加过系统化技术培训或是带过实训项目的人应该会心一笑。Day01-05,第五个学习日,主题是"搭建项目环境",目标很明确:"模拟企业环境",记录里还留着15:12这样的时间戳&…

📰

Python的循环里别用+=拼接字符串,真的会慢到哭

上周排查一个线上接口超时问题,发现日志里一个看似无害的字符串拼接操作,在处理 10 万条数据时竟拖慢了整个服务 3 秒——而换成正确的写法后,耗时直接降到 30 毫秒。这不是什么黑魔法,而是 CPython 字符串不可变特性在循环里的致…

📰

链表头结点详解:从原理到实战,彻底解决指针边界问题

提到链表头结点,很多新手的反应是:这不是一个多余的东西吗?数据都没存,凭什么占一个节点?但真正动手写插入、删除、遍历之后,又会发现代码各种边界条件纠缠不清,最后往往栽在“链表头到底改没改…

📰

PHP轻量课表查询系统:基于XMLReader的Excel解析与RESTful课表服务

简介:这是一套基于PHP与Excel的通用课表查询系统源码,面向计算机专业本科生、毕业设计开发者及Web初学者,解决学校、培训机构课程信息动态管理与便捷查询的实际需求。资源共19个文件,含5个核心PHP脚本(如index.php入口…

📰

别等迷路才下载:5 款户外轨迹导航 APP 实测与适配人群

作为多年徒步爱好者,我手机里常驻两步路户外助手,也习惯出发前用两步路户外助手核对轨迹。户外最怕的不是累,而是岔路口没信号、地图刷不出来、轨迹漂移,前后队一拉开,谁也不知道谁在哪。尤其重装穿越、夜爬、雨雾天&a…

📰

Fedora 安装 Microsoft Edge 官方仓库配置与常见问题排查指南

如果你也跟我一样,主力系统是 Fedora,桌面日常却始终绕不开一个 Chromium 内核的浏览器需求,那 Microsoft Edge 是个值得一试的选择。网上关于 Windows 版 Edge 的教程满天飞,但 Fedora 下的安装与配置往往被一笔带过;…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬