蓝桥杯之单片机设计与开发(11)——单片机C语言小结

今天闲着无聊把书翻看一遍,收获颇丰。

目录

1、数据类型

基本类型数据长度

强制类型转换

bit强制类型转换

2、变量类型

局部变量

全局变量

变量的存储类别


1、数据类型

C语言的数据基本类型分为:字符型、整型、长整型以及浮点型。

  • 字符型、整型和长整型只能表示整数
  • unsigned型只能表达非负整数
  • signed型可以表达负整数
  • 浮点型表达小数

基本类型数据长度

字符型 unsigned char 0 ~ 255
  signed char -128 ~ 127
整型 unsigned int 0 ~ 65535
  signed int -32768 ~ 32767
长整型 unsigned long 0 ~ 4294967295
  signed long -2147483648 ~ 2147483647
浮点型 float -3.4 × e38 ~ 3.4 × e38
  double C51中等于float


在C语言中,不同的数据类型之间是可以混着运算的。当表达式中的数据类型不一致是,首先转换为同一种类型,然后再进行计算。转换原则是:短字节的数据向长字节数据转换。

如下面代码:

unsigned char a;
unsigned int b;
unsigned long c;
c = a * b;

在运算的过程中,程序会自动全部按照unsigned int 型来计算。

比如 a = 10, b = 200, c 的结果就是2000.

那当a = 100, b = 700,时,c为多少?

所以一定要注意每个变量类型的取值范围,c的数据类型是unsigned int型,取值范围为0 ~ 65535,而70000超出了范围,其结果就会溢出,最终c的结果就是(70000 - 65535) = 4464.

那么,如果想让c正常获得70000这个结果,需要把c定义为unsigned long型变量。

unsigned char a = 100;
unsigned int b = 700;
unsigned long c = 0;
c = a * b;

此时c的结果是多少?

答案是:c = 4464

WHY???

因为C语言在不同类型运算时,数值会转换为同一类型运算,但是每一步运算都会进行识别判断,不会进行一个总的分析判断。

比如这段代码中,a和b相乘时,是按照unsigned int类型运算的,所以运算结果也就是unsigned int类型的4464,只是把最终的unsigned int型4464赋值给了unsigned long型的变量c而已。

为避免这种情况,我们可以采用强制类型转换的方法。

强制类型转换

在一个变量的前边加上一个数据类型名,并且使用小括号括起来,就表示把这个变量强制转换为括号里的类型。

比如

c = (unsigned long)a * b;

根据符号运算优先级,首先把a强制转换为unsigned long型变量,然后与b相乘,根据C语言运算规则,b就会自动转换成一个unsigned long型的变量,而后运算完毕的结果也是一个unsigned long型的,最终赋值给c。

不同类型变量之间的相互赋值,短字节类型变量向长字节类型变量赋值时,其值保持不变。如

unsigned char a = 100;
unsigned int b = 700;
b = a;

此时程序的最终结果就是b = 100.

但如果是

unsigned char a = 100;
unsigned int b = 700;
a = b;

那么a的值仅仅是取了b的低8位,首先把700变成一个16位的二进制数据,然后取它的低八位出来,也就是188,所以最终结果就是a = 188。这就是长字节数据类型给短字节数据类型赋值的结果,会从长字节类型变量的低位开始截取正好等于短字节类型长度的位,然后赋值给短字节类型。

bit强制类型转换

但是在51单片机中,有一个例外就是bit类型的强制转换。

bit a = 0;
unsigned char b;
a = (bit)b;

在这里,使用bit作强制类型转换,不是取b的最低位,而是判断b是不是0,如果b是0,那么a的结果就是0;如果b是任意非0的其他值,那么a的结果都是1。

2、变量类型

局部变量

在一个函数内部声明的变量就是局部变量,它只在本函数内有效,在本函数之外是不能使用的。

函数的形参也是局部变量。

全局变量

在函数外声明的变量就是全局变量。其作用域就是从它开始声明的位置一直到程序结束。

全局变量可以被其作用域内的所有函数使用。

一般来说,一个程序文件内的所有全局变量都在文件的开头部分定义,在所有函数之前。

全局函数优缺点:

由于C语言函数只有一个返回值。但是却经常会希望一个函数可以提供或影响多个结果值,这时就可以利用全局变量来实现。但是考虑到全局变量的此特征,应该限制全局变量的使用,过多使用全局变量也会带来一些问题。

(1)全局变量可以被作用域内所有的函数直接引用,可以增加函数间数据联系的途径,但同时加强了函数模块之间的数据联系,使这些函数的独立性降低。对其中任何一个函数的修改都可能会影响到其他函数的执行结果,函数之间过于紧密的联系不利于程序的维护。

(2) 全局变量的应用会降低函数的通用性。函数在执行的时候过多依赖于全局变量,不利于函数的重复利用。目前编写的程序还都比较简单,就一个c文件,但以后要学到一个程序中有多个.c文件,当一个函数被另外一个.c文件调用的时候,必须将这个全局变量的变量值一起移植 。而全局变量不只被一个函数调用,这样会引起些不可预见的后果。

(3) 过多使用全局变量会降低程序的清晰度,使程序的可读性下降。在各个函数执行的时候都可能改变全局变量值,往往难以清楚地判断出每个时刻各个全局变量的值。

(4)定义全局变量会永久占用单片机的内存单元,而局部变量只有进入定义局部变量的函数时才会占用内存单元,函数退出后会自动释放所占用的内存。所以大量的全局变量会额外增加内存消耗。

综上所述,在编程规范上有一条原则,就是尽量减少全局变量的使用。能用局部变量代替的就不用全局变量。

还有一种特殊情况,大家在看程序的时候请注意,C语言是允许局部变量和全局变量同名的,它们定义后在内存中占有不同的内存单元。如果在同源文件中全局变量和局部变量同名,在局部变量作用域范围内,只有局部变量最有效,全局变量不起作用,也就是说局部变量是具有更高的优先级。但是从编程规范上讲,是要避免全局变量与局部变量重名的,从而避免不必要的误解和误操作。

变量的存储类别

变量的存储类别分为自动、静态、寄存器和外部四种。

动态变量

函数中的局部变量,如果不加static这个关键字来修饰都属于自动变量也叫作动态存储变量。这种存储类别的变量,在调用该函数的时候系统会给它们分配存储空间,在函数调用结束后会自动释放这些存储空间。动态存储变量的关键字是auto,但是这个关键字一般可以省略,所以平时不用。

静态变量

全局变量都是静态变量。

另外的在定义局部变量时前边加上static这个关键字修饰,这个变量就称为静态局部变量。它的特点就是在整个生存期只赋一次初值,在第一次执行该函数时,它的值就是给定的那个初值,而之后在该函数的所有执行次数中,它的值都是上一次函数执行结束后的值,即它可以保持前一次的执行结果。

 

 

 

 

 

 

 

你可能感兴趣的:(蓝桥杯,第十届蓝桥杯)