C++的数据类型(《 Visual C++从入门到精通 》笔记)

目录

数值类型

字符类型

数组类型

1.一维数组

2. 二维数组

布尔类型

枚举类型

结构体类型

共用体类型

指针类型

引用类型

自定义类型


数值类型

整型类型名称字节数范围
基本整型[signed] int有符号整型4-2147483648 ~ 2147483647
unsigned [int]无符号整型40 ~ 4294967295
短整型[signed] short有符号短整型2-32768 ~ 32767
unsigned short [int]无符号短整型20~65,535
长整型signed long int有符号长整型8-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int无符号长整型80 到 18,446,744,073,709,551,615
实型float单精度型4精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字)
double双精度型8
双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字)
long double长双精度型16长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。

实数的相加
实型数据的有效数字是有限制的,如单精度float的有效数字是6~7位,如果将数字86041238.78赋值给 float类型,显示的数字可能是86041240.00,个位数8被四舍五入,小数位被忽略。如果将86041238.78与5相加,输出的结果为86041245.00,而不是86041243.78。

字符类型

类型字节数范围
char1-128 ~ 127 或 0 ~ 255
unsigned char10 ~ 255
signed char1-128 ~ 127

        在C++语言中,字符数据使用“ ' ' ”来表示,如'A'、'B'、'C'等。定义字符变量可以使用char关键字。例如:

char c= 'a'; 
char ch = 'b';

        在计算机中字符是以ASCII码的形式存储的,因此可以直接将整数赋值给字符变量。例如:

char ch=97; 
printf(%c\n",ch);

输出结果为“a”,因为97对应的ASCII码为“a”。

数组类型

        数组是指具有相同数据类型的一组元素的集合,数组中的元素是按顺序存储在内存中的。数组按维数划分,可以分为一维数组、二维数组和多维数组。

1.一维数组


在C++语言中,一维数组的定义格式如下:
数组类型   数组名称[数组长度];
例如,下面的代码定义了一个具有10个元素的整型数组:

int array[10];

在定义数组后,还需要访问数组中的元素。数组元素是通过数组名和下标来访问的。例如:

array[1] =1;

上面的代码将数组array中的第2个元素值设置为1。
        注意:这里需要注意的是,数组的下标是从0开始的。array数组共包含10个元素,下标分别为“0”、“1”、 “9”,如果出现arrav10],将会导致数组访问越界,发生意 想不到的后果,可惜的是编译器并不能识知此类错误,因此在访问数组元素时一定要谨慎,不要发生数组访问越界的情况。
在定义数组时,用户可以直接为数组赋初值。例如:

int array[10] = {0,1.2,3,4,5,6,7.8.9};

也可以只对部分元素赋初值。例如:

int array[10] = {0,1,2,3,4};

上面的代码只对array数组的前5个元素设置了初值,其他值的初值为0。注意,不能给数组提供超过了数组长度的初始值,例如下面的代码是不能通过编译的,将提示太多的初始值。

int array[10] = {0,1,2,3,4,5,6,7,8,9,10};

如果将数组元素全部初始化为0,用户可以简写为:

int array[10]= {0};

但是上述方式不能够将全部数组元素初始化为其他的值。例如,将全部数组元素初始化为1:

int array[10]= {1};

上面的代码将导致第1个数组元素的值为1,其他数组元素的值为0。
如果需要对数组全部元素进行初始化,可以省略数组长度,但是数组下标符号“[]”不能省
略。 例如: 

int array[] = {0,1,2,3,4,5,6,7,8,9};

2. 二维数组

在C++语言中,二维数组的定义格式如下:
数组类型数组名  [常量表达式][常量表达式];
例如:

int array[3][4];

二维数组元素也是通过数组名和下标来访问的。例如:

array[1][2]=10;

可以认为二维数组是一个特殊的一维数组,只是数组中的每一个元素又是一个一维数组。例如,array[3][4]可以认为是一个一维数组array[3],其中的每一个元素又是一个包含4个元素的一维数组。
在定义二维数组时也可以直接进行初始化。例如:

int array[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };

用户也可以在一个大括号内直接初始化所有的元素。例如:

int array[3][4] = { 1.2,3,4,5,6,7,8,9,10,11,12};

但是该方法并不提倡,因为如果数组元素过多,将很难界定每一个元素。

与一维数组类似,二维数组也可以只对部分元素进行初始化。例如:

int array[3][4];={ {1},{2},{3} };

结果是对每一行第1个元素赋值,其他元素为0。
对于二维数组,还可以只对某一个元素赋值、对某一行赋值。例如:

int array[3][4]; = { {1},{2,1},{3,5,8,9} };
int array[3][4];={ {1},{},{3,5,8,9} }; //略过第2行,对第3行赋值 

在定义二维数组时,如果需要提供全部元素的初始值,可以省略第一维的长度,但是不能省略第二维的长度。例如:
 

int array[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int array [][4] = {1,2,3,4,5,6,7,8,9,10,11};

布尔类型

布尔类型共有两个取值,true表示真,值为1;false表示假,值为0。

枚举类型

在开发程序时,一个对象可能会存在多个状态。例如,Oracle数据库具有关闭、打开、装载、卸载等状态。如果直接在程序中使用0表示关闭状态,1表示打开状态......会使得代码难以阅读。有些用户定义了有意义的常量来表示各个状态,但是在涉及具体函数调用时,无法限制只允许使用“0、1、2、3”。

枚举类型提供了解决上述问题的最好方法。枚举类型提供了一组常量的集合。在定义函数时,将函数参数设置为枚举类型,这样可以限制调用函数必须提供枚举类型中的某个常量,而不能随意输入一个整数。在C++语言中,可以使用enum关键字定义校举类型。定义格式如下:

enum <枚举类型名>{<常量1>,<常量2>,...<常量3>};

使用enum关键字定义一个枚举类型,例如:

enum InstanceState{CLOSE,OPEN,MOUNT,UNMOUNT};

在定义枚举类型时,可以为各个常量提供一个整数值,如果没有提供整数值,默认第1个常量值为0,第2个常量值为1,依此类推。例如上面的代码中,CLOSE常量的值为0,OPEN的值为1......
下面为枚举类型设置常量值。例如:

enum InstanceState{CLOSE=1,OPEN,MOUNT=4,UNMOUNT};

在上面的代码中,将枚举常量CLOSE设置为1,MOUNT设置为4。那么OPEN和UNMOUNT的值是多少呢?由于没有为OPEN和UNMOUNT提供常量值,他们的值应为前一个常量值加1,即OPEN和UNMOUNT的值分别为2和5。下面来演示一下枚举类型的实际应用。

【例题】应用枚举类型。   (视频从32分开始看)

结构体类型

结构体是一组变量的集合。与数组不同,结构体中的变量可以有各种类型。通常将一组密切相关的信息组合为一个结构体,以描述一个对象。例如,描述学生信息,学生包括姓名、性别、年龄、地址等信息,可以定义一个结构体来描述学生的所有信息。其中,关键字struct用于声明一个结构体类型。结构体中的变量被称为成员,如name、sex等。在声明结构体时,不要忘记末尾的分号。【例2.4】定义结构体类型:

constint MAXCHAR=128;
struct Student
{
    char name[MAX_CHAR];   //姓名 
    char sex[MAX_CHAR];    //性别 
    unsigned int age;      //年龄 
    char addr[MAX_CHAR];   //地址 
};

在声明一个结构体后,可以定义一个结构变量。在C语言中定义结构变量的语法格式如下 :

struct 结构体类型 结构体类型变量;

例如,下面的代码采用C语言的形式定义结构体变量:

struct Student stdnt;

在C++语言中定义结构体变量的格式与定义普通变量的格式相同,也可以省略前面的struct。例如:

 

Student stdnt;

当定义一个结构体变量时,编译器将为变量分配足够的空间以容纳结构体中所有的成员。在声明结构体类型时,也可以直接定义结构体变量。例如:
【例】定义结构体类型时直接定义结构体变量。

constint MAXCHAR=128;
struct Student
{
    char name[MAX_CHAR];   //姓名 
    char sex[MAX_CHAR];    //性别 
    unsigned int age;      //年龄 
    char addr[MAX_CHAR];   //地址 
}stdnt;

上述代码在声明结构体Student的同时,定义了一个结构体变量stdnt。此外,在定义结构体时,如果只需要定义一次结构体变量(在其他地方不需要定义该类型的结构体变量),可以不写结构体类型的名称,而只给出结构体变量。例如:

struct
{
    char name[MAX_CHAR];   //姓名 
    char sex[MAX_CHAR];    //性别 
    unsigned int age;      //年龄 
    char addr[MAX_CHAR];   //地址 
}stdnt;

在使用结构体时,需要访问结构体中的各个成员,可以使用“.”符号来访问结构体中的成员。 例如: 

Student stdnt;
stdnt.age=10;

两个整型变量可以相互赋值,那久两个结构体变量也可以直接赋值呢。观察如下代码:

【例题】结构体变量之间的赋值。(视频37分40秒开始)

共用体类型

共用体类型提供了一种机制,使得多个变量(共用体中的成员)可以共享同一个内存地址。下面的代码定义了一个共用体类型unType。【例2.7】定义共用体类型:

union unType
{
char cdata; 
int idata;
};

定义共用体与定义结构体类似,只是关键字不同,共用体使用union关键字。在共用体unType中,成员 cdata与idata的内存起始位置相同,如图2.3所示:

 由于共用体成员共用内存空间,因此如果改变了一个共用体成员的值,其他成员的值也会发生改变。但是,对于共用体来说,通常一次只需要使用一个成员。当定义一个共用体变量时,编译器会根据共用体成员中占用最多内存空间的变量分配空间,这样是得共用体中的所有成员能够获得足够的空间。例如,定义一个unType类型的变量tg,编译类将为其分配4个字节的空间,因为idata需要4个字节的空间,cdata只需要1个字节的空间。

注:共用体的内存空间可以用来存放数种不同类型的成员,但是在每一瞬间只有一个成员起作用,起作用的成员是最后一次存放的成员。

指针类型

在介绍指针之前,先来回顾一下变量的属性。变量具有左值和右值两个属性,即变量的地址和变量的实际数据。指针是用来存放变量的地址的,即指针的值能够存储变量的地址。直接使用变量时,就称之为“直接访问”,而通过指针获得变量地址进行使用的方式被称之为“间接访问”。这就像将一个物品放在银行的保险箱里,如果将钥匙带在身上,需要时直接打开保险箱拿东西,这就是直接访问;而为了安全起见,将保险箱的钥匙锁在家中的抽屉里,当你要拿东西时,首先要回家取得保险箱的钥匙,然后再使用钥匙打开保险箱,这就相当于用指针调用变量的地址所进行的间接访问

如果一个指针存储了变量的地址,那么通过指针就能够访问到变量的值,因为变量的值是存储在变量的地址上的。假设有变量var,指向变量var的指针为pvar,则图2.4描述了指针与变量间的关系:

 在C++中,定义指针的语法格式如下:

数据类型 *指针变量名;

例如,下面的代码定义了一个整型的指针变量:

int *pvar;

只定义一个指针变量是没有意义的,还需要为指针变量赋值。指针变量的值应该是一个有意义的地址(通常是某个变量的地址),而不是数据。如何将变量的地址赋值给指针变量呢?C++中可以使用“&”运算符获得变量的地址。下面的代码演示了通过“&”运算符获得变量地址,并将其赋值为指针变量。

int ivar =10;      //定义整型变量 
int *pi;           //定义整型指针变量
pi = &ivar;        //将其赋值为ivar的地址 
int *pvar =&ivar;  //定义整型指针变量,将其初始化为ivar的地址 

当指针被赋予一个有效的变量地址后,如何通过指针访问或修改变量的数据呢?在指针变量前使用“*” 运算符,即可直接访问变量的数据。【例题】使用“*”运算符访问指针数据:

void main()
{
    int ivar =10;                 //定义整型变量
    int *pvar = &ivar;            //定义整型指针变量,将其初始化为ivar的地址
    *pvar = 8;                    //修改指针变量指向地址上的值
    printf(“ivar = %d\n",ivar);   //输出变量值,输出8
    printf("pvar = %d\n",*pvar);   //输出指针变量值,输出8
}

分析上述代码,首先定义了一个整型变量ivar,将其初始化为10;然后定义一个指针变量pvar,将其初始化为ivar的地址;接着修改指针变量指向的地址上的数据;最后输出变量ivar的值和指针变量pvar的值。变量ivar的值为8,通过指针变量修改了ivar的值。

指针变量不仅可以指向简单的变量,还可以指向数组变量。例如:

int iarray[5] = {1,2,3,45};    //定义一个整型数组
int* pvar=&iarray[0];          //定义一个整型指针变量,将其指向数组中的第1个元素

在上面的代码中,&iarray[0]表示获取数组中第1个元素的地址,即数组的首地址。对于数组来说,数组名同样表述数组的首地址,因此下面的代码与上述两行代码是完全相同的。

int iarray[5] = {1,2,3,4.5};    //定义一个整型数组
int* pvar=iarray;               //定义一个整型指针变量,将其指向数组中的第1个元素 

下图描述了当前指针变量pvar与数组iarray之间的关系:

当一个指针变量指向一个数组后,通过指针变量即可访问该数组中的每一个元素。例如,下面的代码利用指针输出数组中的每一个元素:

void main()
{
    int iarray[5] = {1,2,3,4,5};     //定义一个数组,并进行初始化 
    int* pvar = iarray;              //定义一个指针变量,将其指向数组首地址 
    for(int i=0; i<5;i++)            //循环语句,用于遍历数组元素
    { 
        printf{"数组元素[%d] = %d\n",i,*pvar); //利用指针变量输出数组元素 
        pvar= pvar + 1;              //移动指针,使其指向下一个元素 
    }
}

在上述代码中,注意“pvar = pvar + 1”语句,该语句的作用是使指针指向数组中的下一个元素,而不是简单地将指针地址加1或指针值加1。语句“pvar = pvar + 1”是移动指pvar指向的地址,移动量不是1个字,而是1个数组元素的大小,更准应该是指针pvar的类型(这里为int类型)的大小。

在开发程序时,如果需要使用一组指针,可以定义一个指针数组。例如,下面的代码定义了一个整型的指针数组:

int *parray[5];

对于指针数组来说,数组中的每一个变量均是一个指针变量。下面的代码演示了指针数组的应用。

void main()
{
    int *parray[5];             //定义一个指针数组
    int iarray[5] ={9,8,7,6.5}; //定义一个整型数组 
    for(int i=0;i<5;i++)        //for循环 
    {
        parray[i] = & iarray[i]; //为指针数组中的元素赋值 
        printf(“数组元素[%d] = %d\n",i,*parray[i]); //输出指针数组元素中的数据值
    }
}

在定义指针时,也可以使用const关键字。例如:

int ivar = 10;           //定义一个整型变量 
const int *pvar = &ivar; //定义一个整型常量的指针,并进行初始化 

对于指针pvar来说,用户不能够修改pvar指向的值,但是可以修改pvar指向的地址。例如:

int ivar =10;             //定义一个整型变量 
const int *pvar = &ivar;  //定义一个指针常量,对其进行初始化 
//*pvar = 20;             //错误的代码,不能修改指针常量的数据 
int inum =5;              //再次定义一个整型变量 
pvar = &inum;             //修改指针常量指向的地址

在使用const关键字定义指针时,也可以将const关键字放置在指针变量的前面,但是指针变量的性质发生了改变。观察如下代码:

int ivar =10;
int * const pvar = &ivar;    //定义一个指向整型的常量指针
*pvar = 20;                  //修改指针指向的数据 
int inum = 5;                //定义一个整型变量 
//pvar = &inum;              //错误的代码,不能够修改常量指针指向的地址

上面的代码定义了一个常量指针pvar,使用户不能够修改pvar指向的地址,但是可以修改pvar指向的数据。

在定义指针时也可以同时使用两个const关键字。例如:

int ivar =10; //定义一个整型变量 
const int * const pvar =&ivar; //定义一个常量指针常量 

在上面的代码中,用户既不能够修改pvar指向的地址,也不能够修改pvar指向的数据。例如:

//*pvar =20; //非法的代码,不能够修改pvar指向的数据 
int inum =5; //定义一个整型变量 
//pvar = &inum; /非法的代码,不能够修改pvar指向的地址

引用类型

引用可以认为是一个“别名”,即目标的代名词。当定义一个引用时,需要为其指定一个对象,即目标。此时,引用就成了目标的代名词,操作引用与操作实际的目标对象是相同的。定义引用的格式如下:

数据类型 &引用名称 = 目标对象;

在定义引用对象后,即可使用引用对象操作目标对象。下面是使用引用对象代替目标对象的代码:

void main()
{
    int ivar = 10;     //定义一个整型变量 
    int &rvar = ivar;  //定义一个引用对象 
    rvar =5;           //设置引用对象数据 
    printf("ivar =%d n",ivar); //输出变量ivar,值为5
    printf("rvar =%d n",rvar); //输出变量rvar,值为5
}

执行上述代码,可以发现,通过设置引用变量的值,修改了变量ivar的值。

在程序中如果对引用对象进行取地址,返回的将是目标的地址,因为引用是目标的代名词。观察如下代码:

void main()
{
    int ivar = 10;     //定义一个整型变量 
    int arvar= ivar;   //定义一个引用对象 
    printf("ivar的地址 = %d\n",&ivar); //输出整型变量的地址 
    printf("rvar的地址 = %d\n",&rvar); //输出“引用对象”的地址 
}

自定义类型

在C++语言中,用户可以使用typedef关键字自定义数据类型。自定义数据类型并不是真的创建新的数据类型,而是为已存在的数据类型定义一个新的名称。自定义类型的语法格式如下: 

 typedef 数据类型 新的名称;

例如,下面的代码定义了一个UINT数据类型:

typedef unsigned int UINT;

当定义完新的数据类型后,就可以像定义普通数据类型变量一样定义新数据类型的变量。例如,下面的代码定义了一个UINT类型的变量:

UINT ivar=10;

在程序中使用自定义类型的好处是能够提高程序的移植性。同一种数据类型,在不同机器或不同操作系统上,其长度或性质可能是不同的。如果程序中统一使用了自定义类型,在修改程序时,只需要修改自定义类型的基类型即可,代码的其他地方不需要改动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值