第九章 类型及类型转换
  C/C++作为强类型语言,类型及类型转换的重要性在JAVA课中已做过介绍(JAVA也是强类型语言)。
这一章集中讲一下C/C++的类型及类型转换,内容包括:
C语言类型
C++类型
C/C++中基本的类型转换
C++对象的类型转换
类型转换函数
一、C语言类型
  C语言的基本类型以及struct等复合类型,同学们已经很熟悉了,不再赘述,下面讨论几个
课本中讲得不多的类型。
1枚举enum
  C语言提供了一种称为枚举的类型。在枚举类型的定义中列举出所有可能的取值,而且被说明为该枚举类型的变量取值不能超过定义的范围。
  枚举类型定义的一般形式为:
enum 枚举名 { 枚举值表 };
 在枚举值表中应罗列出所有可用值。这些值也称为枚举元素。
  例如:
enum weekday
{ sun,mou,tue,wed,thu,fri,sat };
  枚举元素本身由系统定义了一个表示序号的数值,从0 开始顺序定义为012…。如在weekday中,sun值为0mon值为1 …,sat值为6
枚举类型是一种基本数据类型,而不是一种复合类型, 因为它不能再分解为任何基本类型。
枚举变量的使用如下例所示: 
main(){
 enum weekday
 {
  sun,mon,tue,wed,thu,fri,sat
 } a,b,c,d;
 a=sun;  //
 b=mon; //
 c=2;          //错。枚举类型不等同于整数
d=(enum weekday)3;  //需要强制类型转换
  }
  枚举的语法不多做介绍,主要讲一下它在实际编程中怎么用:
有些可以定义为整型的变量,取值被限定在一个有限的范围内,可取的值都有一个熟知的名字。例如,一个星期内的七天,一年的十二个月等。如果把这些量说明为字符串,则对这些变量进行关系运算或算术运算不方便(比如比较大小),而说明为整型每个值又没有名字也不太方便。这时后可考虑将其定义为枚举。
使用枚举的好处是:不仅帮助程序员和用户记忆,而且使程序可靠,可以防止变量取非法取值。枚举在实际编程中非常常见,比如JAVA线程库中线程的状态(wait, start, run…,)等等就是用枚举(而不是整型或字串),还有很多C程序对设备状态、寄存器状态等往往也用枚举标识。
Q1:在什么情况下使用枚举enum类型?好处是什么?
2 寄存器变量register
  register int i;按语法的意思,是把i放到寄存器内,这比放到内存中快得多,如果i频繁使用的话,会提高效率。问题是C语言是可移值的某种程度上有跨平台的特性,不同平台编译register int i时会有不同的处理,为了防止副作用,有的C编译器可能不把i放到寄存器内。
  大多数C语言编译器都含有优化器,对常使用的局部变量等等进行优化,有时没有声明为register的变量也会放到寄存器中,所以没必要使用register int i这种可移值性不好的代码。
3 typedef
见“第四章 预处理指令”
4 共同体union
  C语言里,union可以看作是一种特殊的struct,而在C++里,structunion可以看作是特殊的类,它们可以有构造函数。无论如何,union的基本特性是:使若干变量共享一段内存。比如:
union myunion {       
int x ;char ch; float y
    }a,b      //
定义类型myunion xchy共享其中类型最宽的字节的内存。最后定义了myunion类型变量a,b
    a.x; b.ch; b.y;    //引用共同体成员   
union在实际编程中有什么用?下面例举几种用途;
1)有人认为:不同类型变量共用一段内存,类型转换时不用强制转换。的确如此,但这绝不是好的编程风格,如果只是为了类型转换方便,最好不要用union
2)有时需要操作几个固定字节数、固定地址的硬件或软件接口(比如设备I/O端口),这个接口对不同代码的访问需要呈现不同的界面(比如有时是字符串,有时是整数,有时是控制字),可以使用union让几个成员共享该界面。比如:
  union portX{     
lont int x ;  // 4字节端口,I/O整数 
char str[4] ;  //同一个4字节端口,I/O字串
char c_word[4]; //同一个4字节端口,I/O控制字
} myPort 
(3) 节约内存,在一些微小系统里,确实需要使用union节约内存,比如让多个数组共享一段内存。
  C++中,union用作类的成员变量,由于类的构造函数的问题,可能会有一些需要特殊处理的问题,略过不讲。其它有关union语法的问题也略过不讲,我们只强调该怎么用它。在一些微小系统和底层程序中,union的出镜率还是挺高的。
5 volatile
C语言关键字volatile(易变的)表示不经过赋值,其值也可能被改变(例如,表示时钟的变量、表示端口的变量等)。声明为volatile的变量会阻止编译器对其优化(有时编译器会把变量优化到我们不希望的地方),在与硬件很密切的编程中使用较多。
比如以下声明:
volatile int a;
a在运行期间不经过赋值也可能被改变。
下面例举volatile变量的几种用途;
1) 设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量
3) 多线程应用中被几个任务共享的变量
volatile还可以用来修饰常量:
volatile const int a;
这是什么意思?a不允许程序员修改,但会在程序运行过程中被系统修改,比如只读的状态寄存器。以前讲过,const真正的含义是“只读”,而不是“常数”。
  对嵌入式编程或对硬件直接编程感兴趣的同学应注意volatile
6 浮点数的判等和比较
  浮点数采用科学计数法,其值的精度不是100%精确,因此用于判等和比较时要特别小心。常用判等的方法是,两个浮点数相减的绝对值小于一个很小很小的数就认为相等。
Q2浮点数在判断是否为0时会出现什么问题?原因是什么?

二、C++类型
C++主要增加了类、泛型等类型,对struct也作了面向对象的升级。
 
1 C++classstruct
Q3C++类与结构体区别?
C++里,struct可以看作是一个特殊的类,区别在于:
class中默认的成员访问权限是private的,而struct中则是public的。从class继承默认是private继承,而从struct继承默认是public继承。 
例:
#include  <cstdlib> 
#include  <iostream> 
using  namespace  std; 
struct  ST { 
ST()  {……}  //结构体可以有构造函数和其它成员函数
    int  a;  int  b;  // 默认的成员访问权限是public             
  }; 
  //结构体成员函数实现的语法与类相同
 
  int main(int  argc, char *argv[])  { 
    ST st1( );  //定义结构体栈对象     
    ST *st2=new ST( );  //定义结构体堆对象 
……
2c语言struct用法例子.C++bool类型
  C++bool类型可取值为falsetrue,而旧式方式是0表示false,非0表示true.
三、C/C++基本的类型转换
  这一小节主要是复习性质的,大多数内容在C语言中学过。
C/C++允许在一个表达式中参与运算的操作数的数据类型不一致,即支持不同数据类型的数据之间的混合运算。在对这样的表达式求值时,C++语言需要对其中的一些操作数进行类型转换。
表达式中的类型转换有两种方式:自动转换和强制转换。
1自动转换
一般地,双目运算中的算术运算符、关系运算符、逻辑运算符和位操作运算符组成的表达
式,要求两个操作数的类型一致,如果操作数类型不一致,则自动将低类型转换为高的类型。
各种类型的高低顺序如下所示:
      double  ←←    float
                           
              long   
               
              unsigned
               
              int  ←←  char,short
 
自动转换的特点:
自动转换由编译系统自动完成。
自动转换是一种保值映射,即在转换中数据的精度不受损失。
自动类型转换相当于“类型升级”,如果原来的数是无符号数,那么在扩展的时候,高位填充的是0;如果是有符号数,那么高位填充的是符号位。
可以自动转换的类型是“类型兼容”的,它们反过来可以进型强制转换。
自动转换一般只发生在算术表达式的运算中,因此,一般类型转换都应该用强制类型转换。
2 强制转换
  分为显式强制转换和隐式强制转换。
1)显式强制转换
  有两种格式,例如:
    double f=3.55;
    int h;
    h=int (f); //第一种格式,函数风格
    h=(int)f;  //第二种格式,C风格
  这两种格式的作用一是通知编译器,二是告诉程序的阅读者这里有类型转换,有些程序员把可以自动转换的类型也写成上述两种风格之一,这是好习惯。比如:
    double f;
    int h=5;
    f=double(h);
  本来是可以自动转换的,但写成强制转换对程序的阅读者有更强的提示作用。 
(2) 隐式强制转换   

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。