单片机c语言教程:C51运算符和表达式(指针和地址运算符)

发布者:ShiningSmile最新更新时间:2012-09-21 来源: 21ic 关键字:c语言教程  C51运算符  表达式 手机看文章 扫描二维码
随时随地手机看文章

我们学习数据类型时,学习过指针类型,知道它是一种存放指向另一个数据的地址的变量类型。指针是单片机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  

#include  

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=%dn",CBA);  //显示此时 CBA 的值

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

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

printf("2:  CBA=%dn",CBA);  //显示此时 CBA 的值

printf("     ABC=%dn",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

 

[page]

执行 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    在串行调试窗口的最终结果

[page]

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 位。这是因为执行了数据类型的隐式转换。隐式转换是 在程序进行编译时由编译器自动去处理完成的。所以有必要了解隐式转换的规则:

[page]

1.变量赋值时发生的隐式转换,“=”号右边的表达式的数据类型转换成左边变量的数据类型。就如上面例子中的把 INT 赋值给 CHAR 字符型变量,得到的 CHAR 将会是 INT 的低 8 位。如把浮点数赋值给整形变量,小数部分将丢失。

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

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

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

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

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

#include  

#include  

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 进行存取操作了。

关键字:c语言教程  C51运算符  表达式 引用地址:单片机c语言教程:C51运算符和表达式(指针和地址运算符)

上一篇:单片机c语言教程:C51表达式语句及仿真器
下一篇:单片机c语言教程:运算符和表达式(位运算符)

推荐阅读最新更新时间:2024-03-16 13:09

关于ARM汇编中字符串表达式运算符总结如下
:LEN:X 返回字符串X的长度(字符数) :CHR:M 将0~255之间的整数转换为一个字符 :STR:X 将一个数字表达式或逻辑表达式转换为一个字符串.对于数字表达式,STR运算符将其转换为一个以十六进制组成的字符串;对于逻辑表达式,STR运算符将其转换为字符串T或F. X:LEFT:Y 返回某个字符串左端的一个子串.X为源字符串,Y表示返回的个数 X:RIGHT:Y 与LEFT对应 X:CC:Y 将Y连接到X的后面 :BASE:X 返回基于寄存器的表达式中寄存器的编号 :INDEX:X 返回基于寄存器的表达式中相对于其基址寄存器的偏移量 ?X 返回定义符号X的代码行所生成的可执行代码的字节数 :DEF:X
[单片机]
单片机c语言教程C51表达式语句及仿真器
前面学习了大部分的基本语法,以下所要学习的各种基本语句的语法能说是组成程序的灵魂。在前面的课程中的例子里,也简单理解过一些语句的使用方法,能看出C语言是一种结构化的程序设计语言。C 语言供给了相当丰富的程序控制语句。学习掌握这些语句的使用方法也是单片机C语言学习中的重点。 表达式语句是最基本的一种语句。不一样的程序设计语言都会有不一样的表达式语句,如VB就是在表达式后面加入回车就构成了VB 的表达式语句,而在51单片机的C语言中则是加入分号“;”构成表达式语句。举例如下: b = b * 10; Count++; X = A;Y = B; Page = (a+b)/a-1; 以上的都是合法的表达式语句。在我收到的一些网友
[单片机]
单片机<font color='red'>c语言</font><font color='red'>教程</font>:<font color='red'>C51</font><font color='red'>表达式</font>语句及仿真器
用定制测量表达式简化PSpice对最坏情形的模拟
  IC 设计期间,最坏情形的模 拟可帮助设计师说明 PNP 和 NPN 晶体管以及基极电阻器和多晶硅电阻器的特性变化。仅是这四类器件产生的模拟条件组合就超过 16 种。为了适应温度变化,每个组合都要在 -40℃、+27℃(室温)和 +125℃ 下接受模拟,因此在模拟完成时会产生至少 48 个数据系列供分析。为了帮助 IC 设计师评估模拟波形的特性,PSpice 提供了一个由若干易用并预先定义的测量尺度组成的库,包括带宽、增益/相位余量等等。PSpice 还允许设计师利用预先定义的 YatX 和 XatNthY 测量尺度,在给定的 x 值(通常是时间)测量波形的 y 值,并找出一个对应于给定 y 值第 n 个实例的 x 值。   
[单片机]
单片机C语言教程(六)
上课所提到变量就是一种在程序执行过程中其值能不断变化的量。要在程序中使用变量必须先用标识符作为变量名,并指出所用的数据类型和存储模式,这样编译系统才能为变量分配相应的存储空间。定义一个变量的格式如下:    数据类型   变量名表  在定义格式中除了数据类型和变量名表是必要的,其它都是可选项。存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。这些存储种类的具体含义和用法,将在第七课《变量的存储》中进一步进行学习。   而这里的数据类型则是和我们在第四课中学习到的名种数据类型的定义是一样的。说明了一个变量的数据类型后,还可选择说明
[单片机]
51单片机教程之基础编(基于C语言
大家好,我是陈滨,本人是去年9月份开始学单片机,到现在一年多了,现在本人基本掌握了单片机编程,开始深入学习汇编语言了。很多初学者有很多的疑惑,我究竟是先学C语言,还是汇编语言?其实我告诉你,本人认为,先学C语言!为什么呢?C语言是目前使用最广泛的中级语言,就连现在的windows7也是C语言编写的,C语言易读性好,无需对单片机内部结构十分熟悉即会编程,可移植性高,便于维护。C语言只有32个关键字,9种控制语句,而且编译器提供了很多函数库,使用十分方便。而汇编语言达100多条指令,每条指令对应一个机器码,跟单片机内部结构息息相关,而且不提供库函数,每种东西都要自己写。汇编语言最致命的地方是它不同硬件几乎不可移植,维护麻烦。但是读者又有
[单片机]
单片机c语言教程 第一课 建立您的第一个C项目
51单片机C语言学习杂记 学习单片机实在不是件易事,一来要购买高价格的编程器,仿真器,二来要学习编程语言,还有众多种类的单片机选择真是件让人头疼的事。在众多单片机中51架构的芯片风行很久,学习资料也相对很多,是初学的较好的选择之一。51的编程语言常用的有二种,一种是汇编语言,一种是C语言。汇编语言的机器代码生成效率很高但可读性却并不强,复杂一点的程序就更是难读懂,而C语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,而且C语言还可以嵌入汇编来解决高时效性的代码编写问题。对于开发周期来说,中大型的软件编写用C语言的开发周期通常要小于汇编语言很多。综合以上C语言的优点,我在学习时选择了C语言。以后
[单片机]
单片机<font color='red'>c语言</font><font color='red'>教程</font> 第一课 建立您的第一个C项目
单片机c语言教程:建立你的第一个KeilC51项目
随着单片机技术的不断发展,以单片机C语言为主流的高级语言也不断被更多的单片机爱好者和工程师所喜爱。使用C51肯定要使用到编译器,以便把写好的C程序编译为机器码,这样单片机才能执行编写好的程序。KEIL uVISION2 是众多单片机应用开发软件中优秀的软件之一,它支持众多不一样公司的MCS51架构的芯片,它集编辑,编译,仿真等于一体,同时还支持,PLM,汇编和C语言的程序设计,它的界面和常用的微软 VC++的界面相似,界面友好,易学易用,在调试程序,软件仿真方面也有很强大的功能。本站提供的单片机c语言教程都是基于keilc51的。   下面结合8051介绍单片机C语言的优越性:   ·无须懂得单片机的具体硬件,也能够编出符合硬
[单片机]
单片机<font color='red'>c语言</font><font color='red'>教程</font>:建立你的第一个KeilC51项目
单片机C语言中的表达式语句及复合语句
1. 表达式语句 在表达式的后边加一个分号“;”就构成了表达式语句 ,如: a=++b*9; x=8;y=7; ++k; 可以一行放一个表达式形成表达式语句,也可以一行放多个表达式形成表达式语句,这时每个表达式后面都必须带“;”号,另外,还可以仅由—个分号“;”占一行形成一个表达式语句,这种语句称为空语句。 空语句在程序设计中通常用于两种情况: (1)在程序中为有关语句提供标号,用以标记程序执行的位置。例如采用下面的语句可以构成一个循环。 repeat:; : goto repeat; (2)在用while语句构成的循环语句后面加一个分号,形成一个不执行其它操作的空循环体。这种结
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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