历史上的今天
返回首页

历史上的今天

今天是:2025年05月06日(星期二)

正在发生

2018年05月06日 | 单片机C语言之指针变量

2018-05-06 来源:eefocus

单片机C语言变量分别有char型,int型,long型,float型等,它们分别占用内存为1个单元,2单元,4单元,4单元等,另外数组和字符串则占用了内存某段连续的单元。这些变量的共同特征是它们都装的数值。那如果一个变量里面装的不是数值,而是地址,这个变量则称为指针变量。所以指针变量用于存储器的地址号。

那么问题又来了,指针变量占多大内存呢?比如char *p,p指针变量前面用char修饰,莫非占一个单元?再例如 long *r,r指针变量前用long修饰,莫非是占4个单元?我们知道C51中,RAM的地址号是从0到255,ROM则是从0到65535。最大的地址号是正整数65535,显然有两个字节便可装下。因此C51中指针变量自身只占两个单元。

既然如此那这些类型修饰符可以不要?我们知道,指针变量中装的是一个地址,也就是说通过这个地址,我便可以找到这个地址中的信息。如果指针指向的是一个char型变量,那么其通过指针(装载char型变量的地址)我找到了这个变量。但如果是指向一个float型变量呢,如果没有这个float来修饰指针变量,那么我们巡着指针只能找到一个字节的数据,而一个float型有4个字节,显然计算机就分不清是不是该把指针后面的三个字节视为一个完整的数据。所以指针变量前面的类型修饰符不是用于修饰指针变量自身所占用的地址数量,而是用于修饰指针变量中所存储的地址与后续地址之间的关联情况。

接下来我们用一个实验来感受下指针的用法。

实验、从单片机发送字符串0123456789到桌面串口调试助手。

  1. #include "reg51.h"  

  2. #define u16 unsigned int  

  3. #define u8 unsigned char  

  4.   

  5. void delay(u16 x)  

  6. {  

  7.     while(x--);  

  8. }  

  9.   

  10. void Uart_Init() //串口初始化  

  11. {  

  12.     SCON=0x50; //8位异步模式  

  13.     TMOD|=0x20; //定时器1工作方式2  

  14.     TH1=253;//9600bit/s  

  15.     TR1=1;  

  16. }  

  17.   

  18. void Send_Byte(u8 dat)    //串口发送一个字节  

  19. {  

  20.     SBUF=dat; //启动发送,只需要把发送内容给SBUF这个寄存器  

  21.     while(TI==0); //等待发送完成,因为TI为1时表示在发送停止位  

  22.     TI=0;  

  23. }  

  24.   

  25.  void Send_String(u8 *str)   //发送一个字符串  *str为字符串第一个字符的地址  

  26.  {  

  27.     while(*str)  

  28.     {  

  29.         Send_Byte(*str);  

  30.         str++;  

  31.     }  

  32.   

  33.  }  

  34.   

  35. void main()  

  36. {  

  37.     Uart_Init();  

  38.     while(1)  

  39.     {  

  40.        Send_String("0123456789");  

  41.        Send_Byte(10); //回车键  

  42.        delay(60000);  

  43.        delay(60000);  

  44.     }  

  45. }  


从仿真串口接收器来看,这个程序运行得很好。现在我把void Send_String(u8 *str)修改为void Send_String(u16 *str),重新编译并仿真,运行得到



13579?跟着一串乱码,这又是为什么?u16是一个无符号int型,Send_String函数每次会取两个单元作为一个数传进来,进入while循环后,第一次就取"0"*256+"1"传给了Send_Byte函数,而Send_Byte只能装下u8型即一个单元数据,就就是高位的0要溢出,就只剩下1了。所以一直取到了9,之后因为while(*str),继续取字符串后续的内存单元,而这些内存单元里面是什么并不确定,所以显示乱码。

同样我们可以尝试void Send_String(long *str)等等。另外补充一个知识点,定义chara; char *p; p=&a; 其中&是C语言求首地址运算符。


推荐阅读

史海拾趣

ERA Transformers公司的发展小趣事

为了保持技术领先地位和市场竞争力,ERA Transformers公司非常重视创新与研发工作。公司每年都会投入大量资金用于新产品的研发和技术创新。在一次研发项目中,公司成功开发出了一种具有超高能效和极低损耗的新型变压器。这款产品的问世立即引起了市场的广泛关注,并成功获得了多项国内外专利。持续的创新与研发使得ERA Transformers公司在电子行业中始终保持着领先地位。

ELANTEC (Renesas )公司的发展小趣事

作为一家半导体公司,技术突破和创新是ELANTEC发展的核心动力。在移动通信领域,ELANTEC不断推出具有创新性的产品和技术,如低功耗、高性能的移动通信芯片等。此外,在汽车电子、工业控制等领域,ELANTEC也取得了多项技术突破,为客户提供了更加优质的产品和服务。

Cantherm公司的发展小趣事

随着环保意识的日益增强,Cantherm公司积极响应国家号召,将环保理念融入产品设计和生产过程中。公司研发出一系列环保型电子产品,采用可降解材料和节能技术,有效降低了产品对环境的影响。这一举措不仅提升了公司的社会形象,还为公司带来了更多的环保项目合作机会。

Digital Core Design公司的发展小趣事

随着《古墓丽影》系列游戏的成功,Core Design的团队迅速扩张。当PS2主机即将推出时,索尼和Core Design都对这款新主机充满期待。为了抓住这一机遇,Core Design将“古墓丽影”的制作团队从最初的12人增加到60人,随后又增加到了100人。这一举措展示了Core Design对市场和技术的敏锐洞察力和决心。

ANOVA公司的发展小趣事

面对日益复杂多变的电子市场环境,ANOVA公司始终保持着清醒的头脑和敏锐的洞察力。无论是疫情带来的供应链挑战,还是技术更新换代带来的竞争压力,ANOVA都能迅速应对,不断调整策略,确保公司的稳健发展。同时,ANOVA也积极展望未来,不断探索新的业务领域和技术方向,以期在电子行业中继续保持领先地位。

这五个故事只是ANOVA公司发展过程中的冰山一角,但它们足以展现出ANOVA公司如何在电子行业中逐步崛起,成为一支不可忽视的力量。ANOVA以其卓越的技术实力、全球化的布局和紧密的合作伙伴关系,不断推动着电子行业的发展和进步。

Hitano Enterprise Corp公司的发展小趣事

ANOVA深知,成功的关键在于与合作伙伴的紧密合作。因此,公司始终与客户保持紧密的合作关系,共同开发特定的解决方案,协助制定部署策略。ANOVA的服务团队以客户的需求为导向,以十几种语言提供个性化的服务,确保每一位客户都能得到满意的解决方案。此外,ANOVA还积极与商业伙伴合作,共同开拓市场,实现共赢。

问答坊 | AI 解惑

常用电子元器件的识别(1)

常用元器件的识别 电阻 电阻在电路中用“R”加数字表示,如:R1表示编号为1的电阻。电阻在电路中的主要作用为 分流、限流、分压、偏置等。 1、参数识别:电阻的单位为欧姆(Ω),倍率单位有:千欧(KΩ),兆欧(MΩ)等。换算 方法是:1兆欧 ...…

查看全部问答>

三极管的实际工作功率如何确定?

一般三极管厂家的产品手册上都会有三极管的最大耗散功率Pcm,那三极管在具体电路里工作的时候,我如何确定它的实际消耗功率呢?怎么保证选用的三极管功率够用?有没有计算公式? 如果没有具体的计算公式,那三极管实际消耗的功率和什么参数有关系 ...…

查看全部问答>

STM32 函数说明

很有用的STM32 开发函数说明…

查看全部问答>

FPGA-SOPC开发快速教程.pdf

FPGA-SOPC开发快速教程.pdf…

查看全部问答>

图像处理与视频编、解码

CCD与CMOS图像传感器,你了解吗? 图像处理算法的硬件实现你试过吗? 犹如洪水般滚滚而来的高速、高流量的视频你怎么应付啊?…

查看全部问答>

第一个WINCE的项目,有两个问题要请教大家

第一个WINCE的项目,有两个问题要请教大家。 前提是,我只负责软件部分。 1 分辨率问题 显示屏幕尺寸是640*480,我做的程序要满屏幕显示。我在模拟器上通过GetClientWindow确定了窗口大小为640*480.而且我还通过MoveWindow,再次将窗口设置为0,0, ...…

查看全部问答>

【求助】keil中使用lib文件中的问题

LIB_VER2.0.LIB(1): error C100: unprintable character 0x07 skipped LIB_VER2.0.LIB(1): error C141: syntax error near \',\' LIB_VER2.0.LIB(2): error C100: unprintable character 0xFD skipped LIB_VER2.0.LIB(3): error C129: missing \ ...…

查看全部问答>

关于地址分配

西门子PLC,各模块的地址是固定分配的,可是他的地址又不是连贯的(比如做组态时,两块相同的16路DI模块分别插入两个相邻的SLOT  中,可是两块模块之间的地址不连续。第一块开始0,结束1,;第二块开始4,结束5)。系统默认选项去掉后可以 ...…

查看全部问答>

承接项目

由于现在工作比较清闲,想在此论坛可以找到类似兼职。说明:自己不是很懂,愿意跟从师傅,打杂跑腿,只要是有关DSP相关的工作都可以。 有意者请联系:media.28@163.com 我会一直关注我的邮箱。…

查看全部问答>