关于KeilC51的指针

发布者:星尘散落最新更新时间:2016-12-14 来源: eefocus关键字:Keil  C51  指针 手机看文章 扫描二维码
随时随地手机看文章

  keil中的指针分为两种,一种是普通指针,兼容标准C语言的指针;另一种是我翻译成内存特殊指针(memory-specific pointers,翻译的不好:>)

  

  一、普通指针

  普通指针的定义方式如下, char * ptr;   跟标准C的定义方式一样。这种指针占三个字节。第一个字节是标识存储类型,是指针指向的变量的数据类型。 第二个字节是指针存储地址的高位字节。第三个字节是指针存储地址的低位字节。

  普通指针默认存储在内部存储器data,即片上RAM。如果想指定指针的存储位置,可以在 * 后加上存储类型,如下面几种定义方式:

char * data  ptr;     //与char * ptr;等价,即默认的定义方式char * xdata ptr;     //指针存储在片外RAMchar * idata ptr;     //指针存储在idatachar * pdata ptr;     //指针存储在pdata

   由定义普通指针写的程序最终的代码较长,运行速度相对较慢,因为keil在编译的时候不知道这个指针将要指向的变量的数据类型,只有当程序执行的时候才能知道,所以编译器不能对这段代码进行优化,不过,这样做的优点是,此指针可以指向存储在任何位置的变量。

 

  二、内存特殊指针

  内在特殊指针的定义方式为:

  char xdata * ptr;

  这个指针存储的时候占的字节数是不一定的,占一个字节的变量类型为:idata,data, pdata, bdata。占两个字节的变量类型为: code,xdata。下图是我在keil上测试的时候截的图:

  注意:

  char xdata * ptr;

   这里定义的ptr所指向的变量存储在xdata中,即外部变量,这样的话指针变量ptr占两个字节,我们再定义一个外部变量。

  char xdata variable1;
  ptr=&variable1;        //这样是正确的。

   这段程序中,变量variable1是存储在外部存储器中的,是最合适的。

    char data variable2;
     ptr = &variable2;

  变量variable2存储在片内存储器中。一个字节的指针即可以够用,不过这样写程序也不算错,我试过keil也能运行。像普通指针一样,定义内存特殊指针时也可以指定指针的存储位置。

  char xdata * data ptr;

  这个定义是说,定义了一个指向(存储在xdata)变量的一个(存储在data)的指针。

  内在特殊指针产生的代码可以经过编译器优化,运行速度较快。因为指针指向变量的存储位置是知道的,所以编译器在编译的时候可以进行优化。这样程序通过最简洁的方式去寻址,但是代价是降低了程序的灵活性。

 

  三、指针类型转换

   编译器在适当的时候对指针的类型进行转换。如进行参数传递的时候。如下面这个外部函数声明printf中的形参ptr是一个变通指针,编译器为函数分配三个字节 

复制代码

extern void printf(char  * ptr);char data  * ptr1 ;char xdata * ptr2 ;

voia main(void)
{
    printf(ptr1);       //这样在参数传递的时候转换
    printf(ptr2);       //未转换}

复制代码

  在第一个printf()调用中,实参是指向data,占两个字节。但是函数原型中形参是变通指针,占三个字节。这样,参数传递的过程中将ptr1扩展了成三个字节再传递。

  注意:为了防止在传递参数的时候造成类似的指针类型错误。在调用函数前,最好进行必要的外部函数声明(extern ...)或引用相应的头文件(#include ...)或者在函数调用填写参数的时候加上数据类型转换。这样就有两种的转换方式。
  1、形参为普通类型,实参为内存特殊类型:补充第一个字节为相应的数据类型代码。高位地址没有的补充第二字节为0
  2、实参为内存特殊类型,形参为普通类型:截取相应的地址字节。

  

   四,由上面的说明我们可以看出,,只要我们写程序的时候在 * 两面都加上类型的标识符就可以了。但是在使用的时候 * 两边都有类型标识,很容易记混。

char xdata * data ptr;

  这是一个指向一个存储在xdata的数据类型为char的指针,但这个指针却存储在data中。我是这样记的,与char在一起的xdata标识都是描述指针指向的变量的。而跟指针在一起的标识是描述指针自己的。


关键字:Keil  C51  指针 引用地址:关于KeilC51的指针

上一篇:EMS-keil C51常用错误
下一篇:Hash查找法在Keil C51中的实现

推荐阅读最新更新时间:2024-03-16 15:25

裸机程序--keil mdk下xc2440按键控制LED
其实只要前面几个回了,熟悉了keil mdk开发环境之后,简单的诸如led和按键的裸机程序其实和51单片机没什么区别了。。。 新建工程,配置GPF0,也就是LED1为输出模式,GPF4,也就是按键1为输入模式; 新建main.c文件,并加入工程,编写代码如下 同样给出 配置,和上次一模一样。。。
[单片机]
C51单片机学习笔记(六)——液晶显示屏的使用
1.LCD1602的认识 液晶显示屏简称液晶、LCD。各种型号的液晶通常是按显示字符的行数或液晶点阵的行、列进行命名的。1602的意思就是每一行显示16个字符,共可以显示2行,常见的液晶还有0801、0802、1601等,这类液晶是字符型液晶,只能显示ASCII码字符。而LCD12864属于图形型液晶,由128*64个像素点构成,可以显示各种图形包括汉字。 LCD1602可显示2行ASCII码字符,每行包括16个5*10点阵(像素),有16个引脚,其实物图如下所示: 2.LCD1602的引脚及其功能 3.LCD模块的内部结构 LCD1602模块的内部结构分为三部分:LCD控制器、LCD驱动器、LCD显示器 LCD控制器
[单片机]
<font color='red'>C51</font>单片机学习笔记(六)——液晶显示屏的使用
C51和MDK的ROM大小及变量绝对地址初始化
#1. C51的ROM大小 Keil编译完之后,显示的Program Size: data=9.0 xdata=8 const=15 code=180,则 The Total ROM(const + code + code-gap + const-gap) is 199BYTE 实际生成的bin文件大小: 在.MAP中的C O D E M E M O R Y 中 code-gap为0,cosnt-gap为4,则const + code + const-gap=15 + 180 + 4 = 199,刚好和实际生成的bin文件大小一致。 #2. C51的ROM大小优化 如果实际编译显示的const + code远小于实际的Bi
[单片机]
<font color='red'>C51</font>和MDK的ROM大小及变量绝对地址初始化
Keil C51单片机中变量的使用方法解析
8051内核单片机是一种通用单片机,在国内占有较大的市场份额。在将C语言用于51内核单片机的研究方面,Keil公司做得最为成功。由于51内核单片机的存储结构的特殊性,Keil C51中变量的使用与标准C有所不同。正确地使用变量,有利于获得高效的目标代码。下面详细介绍Keil C51中变量的使用方法。 一、CPU存储结构与变量的关系 变量都需要有存储空间,存储空间的不同使得变量使用时的工作效率也不同。 标准C的典型运行环境是8086(含IA-32系列)内核,其存储结构是CPU内部有寄存器,外部有存储器,寄存器的访问速度大大高于存储器的访问速度。在标准C中,不加特别定义的变量是放在存储器中的,使用register可以强制变量存储在
[单片机]
<font color='red'>Keil</font> <font color='red'>C51</font>单片机中变量的使用方法解析
单片机C51 DATA,XDATA,BDATA,IDATA,CODE存储资源分配
单片机初学者一般对c51语言里的DATA,XDATA,BDATA,IDATA,CODE,不是很清楚,因为在微机的c语言里根本没有这些东西,一下子出来难以让人接受,特别是没有硬件基本的朋友们.这也是写程序的时候经常犯错误的地方。请看下表 普通51系列单片机存储空间资源分配情况 空间名称 地址范围 说明 DATA D:00H~7FH 片内RAM直接寻址区 BDATA D:20H~2FH 片内RAM位寻址区 IDATA I:00H~FFH 片内RAM间接寻址区 XDATA X:0000H~FFFFH 64K片外RAM数据区 CODE C:
[单片机]
51单片机Keil C延时程序的简单研究
以前用汇编语言写单片机程序的时候,这个问题还是相对轻易解决的。比如用的是12MHz晶振的51,打算延时20us,只要用下面的代码,就可以满足一般的需要: mov r0, #09h loop: djnz r0, loop 51单片机的指令周期是晶振频率的1/12,也就是1us一个周期。mov r0, #09h需要2个极其周期,djnz也需要2个极其周期。那么存在r0里的数就是(20-2)/2。用这种方法,可以非常方便的实现256us以下时间的延时。假如需要更长时间,可以使用两层嵌套。而且精度可以达到2us,一般来说,这已经足够了。 现在,应用更广泛的毫无疑问是Keil的C编译器。相对汇编来说,C固然有很多优点,比如程序易维护,便
[单片机]
51单片机程序设计中的地址指针及其应用
CS-51单片机外部RAM的地址空间为64K,地址总线为16位,访问外接RAM可执行如下4条指令: MOVX A,@DPTR MOVX @DPTR,A MOVX A,@RI MOVX @RI,A 其中DPTR为16位地址寄存器,地址高8位存于DPH,地址低8位存于DPL;Ri(I=0,1)是8位寄存器,作为地址指针时仅存低8位地址。 MCS-51执行上述指令时分为两个阶段:首先,是从外接程序存储器中取出指令代码,并进行分析。然后,执行对外接RAM的数据读/写操作。在这两个阶段,P0口、P1口上的地址选通是有区别的。 执行“MOVX A,@DPTR”和“MOVX @DPTR,A”指令时,在读指令代码阶段,由程序计数器(PC)提供A0
[单片机]
指针变量,位带指针,LSB最低有效位······
1指针变量及例子 前面文章【 STM32位带操作 】牵涉到的一个重要知识点就是指针变量。 这种位带映射操作,就是操作映射过后的地址,其实就是操作指针变量。 指针变量:指存放地址的变量。 指针变量是一种特殊的变量,它不同于一般的变量,一般变量存放的是数据本身,而指针变量存放的是数据的地址。《摘自百度百科【指针变量】》 指针变量的例子 int main(void) { uint32_t *p; p = (uint32_t *)(0x42210184); System_Initializes(); while(1) { *p = 0; TIMDelay_Nms(500); *p = 1; TIM
[单片机]
<font color='red'>指针</font>变量,位带<font color='red'>指针</font>,LSB最低有效位······
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved