234彩票代理

  • <tt class='tlJykMlA'></tt>
  • <thead class='94K7Lauipx'><option class='9cNvbSu7LJ'></option></thead>

    <em class='jepytdnyfeW3'><b class='oR1Ys12nk'><td class='6rzzLTN'></td></b></em>

  • <dl class='Td0EmkF'><b class='qoWhaibfJ9'></b></dl>

  • <span class='lS1G'></span>

    (玩电子) 电子技术学习与研究
    当前位置:单片机教程网 >> 基础教程 >> 浏览文章

    第九课 C51运算︻符№和表达式(指针№和地址运算︻符)

    作者:佚名   来源:本站原创   点击数:x  更新时间:2007年07月15日   【字体:

    在第 3 课我们学习数据类型时,学习过指针类型,知道它是一种存放指向另一个数据的一地址的一变量类型 。指针是单片机C语言中一个十分重要的一概念,也是学习单片机C语言中的一一个难点 。对于指针将会在第九课中做详细的一讲解 。在这里我们先来了解一下单片机C语言中供给的一两个专门用于指针№和地址的一运算︻符:

    *    取▓内容

    &    取▓地址取▓内容№和地址的一一般形式分别为:

    变量  =  *  指针变量 指针变量  =  &  目标变量

    取▓内容运算︻是将指针变量所指向的一目标变量的一值赋给左边的一变量;取▓地址运算︻是将目标变量的一地址赋给左边的一变量 。要注意的一是:指针变量中只能存放地址(也就是指针型数据), 一般情况下不 要将非指针类型的一数据赋值给一个指针变量 。

    下面来看一个例子,并用一个图表№和实例去简单理解指针的一使用方法№和含义 。

    设有两个 unsigned  int  变量    ABC 处 CBA  存放在 0x0028,0x002A 中 另有一个指针变量    portA  存放在 0x002C 中 那么我们写这样一段程序去看看*,&的一运算︻结果

    unsigned  int  data  ABC  _at_  0x0028; unsigned  int  data  CBA  _at_  0x002A; unsigned  int  data  *Port  _at_  0x002C;

    #include  <at89x51.h>

    #include  <stdio.h>

    void  main(void)

    {

    SCON  =  0x50;  //串行口方式 1,允许接收 TMOD  =  0x20;  //定时器 1 定时方式 2

    TH1  =  0xE8;  //11.0592MHz  1200 波特率 TL1  =  0xE8;

    TI  =  1;

    TR1  =  1;  //启动定时器

    ABC  =  10;  //设初值 CBA  =  20;

    Port  =  &CBA;  //取▓ CBA 的一地址放到指针变量 Port

    *Port  =  100;  //更改指针变量 Port 所指向的一地址的一内容

    printf("1:  CBA=%d\n",CBA);  //显示此时 CBA 的一值


    Port  =  &ABC;  //取▓ ABC 的一地址放到指针变量 Port

    CBA  =  *Port;  //把当前 Port 所指的一地址的一内容赋给变量 CBA

    printf("2:  CBA=%d\n",CBA);  //显示此时 CBA 的一值

    printf("     ABC=%d\n",ABC);  //显示 ABC 的一值

    }

    程序初始时

    地址

    说明

    0x00

    0x002DH

     

    0x00

    0x002CH

     

    0x00

    0x002BH

     

    0x00

    0x002AH

     

    0x0A

    0x0029H

     

    0x00

    0x0028H

     

    执行 ABC  =  10;向 ABC 所指的一地址 0x28H 写入 10(0xA),因  ABC 是 int 类型要占用 0x28H №和

    0x29H 两个字节的一内存空间,低位字节会放入高地址中,所以 0x28H 中放入 0x00,0x29H 中 放入 0x0A

    地址

    说明

    0x00

    0x002DH

     

    0x00

    0x002CH

     

    0x00

    0x002BH

     

    0x00

    0x002AH

     

    0x0A

    0x0029H

    ABC 为 int 类型占用两字节

    0x00

    0x0028H

     

    执行 CBA  =  20;原理№和上    一句一样

    地址

    说明

    0x00

    0x002DH

     

    0x00

    0x002CH

     

    0x14

    0x002BH

    CBA 为 int 类型占用两字节

    0x00

    0x002AH

     

    0x0A

    0x0029H

    ABC 为 int 类型占用两字节

    0x00

    0x0028H

     

    执行 Port  =  &CBA;  取▓ CBA 的一首地址放到指针变量 Port

    地址

    说明

    0x00

    0x002DH

     

    0x2A

    0x002CH

    CBA 的一首地址存入 Port

    0x14

    0x002BH

     

    0x00

    0x002AH

     

    0x0A

    0x0029H

     

    0x00

    0x0028H

     

    *Port  =  100;  更改指针变量 Port 所指向的一地址的一内容

    地址

    说明

    0x00

    0x002DH

     

    0x2A

    0x002CH

     

    0x64

    0x002BH

    Port 指向了 CBA 所在地址 2AH

    0x00

    0x002AH

    并存入 100

    0x0A

    0x0029H

     

    0x00

    0x0028H

     

    其它的一语句也是一样的一道理,大家能用 Keil 的一单步执行№和打开存储器查看器一看,这样

    就更不 难理解了 。

    图 9-1    存储器查看窗

    图 9-2    在串行调试窗口的一最终结果

    sizeof 运算︻符

    看上    去这确实是个奇怪的一运算︻符,有点像函数,却又●不 是 。大家看到 size 应该就猜到 是№和大小有关的一吧?是的一,sizeof  是用来求数据类型、变量或是表达式的一字节数的一一个运 算︻符,但它并不 像“=”之类运算︻符那样在程序执行后才能计算︻出结果,它是直接在编译时 产生结果的一 。它的一语法如下:

    sizeof  (数据类型)


    sizeof  (表达式) 下面是两句应用例句,程序大家能试着编写一下 。

    printf("char 是多少个字节?  ½  字节\n",sizeof(char));

    printf("long 是多少个字节?  ½  字节\n",sizeof(long));

    结果是:

    char 是多少个字节?  1 字节

    long 是多少个字节?  4 字节

    强制类型转换运算︻符 不 知你们是否有自己去试着编一些程序,从中是否有遇到一些问题?开始学习时我就遇到过

    这样一个问题:两个不 一样数据类型的一数在相互赋值时会出现不 对的一值 。如下面的一一段小程序:

    void  main(void)

    {

    unsigned  char  a;

    unsigned  int  b;

    b=100*4;

    a=b;

    while(1);

    }

    这段小程序并没有什么实际的一应用意义,如果你是细心的一朋友定会发现 a 的一值是不 会等于

    100*4 的一 。是的一 a №和 b 一个是 char 类型一个是 int 类型,从以前的一学习可知 char 只占一个 字节值最大只能是 255 。但编译时为何不 出错呢?先来看看这程序的一运行情况:

    图 9-3    小程序的一运行情况

    b=100*4 就能得知 b=0x190,这个时候我们能在 Watches 查看 a 的一值,对于 watches 窗口我们 在第 5 课时简单学习过,在这个窗口 Locals 页里能查看程序运行中的一变量的一值,也能

    在  watch  页中输入所要查看的一变量名对它的一值进行查看 。做法是按图中  1  的一  watch#1(或

    watch#2),然后光标移到图中的一 2 按 F2 键,这样就能输入变量名了 。在这里我们能查看

    到 a 的一值为 0x90,也就是 b 的一低 8 位 。这是因 为执行了数据类型的一隐式转换 。隐式转换是 在程序进行编译时由编译器自动去处理完成的一 。所以有必要了解隐式转换的一规则:

    1.变量赋值时发生的一隐式转换,“=”号右边的一表达式的一数据类型转换成左边变量的一数


    据类型 。就如上    面例子中的一把 INT 赋值给 CHAR 字符型变量,得到的一 CHAR 将会是 INT 的一低 8 位 。如把浮点数赋值给整形变量,小数部分将丢失 。

    2.所有 char 型的一操作数转换成 int 型 。

    3.两个具有不 一样数据类型的一操作数用运算︻符连接时,隐式转换会按以下次序进行:如 有一操作数是 float 类型,则另一个操作数也会转换成 float 类型;如果一个操作数为 long 类型,另一个也转换成 long;如果一个操作数是 unsigned 类型,则另一个操作会被转换成 unsigned 类型 。

    从上    面的一规则能大概知道有那几种数据类型是能进行隐式转换的一 。是的一,在  单片机c语言 中只有 char,int,long 及 float 这几种基本的一数据类型能被隐式转换 。而其它的一数据类型 就只能用到显示转换 。要使用强制转换运算︻符应遵循以下的一表达形式:

    (类型)  表达式 用显示类型转换来处理不 一样类型的一数据间运算︻№和赋值是十分方便№和方便的一,特别对指针

    变量赋值是很有用的一 。看一面一段小程序:

    #include  <at89x51.h>

    #include  <stdio.h>

    void  main(void)

    {

    char  xdata  *  XROM;

    char  a;

    int  Aa  =  0xFB1C;

    long  Ba  =  0x893B7832;

    float  Ca  =  3.4534;

    SCON  =  0x50;  //串行口方式 1,允许接收 TMOD  =  0x20;  //定时器 1 定时方式 2

    TH1  =  0xE8;  //11.0592MHz  1200 波特率 TL1  =  0xE8;

    TI  =  1;

    TR1  =  1;  //启动定时器

    XROM=(char  xdata  *)  0xB012;  //给指针变量赋 XROM 初值

    *XROM  =  ‘R’;  //给 XROM 指向的一绝对地址赋值

    a  =  *((char  xdata  *)  0xB012);  //等同于 a  =  *XROM

    printf  (“%bx  %x  %d  %c  \n”,(char)  Aa,  (int)  Ba,(int)Ca,  a);//转换类型并输出

    while(1);

    }

    程序运行结果:1c  7832  3  R 在上    面这段程序中,能很清楚到到各种类型进行强制类型转换的一基本使用方法,程序中先

    在外部数据存储器 XDATA 中定义了一个字符型指针变量 XROM,当用 XROM=(char  xdata  *)

    0xB012 这一语句时,便把 0xB012 这个地址指针赋于了 XROM,如你用 XROM 则会是非法的一, 这种方法特别适合于用标识符来存取▓绝对地址,如在程序前用#define  ROM  0xB012  这样的一 语句,在程序中就能用上    面的一方法用 ROM 对绝对地址 0xB012 进行存取▓操作了 。运算︻符的一优先级说明表格能在笔者的一 本教程附录 中查看 。

    发表评论】【告诉好友】【收藏此文】【关闭窗口

    文章评论

    相关文章