新闻详情

新闻详情

首页 / 资讯中心 / 详情

嵌入式软件-C语言指针终极简单理解使用教学

发布时间:2026/9/29 7:58:35来源:尧图网络
嵌入式软件-C语言指针终极简单理解使用教学
相信很多小伙伴在学嵌入式的时候和我一样c语言指针是一个分水岭原来只能用简单的逻辑做项目比如全是if和swich然后全区变量和局部变量满天飞只要代码能跑通即可基本不能维护和添加功能。那么你看到了这篇文章运气真是太好了我将用最简单的理解方式帮你完全理解指针并且应用到嵌入式软件工程中让你的工程质量更进一步。咱们都不是智商天才一点一点学呗hh。1.零基础认识指针1.1 什么是指针指针就是地址地址就是指针我们可以先看一个例子int a 5int是类型a是变量名5是值这个值只要存在那么在内存中就一定有一个独特的地址这个地址就是存储5的内存空间的名字或者理解为房间号那么你想要找到5这个值有两种方法1.直接prinf输出变量名a2.用变量名a的地址找到这个值先取a的地址a,再读取这个地址的值*(a)int a 5; //第一种方法 prinf(a %d\n,a); //第二种方法 //用取地址运算符先取地址 prinf(a 的地址是0x%p\n,a); //再用取值运算符*号把地址的值取出来 prinf(a %d\n,*(a));1.2 什么是指针变量大家都知道整型变量是存放整型数的变量那么指针变量就是存放指针的变量指针地址指针变量就是存储地址的变量。先普及一个小知识*号有两个作用上面1.1节演示的作用是取值运算符还有一个作用是标识符就是告诉系统这个变量是指针变量。指针变量存的是另一个变量的地址。还是那个例子假如我想要去存储整型变量a的地址也是存储5这个值的地址我需要先定义一个指针变量p然后把a的地址赋给p。int a 5; int *p ;//先定义一个指针变量注意此时我并没有给p赋值现在p不指向任何变量野指针 p a ;//用取a的地址赋给p现在这个p就是指针变量存储变量a的地址。现在我想用这个指针变量去输出a的值那就用取值运算符*号取出来a这个地址的值即可原来是 *(a),现在把a换成p即可就是*p。printf(a的值 %d\n,a); //5 printf(a的地址(10的地址)%p\n,a); printf(p里面存的值 %p\n,p); //和a完全一样 printf(p自己的地址 %p\n,p); //这是p本身的地址不一样 printf(*p %d\n,*p); //访问那个地址取出5内存地址 变量名 值 0x100 a 5 0x200 p 0x100 //p存的是a的地址还要注意定义指针变量的类型的时候这个指针变量的类型要和被指向变量的类型一样在这个例子中p的类型要和a的类型一样都必须是int类型不能用char *p等等。因为在读取a这个值的时候会出错编译能够成功但是取出来的值会出错。如果是用指针指向特定的区域比如单片机的地址0x66如何定义呢首先0x66是一个普通的字符串让它变成地址的性质需要用到强制类型转换符号()括号里面是类型我们要变成地址那么就需要指针类型如果是int类型的指针则需要用int *如果是char则用char *所以用指针指向特定的地址是int *c (int *)0x66,需要用一个指针变量c去承接它。2.指针的常见用法2.1 指针变量指向数组1.2部分是指针变量指向整型变量。下面是指向数组。指针变量指向数组就是指针变量保存的数组的首地址。数组的首地址就是数组当中第0个元素的首地址比如定义一个数组:int a[5] {1,2,3,4,5},数组的首地址就是第0个元素1的首地址。定义指针变量p指向数组aint a[5] {1,2,3,4,5}; int *p p a[0];数组的首地址还是数组名因此下面的代码和上面的等价就是直接把a[0]换成aint a[5] {1,2,3,4,5}; int *p ; p a;2.2 指针偏移指针偏移就是对指针变量p进行加减这里的加减不是地址的加减因为指针是指针类型如果和整型的1/2/3等加减不会造成不是地址的加减。指针变量p进行加减是按指针类型的大小跳过对应字节数。比如整型数组a[]中p指向第0个元素我想要把第1个元素的值取出来就可以用*(p1)prinf(第一个元素是%d,*(p1));这就是指针偏移当然指针偏移的量不会超过数组的总数不能偏移出数组程序会崩溃。在这个例子中在地址的层面上它的偏移的字节数是4因为int类型占的字节是4如果是其他的类型则是以下原则如果是int*每偏移 1跨过4 字节如果是char*每偏移 1跨过1 字节char 占 1如果是short*每偏移 1跨过2 字节还有有一个小知识数组名可以用来加减在这个例子也就是用数组名a代替指针p取数组中的元素的时候可以用*(a1)或*(a2)等等prinf(第一个元素是%d,*(a1));2.3 指针取内容的其他方式原来咱们取数组中的内容可以直接用a[1]或a[2]等等其中a是数组名现在知道了指针取数组内容可以用*p其中p指向数组那么还有其他方式可以取内容。1.指针可以当作数组名下标法访问内容就是指针p可以当作数组名来用也就是p[1]或p[2]等等int a[3]{1,2,3}; int *p a; printf(%d,p[1]);2.4二维数组的地址目前咱们已经知道了一维数组的地址表示就是数组名或者首元素的地址在二维数组中我们可以用父数组和子数组的方式去理解比如定义一个二维数组int a[3][4]这是一个三行四列的数组比如是一下内容1357911131517192123a[i]就表示第i行的元素集合a[0]{1,3,5,7}a[1]{9,11,13,15}a[2]{17,19,21,23}那么父数组的名就是aa[i]是第i行元素组成的子数组的名a[0],a[1],a[2]那么父数组的地址就是a因为数组的地址名就代表第一个元素a[0]的地址第一个元素的地址就是数组的地址也就是这个二维数组的地址。在这里二维数组a的元素是3个行元素,也就是a[0],a[1],a[2]这三个既是数组a的行元素也是a的子数组每一个行元素又是一个一维数组每个一维数组有四个元素也就是每一个子数组有四个元素。这些子数组又是一维数组的名那么也就是一维数组的地址比如我想要得到第二行这个子数组的值现在我们已经知道了第二行的地址就是子数组的名也就是a[1],那么取值就可以直接用*a[1]即可。还有需要注意的点如果我想要取整个二维数组a的地址可以用五种方法printf(%P,a); printf(%P,a); printf(%P,a[0]); printf(%P,a[0]); printf(%P,a[0][0]);它们都代表首元素的地址。在指针偏移方面在一维数组中指针p1也是a1指的是指针偏移一个元素p和a都是地址a是一维数组名在二维数组中我们需要注意的是整个二维数组名a的元素是三个分别是三个子数a[0],a[1],a[2]那么如果指针偏移表示的话就会和一维数组不一样比如a1则表示偏移一个子数组也就是偏移一行不是偏移表格中的单个元素。那如果是用子数组的名进行偏移呢也就是子数组的地址进行偏移也就是指向子数组的指针偏移也就是a[0]1子数组有四个元素也就是在第一行元素中进行偏移一个元素2.5 数组指针数组指针就是指向数组的指针分为1.指向整个数组。2.指向某一个元素。在二维数组中还有3.指向某一行。注意没有指向某一列因为地址不连续。我们知道在一维数组中定义一个指针指向这个数组的方式是int a[4]{1,2,3,4}; int *p; p a[0];在一维数组中指针偏移1就是移动一个元素那么在二维数组中数组指针的用法是什么呢首先如果是指针指向其中的一行a[0]或者a[1]等则是int a[3][4]{{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int (*p1)[4]; p1 a; int a[3][4]{{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int (*p2)[4]; p2 a[0];这两种方法都是指向其中一行a[0]。如果是指向整个二维数组则是int a[3][4]{{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int (*p)[3][4]; p a;a和a打印出来地址数值一模一样但是指针类型完全不同a→ 类型int (*)[4]行指针指向一行a→ 类型int (*)[3][4]指向整个二维数组以a[3][4]为例现在总结一下二维数组指针中易混的知识表达式含义类型1偏移楼房比喻a是整个二维数组的数组名也是第0行整行子数组的地址也就是行指针int (*)[4]16 字节跳到下一行整第 0 层楼的楼层编号1 → 去到下一层楼a[0]是第0行子数组的数组名也是第0行第0个元素的地址等同于a[0][0]。也是指向第 0 行第 0 个元素的指针。int *4 字节0 层第一个房间的门牌号1 → 同层下一间a是整个二维数组的地址也是指向整个二维数组的指针int (*)[3][4]48 字节跳过全部数组整栋大楼的大楼编号1 → 直接跳到下一栋大楼a[0][0]是第0行第0个元素值是元素的数据值int不能 1不是指针0 层 0 号房间里面住的人房间里的数据a[0][0]取第0行第0个元素的地址也是指向第0行第0个元素的指针int *4 字节a[0][1]0 层 0 号房间的门牌号1 → 同一层隔壁房间3.函数指针3.1 什么是函数指针指针就是地址那么函数指针就是函数的地址。也说为函数入口的地址在数组中数组名就是地址在这里函数名就是地址。在数组中定义数组指针变量指向数组用int (*p)a[i][j] a在这里定义函数指针变量指向函数则是用 void (*p)()函数名在数组中取值是用*号后面加指针变量指针变量指向数组例如一维数组取值*p在这里调用函数则是用*号后面加指针变量指针变量指向函数例如(*p)()3.2 函数指针的类型和数组一样函数指针也有类型。1.常见的普通函数没有返回值的函数定义指针变量如下void nihao() { printf(你好); } void (*p)() nihao ; 调用 (*p)();2.还有返回int 的函数还有返回double的函数类如这种定义指针变量如下int getdata(int a ,int b) { return ab ; } int (*p2)(int a ,int b) getdata ; 调用 (*p2)(1 ,2);3.3 指针函数指针函数就是一个函数只不过它的返回值是指针。恩。目前先写到这里吧等国庆假期回去再写祝大家中秋国庆快乐
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

NTFS取证实战:用$MFT重建文件时间线与恢复删除数据 2026/9/29 7:58:16

NTFS取证实战:用$MFT重建文件时间线与恢复删除数据

在应急响应和数字取证的实际工作中,最常见的一个问题就是:“这个文件到底什么时候创建的?中间有没有被改过名?删除之后还能不能找回来?”这些问题如果只靠翻目录、看文件属性,往往得不到真实答案&#xff0…

阅读更多 →
Mermaid画甘特图 2026/9/29 7:58:15

Mermaid画甘特图

文章目录甘特图基本语法dateFormat格式axisFormat格式甘特图 甘特图从外观来看,是一种水平条形图,其横轴表示时间,纵轴表示任务,从而直观展示项目进度计划。简单示例如下 #mermaid-svg-t5f5AXFpTQu0uJDW{font-family:"trebuc…

阅读更多 →
TRAE国际版团队开发配置:用TaoToken统一Key打通多人协作环境 2026/9/29 7:58:15

TRAE国际版团队开发配置:用TaoToken统一Key打通多人协作环境

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

阅读更多 →
TLS 1.3新握手协议的前向安全审计实战解析 2026/9/29 7:58:15

TLS 1.3新握手协议的前向安全审计实战解析

做安全审计做了这么多年,每年都要在各种报告里反复写SSL/TLS握手协议、前向安全这几个词。这次拿到这个《SSL/TLS 3.0新握手协议的前向安全审计研究报告》标题,我第一反应是:这个主题终于有人愿意往深里挖了。你可能也注意到了,网…

阅读更多 →
FAST Element StyleTarget 接口解析:自定义元素样式注入的节点契约 2026/9/29 7:58:08

FAST Element StyleTarget 接口解析:自定义元素样式注入的节点契约

前端UI组件 【免费下载链接】fast The adaptive interface system for modern web experiences. 项目地址: https://gitcode.com/gh_mirrors/fa/fast 点击查看 免费下载 本篇技术指南围绕 FAST Element(microsoft/fast-element)公开 API 中的…

阅读更多 →
深信服PT1-SIP实验考试题库全解析:从日志接入到溯源封堵的操作指南 2026/9/29 7:58:08

深信服PT1-SIP实验考试题库全解析:从日志接入到溯源封堵的操作指南

简介:面向深信服PT1-SIP实验考试的题库文档,围绕总部AF、AC、EDR与SIP01/SIP02集群的部署和联动展开,适合网络安全运维人员及备考人员按实验场景实操练习。文档先列出总部AF、AC、EDR、SIP01、SIP02等设备的管理网口、路由网口、业务网口IP及…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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