历史上的今天
今天是: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到桌面串口调试助手。
#include "reg51.h"
#define u16 unsigned int
#define u8 unsigned char
void delay(u16 x)
{
while(x--);
}
void Uart_Init() //串口初始化
{
SCON=0x50; //8位异步模式
TMOD|=0x20; //定时器1工作方式2
TH1=253;//9600bit/s
TR1=1;
}
void Send_Byte(u8 dat) //串口发送一个字节
{
SBUF=dat; //启动发送,只需要把发送内容给SBUF这个寄存器
while(TI==0); //等待发送完成,因为TI为1时表示在发送停止位
TI=0;
}
void Send_String(u8 *str) //发送一个字符串 *str为字符串第一个字符的地址
{
while(*str)
{
Send_Byte(*str);
str++;
}
}
void main()
{
Uart_Init();
while(1)
{
Send_String("0123456789");
Send_Byte(10); //回车键
delay(60000);
delay(60000);
}
}
从仿真串口接收器来看,这个程序运行得很好。现在我把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语言求首地址运算符。
下一篇:单片机C语言之串口通信协议
史海拾趣
|
常用元器件的识别 电阻 电阻在电路中用“R”加数字表示,如:R1表示编号为1的电阻。电阻在电路中的主要作用为 分流、限流、分压、偏置等。 1、参数识别:电阻的单位为欧姆(Ω),倍率单位有:千欧(KΩ),兆欧(MΩ)等。换算 方法是:1兆欧 ...… 查看全部问答> |
|
一般三极管厂家的产品手册上都会有三极管的最大耗散功率Pcm,那三极管在具体电路里工作的时候,我如何确定它的实际消耗功率呢?怎么保证选用的三极管功率够用?有没有计算公式? 如果没有具体的计算公式,那三极管实际消耗的功率和什么参数有关系 ...… 查看全部问答> |
|
第一个WINCE的项目,有两个问题要请教大家。 前提是,我只负责软件部分。 1 分辨率问题 显示屏幕尺寸是640*480,我做的程序要满屏幕显示。我在模拟器上通过GetClientWindow确定了窗口大小为640*480.而且我还通过MoveWindow,再次将窗口设置为0,0, ...… 查看全部问答> |
|
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 \ ...… 查看全部问答> |




