文章目录
四、数据类型
(1)整型
C++中能够表示整型的类型有如下几种,区别在于所占用内存空间不同。
数据类型 | 所占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | ( − 2 15 ∼ 2 15 − 1 ) (-2^{15}\sim{2^{15}-1}) (−215∼215−1) |
int(整型) | 4字节 | ( − 2 31 ∼ 2 31 − 1 ) (-2^{31}\sim{2^{31}-1}) (−231∼231−1) |
long(长整型) | 4字节(32位),8字节(64位) | ( − 2 31 ∼ 2 31 − 1 ) (-2^{31}\sim{2^{31}-1}) (−231∼231−1) |
long long(长长整型) | 8字节 | ( − 2 63 ∼ 2 63 − 1 ) (-2^{63}\sim{2^{63}-1}) (−263∼263−1) |
关键字sizeof
可以用于计算变量所占的字节数。
C++能够以三种不同的基数来书写整数,十六进制hex
、八进制octal
、十进制decimal
。输入写方式如下:
int a = 0xff; //十六进制采用0x或0X打头,并且后面的数字在0~f取值,a~f可以大写成A~F
int b = 0XFF;
int c = 077; //八进制采用0单独打头,并且后面的数字在0~7取值
int d = 99; //十进制,无需打头,并且后面的数字在0~9取值
整型后缀:后缀是放在数字常量后面的字母,用于表示类型。整数后面的l
或L
表示该整数为long
常量,u
或U
表示unsigned int
常量,ul
(可以采用任何一种顺序,大写小写均可)表示unsigned long
常量。
long a = 50l; //指定为long常量
unsigned int b = 50u; //指定为unsigned int常量
unsigned long c = 50ul; //指定为unsigned long常量
(2)浮点型(实型)
数据类型 | 所占用空间 | 有效数字范围 |
---|---|---|
float | 4字节 | 7位有效数字 |
double | 8字节 | 15~16位有效数字 |
long double | 8字节 |
浮点型后缀:在使用浮点数据类型的时候,编译器默认小数为双精度double
类型,但是我们可以在小数的后面添加f
或F
来指明使用单精度类型的小数。对于long double
类型可以使用l
或L
后缀。例如:
float f1 = 3.14F; //默认小数为双精度
float f2 = 3.14f; //显示指明小数为单精度
double f3 = 3.14; //小数默认为双精度,这里本身创建双精度变量可以不修改
long double f4 = 3.14L; //创建long double类型
使用科学计数法表示浮点数,e
或E
表示科学计数法的10
,幂可以为正也可以为负。例如:
float f1 = 3e2; //科学计数法表示300
float f2 = 3E-1; //科学计数法表示0.3
(3)字符型
数据类型 | 所占用空间 | 取值范围 |
---|---|---|
char | 1字节 | ( − 128 ∼ 127 ) (-128\sim{127}) (−128∼127) |
单字符字面量用''
单引号来表示,字符串字面量用""
双引号来表示。
转义字符
宽字符类型wchar_t
,可以表示拓展字符集,可以在字符常量前面加上前缀L
来指示宽字符常量和宽字符串。iostream
头文件中提供了处理wchar_t
类型的类似工具wcout
和wcin
,例如:
wchar_t bob = L'F'; //定义一个宽字符类型常量
wcout << L"tall" << endl; //输出宽字符串
(4)字符串
C语言中单字符字面量存储在char类型中,但是C语言没有专门用于存储字符串的数据格式,通常使用char的数组来存储字符串,单字符字面量用''
单引号来表示,字符串字面量用""
双引号来表示,C风格的字符串具有一种特殊的性质:以空字符(null character)结尾,空字符被写作\0
,其ASCII码值为0
,用于标记字符串的结尾。
在C++中加入了字符串类型string
,使用前需要先包含头文件#include <string>
,string
类位于名称空间std
中,因此必须包含一条using
编译指令,或者使用std::string
来引用它。string
类定义隐藏了字符串的数组性质,让我们能够像处理普通字符一样处理字符串。
因此,在C++中有两种风格的字符串,一种是延续了C语言风格的字符串,另一种是C++风格的字符串。
C风格的字符串:char 变量名[] = "字符串值"
char my_str[] = "Hello World!";
C++风格的字符串:string 变量名 = "字符串值"
#include <string> //使用字符串类型需要先包含头文件
string my_str = "Hello World!";
从理论上来说,可以将char
数组视为一组用于存储一个字符串的char
存储单元,而string
类变量是一个表示字符串的实体,可以像使用char
数组一样来使用string
对象。
在C++中允许拼接字符串字面量,即将两个引号括起来的字符串合并为一个。实际上,任何两个由空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。例如:
cout << "I'd like to study C++"
" and Python!"; //这两句的效果是一致的
cout << "I'd like to study C++ and Python";
string
实体的赋值、拼接操作:对于数组来说是不能将一个数组直接赋值给另一个数组的,但是我们可以将一个string
对象赋值给另一个string
对象:
char charr1[20];
char charr2[20] {"jaguart"};
string str1;
string str2 {"panther"};
charr1 = charr2; //非法操作,数组不能赋值
str1 = str2; //合法操作,string对象可以赋值
string
类还简化了字符串的合并操作。可以使用+
运算符将两个string
对象合并起来,还可以使用+=
运算符将字符串附加到string
对象的末尾。(与Python类似)例如:
string str1 {"Hello"};
string str2 {" World!"};
string str3;
str3 = str1 + str2; //str3为"Hello World!"
str1 += " Ok!" //str1为"Hello Ok!"
对传统的C数组进行拷贝和拼接,需要采用cstring
头文件中的strcpy
和strcat
函数,使用这种方式,需要时刻注意不能超过数组的容量,否则会出错。例如:
char charr1[20];
char charr2[20] {"Hello "};
strcpy(charr1, charr2); //将charr2拷贝给charr1
strcat(charr1, " World!"); //将" World!"拼接到charr1后
C++新增原始(Raw)字符串,在原始字符串中转义字符不再转义将表示本身,原始字符串使用"(
和")
作为界定符,并且使用前缀R
来标识原始字符。
string str = R"(Hello \nWorld!)"; //需要"(和)"成对出现
字符串的比较:对于C风格的字符串,应该使用cstring
头文件中的strcmp()
函数来进行字符串的比较,详见C语言。对于C++风格的字符串,可以使用关系运算符来进行比较,这是因为重载了这些关系运算符。举个例子:
#include <iostream>
#include <string>
#include <cstring>
int main(void)
{
using namespace std;
string word = "?ate";
for (char ch = 'a'; word!= "mate"; ch++) //比较字符串是否为"mate"
//for (char ch = 'a'; strcmp(word, "mate"); ch++)
{
cout << word << endl;
word[0] = ch;
}
cout << "After loop ends, word is " << word << endl;
return 0;
}
(5)布尔型
数据类型 | 所占字节大小 | 取值范围 |
---|---|---|
bool | 1字节 | 0或1 |
布尔型数据类型代表真或假,true
是真,本质是1
;false
是假,本质是0
。C++将非零值解释为true
将零值解释为false
。
bool flag = true; //布尔变量设置为真
(6)大括号初始化器
C++除了基于C语言的初始化方式:直接使用=
进行赋值外,例如:
int a = 2; //基本的初始化方式
还具有大括号初始化器{}
,这种方式不仅仅可以用于数组和结构体,还能够给单值变量进行初始化,并且采用这种方式能够省略等号=
,当大括号{}
中不包含任何元素时,初始化为0
,例如:
int a = {2}; //大括号初始化器
int b{3}; //省略=的大括号初始化器
int c{}; //初始化为0
C++将大括号初始化器作为一种通用的初始化方式,可用于所有类型,同样这种方式可以适用于数组,并且可以省略=
,其次,可以不在大括号中包含任何东西,此时将数组全部初始化为0
,例如:
float balances[100] {}; //将数组全部初始化为0;
unsigned int counts[10] {1, 2, 3, 4, 5}; //只初始化数组前5个元素,后5个元素默认为0
char first_date[] = {"Le Chapon Dodu"}; //初始化一个字符串数组
string second_date {"The Elegant Plate"}; //初始化一个string实体
同样的,大括号初始化器也能够适用于结构体变量,例如:
struct infalable {
char name[20];
float volume;
double price;
};
struct inflatable guest = {
"Glorious Gloria",
1.88,
29.99
}; //C语言的初始化方式
inflatable pal {
"Audacious Arthur",
3.12,
32.99
}; //C++的大括号初始化方式,省略了=,并且C++在声明结构体变量时可以省略struct关键字
infaltable mayor {}; //C++初始化器的大括号中不含任何东西,则被初始化为0
(7)强制类型转换
C++中的强制类型转换相对于C语言来说有两种写法:
(typename) value; //第一种,这种语法和C语言一致
typename (value); //第二种,这种语法是C++特有的
第一种格式来源于C语言,第二种格式是存粹的C++风格。新格式的思想是,让强制类型转换就像是函数调用。这样对内置类型的强制类型转换就像为用户定义的类设计的类型转换。
(8)结构体struct
结构体是C++的OOP基础,结构体是用户定义的类型,而结构声明定义了这种类型的数据熟悉,定义了类型后,便可以创建这种类型的变量。C++的结构体基本和C语言一致,只有一点差异:C++允许在创建结构体变量时省略关键字struct
(而在C语言中想这样做,则必须使用typedef
关键字)。
结构体的声明,结构体的声明和定义结构体变量可以组合成一个步骤。
struct tag
{
member-list;
} variable-list;
在声明结构体之后,可以创建结构体变量:
struct tag sub; //C语言只能这样做
tag sub; //C++允许这样做,省略struct关键字
C++中的结构体支持成员赋值,即将一个同类型的结构体通过赋值运算符=
赋值给另外一个结构体。例如:
struct inflatable {
char name[20];
float volume;
double price;
};
inflatable bouquet {
"sunflowers",
0.20,
12.49
};
inflatable choice;
choice = bouquet; //成员赋值
(9)共用体union
与C语言一致
(10)枚举enum
与C语言一致
(11)数组与容器类
C++的数组基本和C语言一致,这里不详细介绍。关于容器类,模板类vector
是动态数组的替代品,模板类array
是定长数组的替代品。
模板类vector
模板类vector
似于string
类,是一种动态数组。首先要使用模板类vector
,必须要包含头文件vector
;其次,vector
包含在名称空间std
中,因此可以使用std::vector
或者使用using
编译指令。
使用模板类vector
创建对象,通用写法:
#include <vector>
using namespace std;
vector <typeName> vt(n_elem); //创建类型为typeName长度为n_elem的向量,n_elem可以为整型常量或整型变量
模板类array
模板类array
的用法也类似,必须要包含头文件array
;其次,array
包含在名称空间std
中,因此可以使用std::array
或者使用using
编译指令。
使用模板类array
创建对象,通用写法:
#include <array>
using namespace std;
array <typeName, n_elem> arr; //创建类型为typeName长度为n_elem的数组,n_elem不能是变量
函数与array
对象,关于array
对象,其类型是array <typeName, n_elem>
,因此必须在函数原型中指明这种类型。例如:
#include <array>
std::array <double, 4> expenses; //创建了一个array对象,类型是 std::array <double, 4>
void show(std::array <double, 4> da); //声明处理这个array对象的函数原型