02. C++和数据
一、标识符
1.1、什么是标识符
标识符(identifier)是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在计算机编程语言中,标识符是用户编程时使用的名字,用来给变量、常量、函数、类等命名,以建立起名字与使用之间的关系。标识符通常由字母和数字以及其它字符构成。
1.2、标识符的命名规则
- 标识符只能由数字、字母(26个英文字母大小写)、下划线(_)组成;
- 标识符不能以数字开头;
- 不可以使用关键字作为标识符,但可以包含关键字;
- 标识符严格区分大小写;
- 不能用连续两个下划线开头,也不能以下划线加大写字母开头,这些被 C++ 保留给标准库使用;
int main(void)
{
int useId = 1;
int age = 10;
int minNum = 3;
int max_num = 30;
return 0;
}
标识符的命名建议见名知意;
二、常量
2.1、什么是常量
常量 指的是在计算机程序运行时,不会被程序修改的量;在 C++ 中,常量主要分为以下几种类型:
- 字面常量
- 整型常量,可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀默认表示 十进制。整型常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数,L 表示长整数,后缀可以大写也可以小写,U 和 L 的顺序任意。例如:100,200,-100,0,037,0x5A
- 浮点型常量,由整数部分、小数点、小数部分 和 指数部分 组成,可以使用小数形式或者指数形式来表示浮点型常量。例如:3.14,0.125,-3.14,314159E-5
- 字符型常量,是括在单引号中的单个字符。字符常量可以是一个普通的字符,也可以是一个转义字符。例如:'a','A','\n'
- 字符串常量,是括在双引号中的字符序列。在字符串常量中,我们可以使用 '\' 实现换行。 例如:"hello","a","123"
- 布尔常量,用来表示真假的值,例如:true 和 false
const
修饰的常变量,本质上是变量,但是不能直接修改,有常量的属性#define
定义的标识符常量- 枚举常量
2.2、字面常量
【1】、整型字面常量
在 C++ 中,一个整型字面量,默认就是 int 类型,前提是数值在 int 能表示的范围内。如果超出 int 范围,那么就需要能够表示这个数的长度最小的那个类型。具体来说,对于十进制整型字面值,如果 int 不够那么选择 long,如果还不够,就选择 long long(不考虑无符号类型)。而八进制和十六进制字面值,则会优先选择无符号 unsigned int,如果不够的话,则选择 long,之后依次是 unsigned long、long long 和 unsigned long long。
如果要以十六进制或八进制方式显示值,则可以使用头文件 iostream 提供控制符 dec、hex 和 oct 分别只用 cout 以十进制、十六进制和八进制格式显示数值。默认格式为十进制,在修改格式之前,原来的格式将一直有效。
#include <iostream>
using namespace std;
int main(void)
{
// 整型字面量
int i1 = 100;
int i2 = -100;
int i3 = 037;
int i4 = 0x5A;
cout << i1 << endl;
cout << i2 << endl;
cout << oct << i3 << endl;
cout << hex << i4 << endl;
return 0;
}
【2】、浮点型字面常量
#include <iostream>
using namespace std;
int main(void)
{
// 浮点型字面量
double d1 = 3.14;
double d2 = -3.14;
double d3 = 314159E-5;
float f1 = 3.14f;
cout << d1 << endl;
cout << d2 << endl;
cout << d3 << endl;
cout << f1 << endl;
return 0;
}
【3】、字符型字面常量
#include <iostream>
using namespace std;
int main(void)
{
// 字符字面量
char c1 = 'a';
char c2 = 'A';
char c3 = '\n';
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
return 0;
}
【4】、字符串字面常量
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
// 字符串字面量
char str1[] = "hello";
char str2[] = "a";
string str3 = "123";
string str4 = "hello world";
string str5 = "hello \
world";
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
cout << str4 << endl;
cout << str5 << endl;
return 0;
}
【5】、布尔字面量
#include <iostream>
using namespace std;
int main(void)
{
// 字符串字面量
bool b1 = true;
bool b2 = false;
cout << b1 << endl;
cout << b2 << endl;
return 0;
}
2.3、const修饰的常变量
#include <iostream>
using namespace std;
int main(void)
{
// 使用const关键字定义常量
const double pi = 3.14;
// 常量赋值之后,不能更改
//pi = 3.1415926;
cout << pi << endl;
return 0;
}
2.4、define定义的标识符常量
#include <iostream>
// 宏定义常量
#define PI 3.1415926
using namespace std;
int main(void)
{
// 标识符常量不能改变
// PI = 3.14;
cout << PI << endl;
return 0;
}
2.5、枚举常量
#include <iostream>
/* 枚举常量 */
enum Color
{
RED,
GREEN,
BLUE
};
using namespace std;
int main(void)
{
enum Color color = BLUE;
cout << color << endl;
return 0;
}
2.6、const和define定义常量的区别
- const 定义的常量带类型,define 不带类型;
- const 是在编译、运行的时候起作用,而 define 是在编译的预处理阶段起作用的;
- define 只是简单的替换,没有类型检查;
- const 常量可以进行调试的,而 define 是不能进行调试的,主要是因为在预编译阶段 define 定义的常量就已经替换掉了,调试的时候没有了;
- const 不能重定义,不可以定义两个一样的,而 define 通过 undef 可以取消某个符号的定义,在重新定义;
- define 可以配合 #indef、#ifndef、#endif 来使用,可以让代码更加灵活;
#include <iostream>
#define A 1
#define B A+3
#define C A/B*3
using namespace std;
int main(void)
{
// C其实是A/A+3*3
cout << C << endl;
return 0;
}
三、变量
3.1、变量的概念
变量就是在程序的执行过程中,其值可能发生改变的量(数据);变量是内存中的一个存储区域(不同的数据类型,占用的空间大小也不一样),该区域的数据可以在同一类型范围内不断的改变,变量是程序中最基本的存储单元,包含 变量类型、变量名 和 存储的值。
3.2、变量的作用
变量的作用就是在内存中保存数据;我们可以使用变量名来访问这块区域的数据;
3.3、变量的定义
变量的定义:
[存储类型] 数据类型 变量名;
int a;
- 变量的 存储类型 可以是 auto、register、static 和 extern;
- auto 说明变量只能再某个程序范围内使用,通常再函数体内或函数中的复合语句里。(默认是随机值)。在函数体的某段程序内说明 auto 存储类型的变量可以省略关键字 auto。
- register 称为寄存器型,register 变量是想将变量放入 CPU 的寄存器中,这样可以加快程序的运行速度。如果申请不到就使用一般内存,同 auto。
- static 变量称为静态存储类型的变量,既可以在函数体内,也可在函数体外声明。(默认是 0)。
- extern 称为外部参照引用型,使用 extern 说明的变量可以被其它文件中的函数所引用。
- 变量的 数据类型 可以是基本数据类型,也可以是自定义的数据类型
register 变量必须是能被 CPU 所接受的类型。这通常意味着 register 变量必须是一个单个的值,并且长度应该小于或等于整型的长度。
我们不能使用 & 来获取 register 变量的地址;
3.4、变量的赋值
变量的赋值:
变量名 = 变量值;
a = 10;
变量可以在声明的同时赋值:
数据类型 变量名 = 变量值;
int a = 10;
- 数据类型:为空间中存储的数据,加入类型(限制)
- 变量名:为空间起的名字
- 数据值:存在空间里面的数值
#include <iostream>
using namespace std;
int main(void)
{
// 定义变量
// 数据类型 变量名 = 数据值;
int a = 10,b = 20;
cout << "a = " << a << ", b = " << b << endl;
return 0;
}
在 C语言 中每个变量必须 先声明,再初始化,后使用;
在同一个作用域中,变量名不能重复声明,但变量可以重新赋值;
一行上可以同时声明多个变量,使用“,”隔开;
3.5、变量的作用域和生命周期
所谓的变量的作用域就是变量的有效范围;变量的作用域为其定义所在的一对{}内,即出了大括号就不认识了;
局部变量的作用域
:是变量所在的局部范围;全局变量的作用域
:是整个工程;
变量的生命周期指的是变量的创建到变量销毁之间的一个时间段。
局部变量的生命周期
:进入局部范围生命开始,出局部范围生命结束;全局变量的生命周期
:整个程序的生命周期;
3.6、变量的分类
3.6.1、按数据类型分类
3.6.2、按变量定义位置分类
在一个函数内部定义的变量,只在本函数范围内有效。在复合语句内定义的变量,只在本复合语句范围内有效;
函数的形参也属于局部变量,作用范围仅限于函数内部的所有语句块;
如果一个变量在所有函数外部定义,那么这个变量就是全局变量。全局变量是可以在程序中的任何位置进行访问的变量;
当局部变量和全局变量名字冲突的情况下,局部优先。
四、数据类型
4.1、基本数据类型
在 C++ 中,用 int 关键字来表示 基本的整数类型。long、short 、unsigned 和 signed 用于提供基本整数类型的变式,例如 unsigned short int 和 long long int。char 关键字用于指定 字母 和 其它字符(如,#、$、%等)。另外,char 类型也可以表示较小的整数。float、double 和 long double 表示 带小数的数。 bool 类型表示布尔值(true 或 false),_Complex 和 _Imaginary 分别表示 复数 和 虚数。
4.1.1、整型类型
整形用于表示没有小数部分的数值,允许是负数。计算机以二进制数字存储整数。C++ 中提供了以下几个类型:short、int、long、long long;C++ 的整型常量默认是 int 型,如果要显示地声明 long 型常量需后加 'l' 或 'L' ,声明 long long 型常量需后加 'll' 或 'LL'。
数据类型 | 占用空间 |
---|---|
[signed] short [int](有符号短整型) | 2 字节,取值范围:-32768~32767 |
unsigned short [int](无符号短整型) | 2 字节,取值范围:0~65535 |
[signed] int(有符号整型) | 通常 4 字节,取值范围:-2147483648~-2147483647 |
unsigned int(无符号整型) | 通常 4 字节,取值范围:0~4294967295 |
[signed] long [int](长整型) | 4 字节(32位)或 8 字节(64位) |
unsigned long [int](无符号长整型) | 4 字节(32位)或 8 字节(64位) |
[signed] long long [int](长长整型) | 8 字节 |
unsigned long long [int](无符号长长整型) | 8 字节 |
#include <iostream>
using namespace std;
int main(void)
{
short int s = 10; // int可以省略
int i = 10; // int可以省略
long int l = 10; // int可以省略
long long int ll = 10; // int可以省略
signed int a = -10; // 定义一个有符号整数,signed可以省略
unsigned int b = 10; // 定义一个无符号整数
cout << s << endl;
cout << i << endl;
cout << l << endl;
cout << ll << endl;
cout << a << endl;
cout << b << endl;
return 0;
}
我们可以使用 sizeof 关键字来计算数据类型在内存中占用的字节(byte)大小,它的语法格式如下:sizeof(数据类型)
或 sizeof(变量名)
。
#include <iostream>
using namespace std;
int main(void)
{
// sizeof计算数据类型在内存中占用的字节大小
// 语法格式:sizeof(数据类型) 或 sizeof(变量名)
cout << "short: " << sizeof(short) << endl;
cout << "int: " << sizeof(int) << endl;
cout << "long: " << sizeof(long) << endl;
cout << "long long: " << sizeof(long long) << endl;
return 0;
}
整型的数据在内存中占的字节数与所选择的操作系统有关。虽然 C++ 标准中没有明确规定整型数据的长度,但 long long 类型整数的长度不能短于 long 类型,并且 long long 至少 8 个字节,long 类型整数的长度不能短于 int 类型,并且 long 至少 4 个字节,short 类型整数的长度不能长于 int 类型,并且 short 至少为 2 个字节,即 short <= int <= long < long long
。
通常,int 被设置为目标计算机而言最为 “自然” 的长度。自然长度指的是计算机处理起来效率最高的长度。如果没有非常有说服力的理由来选择其它类型,则应该使用 int 类型。如果变量的值不可能为负,则可以使用无符号类型,这样变量可以表示更大的数。如果知道变量可能表示的整数值大于 16 位整数的最大可能值,则推荐使用 long 类型。如果要存储的值超过 20 亿,推荐使用 long long 类型。由于 short 比 int 小,使用 short 可以节省内存。通常仅当有大型整型数组是,才有必要使用 short。
当一个小的数据类型赋值给一个大的数据类型,不会出错,因为编译器会自动转换。但当一个大的数据类型赋值给一个小的数据类型,那么就可能丢失高位。
4.1.2、浮点类型
浮点类型用于表示小数部分的数值。计算机把浮点数分成小数部分和指数部分来表示,而且分开存储这两部分。计算机在内部使用二进制和 2 的幂进行储存。C++ 中浮点类型常量默认是 double 类型,也可以在浮点数值后面添加后缀 'd' 或 'D' ;声明 float 类型的常量,需后加 'f' 或 'F'。声明 long double 类型的常量,需后加 'l' 或 'L'。double 型变量所表示的浮点数比 float 型变量更加精确。
因为在任何区间内都存在无穷多个实数,所以计算机的浮点数不能表示区间内的所有值。因此,浮点数通常只是实际值的近似值。浮点类型不能准确的表达一个浮点数,可能会有舍入误差。
浮点型常量的基本形式是:有符号的数字(包括小数点),后面紧跟 e 或 E,最后一个有符号数表示 10 的指数,如:-1.56E+12 和 2.87e-3。正号可以省略。可以没有小数点(如,2E5)或指数部分(19.28),但是不能同时省略两者。可以省略小数部分(如,3.E16)或整数部分(如,.45E-6),但是不能同时省略两者。
数据类型 | 占用空间 |
---|---|
float(单精度类型) | 4 个字节,取值范围:1.2E-38 到 3.4E+38,6 位有效位 |
double(双精度类型) | 8 个字节,取值范围:2.3E-308 到 1.7E+308,15 位有效位 |
long double(长双精度类型) | 16 字节,取值范围:3.4E-4932 到 1.1E+4932,19 位有效位 |
#include <iostream>
using namespace std;
int main(void)
{
float f = 3.14f;
double d = 3.14;
long double ld = 3.14L;
cout << f << endl;
cout << d << endl;
cout << ld << endl;
cout << "floag:" << sizeof(f) << endl;
cout << "double: " << sizeof(d) << endl;
cout << "long double: " << sizeof(ld) << endl;
return 0;
}
C++ 规定,float 类型必须至少能表示 6 位有效数字,且取值范围最少是 1.0e-37 ~ 1.0e+37,float 表示的数值的范围比 long 还大。double 类型和 float 类型的最小取值范围相同,但至少必须能表示 10 位有效数字。一般情况下,double 占用 64 位而不是 32 位。C++ 只保证 long double 类型至少与 double 类型的精度相同;
浮点类型只能使用 long 说明符,其它说明符(short、signed、unsigned)都是不可用的;
4.1.3、字符类型
字符型变量用于存储一个单一字符,在 C语言 中用 char 表示,其中每个字符变量都会占用 1 个字节。char类型的字面量值要用一对单引号(' ')括起来,内部只能写一个字符。
字符型变量实际上并不是把该字符本身放到变量的存储单元中去,而是将 该字符对应的 ASCII 编码放到变量的存储单元中。char 的本质就是一个 1字节 大小的整型,取值范围为:-128~127;我们可以直接给 char 类型的变量赋值一个整数,在输出时,可以按照 ASCII码 输出。char 类型的变量还可以进行运算,相当于一个整数。
数据类型 | 占用空间 |
---|---|
signed char | 1 字节,取值范围:-128~127 |
unsigned char | 1 字节,取值范围:0~255 |
#include <iostream>
using namespace std;
int main(void)
{
// 定义字符变量
char ch = 'a';
unsigned char uch = 97;
cout << ch << endl;
cout << uch << endl;
cout << "char: " << sizeof(ch) << endl;
return 0;
}
signed 关键字一般用于 char 类型,因为其它基本整数类型在默认情况下都是有符号数。至于 char 是否是 signed 则因编译器而异。所以,char 可能等同于 signed char,也可能等同于 unsigned char;
在 C++ 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,这种字符称为 转义字符。
转义字符 | 含义 | ASCII码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格,将当前位置移到前一列 | 008 |
\f | 换页,当当前位置移到下页开头 | 012 |
\n | 换行,将当前位置移到下一行开头 | 010 |
\r | 回车,将当前位置移到本行开头 | 013 |
\t | 水平制表符,跳到下一个 tab 位置 | 009 |
\v | 垂直制表符 | 011 |
\\ | 代表一个反斜线字符,\ | 092 |
\' | 代表一个单引号字符,' | 039 |
\" | 代表一个双引号字符," | 034 |
\? | 代表一个问号,? | 063 |
\0 | 数字 0 | 000 |
\ddd | ddd 表示 1~3 个八进制的数字 | 3位 8进制 |
\xdd | dd 表示 2 个十六进制数字 | 3位 16进制 |
#include <iostream>
using namespace std;
int main(void)
{
cout << "\thello" << endl;
cout << "鲁迅说:\"这句话我从未说过\"" << endl;
cout << "子曰:\'学而时习之,不亦说乎!\'" << endl;
cout << "御坂美琴 夏娜\r木之本樱" << endl;
cout << "\\" << endl;
return 0;
}
另外,C++ 还对字符类型进行了 “扩容”,提供一种 “宽类型” wchar_t。wchar_t 会在底层对应另一种整型,具体占几个字节要看操作系统中的实现。wchr_t 随着具体实现而变化,不够稳定。所以再 C++ 11 新标准中,还为 Unicode 字符集提供了专门的扩展字符类型:char16_t 和 char32_t,分别长 16 位和 32 位。
4.1.4、布尔类型
C++ 用于布尔类型 bool 表示布尔值,即逻辑值 true 和 false。字面值 true 和 false 都可以提升转换为 int 类型,true 被转换为 1,而 false 被转换为 0。另外,任何数字值或指针值都可以被隐式转换为 bool 值。任何非零值都被转换为 true,而零被转换为 false。
#include <iostream>
using namespace std;
int main(void)
{
bool a = true;
bool b = false;
if(a)
cout << "a is true" << endl;
else
cout << "a is false" << endl;
if(b)
cout << "b is true" << endl;
else
cout << "b is false" << endl;
return 0;
}
4.2、基本数据类型转换
4.2.1、隐式类型转换
①、初始化和赋值进行的转换
C++ 允许将一种类型的值赋给另一种类型的变量。这样做时,值将被转换为接收变量的类型。此时,将一个值赋给取值范围更大的类型通常不会导致什么问题,只是占用更多的字节而已。然后,将一个大的值赋值给取值范围小的类型将对导致降低精度。
潜在的数值转换问题:
转换 | 潜在的问题 |
---|---|
将较大的浮点类型转换为较小的浮点类型 | 精度(有效位)降低,值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的 |
将浮点类型转换为整型 | 小数部分丢失,原来的值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的 |
将较大的整型转换为较小的整型 | 原来的值可能超出目标类型的取值范围,通常只复制右边的字节 |
将 0 赋给 bool 变量时,将被转换为 false,而非零值将被转换为 true。
②、表达式中的转换
当同一个表达式中包含两种不同的算术类型时,C++ 将执行两种自动转换:首先,一些类型在出现时便会自动转换;其次,有些类型在于其它类型同时出现在表达式中时将被转换。
在计算表达式时,C++ 将 bool、char、unsigned char、signed char 和 short 值转换为 int。具体来说,true 被转换为 1,false 被转换为 0。这些转换被称为 整型提升(integral pormotion)。如果 short 比 int 短,则 unsigned short 被转换为 int。如果两种类型的长度相同,则 unsigned short 类型将被转换为 unsigned int。wchar_t 被提升为下列类型中第一个宽度足够存储 wchar_t 取值范围的类型:int、unsigned int、long 或 unsigned long。
当运算涉及两种类型时,较小的类型将被转换为较大的类型。
- 如果有一个操作数的类型时 long double,则将另一个操作数转换为 long double。
- 否则,如果有一个操作数的类型是 double,则将另一个操作数转换为 double。
- 否则,如果有一个操作数的类型是 float,则将另一个操作数转换为 float。
- 否则,说明操作数都是整型,因此执行整型提升。
- 在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级别比另一个低,则转换为级别高的类型。
- 如果一个操作数为有符号的,另一个操作数为无符号的,且无符号操作数的级别比有符号操作数高,则将有符号操作数转换为无符号操作数所属的类型。
- 否则,如果有符号类型则可以表示无符号类型的所有可能取值,则将无符号操作数转换为有符号操作数所属的类型。
- 否则,将两个操作数都转换为有符号类型的无符号版本。
类型的级别从高至低依次是
long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int、int
。之所以 short、char 和 bool 没有列出,是因为它们已经被升级到 int 或 unsigned int 。
#include <iostream>
using namespace std;
int main(void)
{
char ch;
int i;
float f1;
f1 = i = ch = 'C';
cout << "ch: " << ch << ", i: " << i << ", f1: " << f1 << endl;
ch = ch + 1;
i = f1 + 2 * ch;
f1 = 2.0 * ch + i;
cout << "ch: " << ch << ", i: " << i << ", f1: " << f1 << endl;
ch = 1107;
cout << "Now ch: " << ch << endl;
ch = 80.89;
cout << "Now ch: " << ch << endl;
return 0;
}
- 第 9 行和 第 10 行:字符 'C' 被作为 1 字节的 ASCII 码值储存在 ch 中。整数变量 i 接受由 'C' 转换的整数,即按 4 字节储存 67。最后,f1 接受由 67 转换的浮点数 67.00;
- 第 12 行和第 15 行:字符变量 'C' 被转换成整数 67,然后加 1。计算结果是 4 字节整数 68,被截断成 1 字节储存在 ch 中。根据 %c 转换说明打印时,68 被解释成 'D' 的 ASCII 码。
- 第 13 行和第 15 行:ch 的值被转换为 4 字节的整数(68),然后 2 乘以 ch。为了和 f1 相加,乘积整数(136)被转换为浮点数。计算结果(203.00f)被转换成 int 类型,并储存在 i 中。
- 第 14 行和第 15 行:ch 的值('D',或 68)被转换为浮点数,然后 2 乘以 ch。为了做加法,i 的值(203)被转换为浮点类型。计算结果(339.00)被储存在 f1 中。
- 第 17 行和第 18 行:演示了类型降级的示例。把 ch 设置为一个超过其范围的值,忽略额外的位后,最终 ch 的值时字符 S 的 ASCII 码。或者,更确切地说,ch 的值是 1107 % 265,即 83。
- 第 20 行和第 21 行:演示了另一个类型降级的示例。把 ch 设置为一个浮点数,发生截断后,ch 的值是字符 P 的 ASCII 码。
有多种类型的数据混合运算时,系统首先会自动将所有数据转换成精度最大的那种数据类型,然后再进行计算;
若两种类型的字节数不同,转换成字节数大的类型,若两种类型的字节数相同,且一种有符号,一种无符号,则转成成无符号类型;
在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换成左边量的类型,如果右边变量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入;
4.2.2、强制类型转换
强制类型转换就是自动类型提升运算的逆运算;我们需要 使用强转符:() 来强制转换;它的格式如下:
(目标数据类型)被强转的数据;
#include <iostream>
using namespace std;
int main(void)
{
int i1 = 353;
char ch = (char)i1;
float f = 3.14f;
double d = (int)f;
cout << ch << endl;
cout << d << endl;
return 0;
}
上面的强制类型转换的方式来自于经典的 C 语言。在 C++ 中,我们还可以书写成如下格式:
目标数据类型(被强转的数据)
#include <iostream>
using namespace std;
int main(void)
{
int i1 = 353;
char ch = char(i1);
float f = 3.14f;
double d = int(f);
cout << ch << endl;
cout << d << endl;
return 0;
}
C++ 中还引入了 4 个强制类型转换运算符,这种新的转换方式传统的方式更为严格。通常在类型转换中用的运算符是 static_cast
,用法如下:
static_cast<目标数据类型>(被强转的数据)
#include <iostream>
using namespace std;
int main(void)
{
int i1 = 353;
char ch = static_cast<char>(i1);
float f = 3.14f;
double d = static_cast<int>(f);
cout << ch << endl;
cout << d << endl;
return 0;
}
强制类型转换可能会损失精度,导致数据错误;
强制类型转换操作不会改变操作数本身;
4.3、复合数据类型
4.3.1、字符串类型
字符串(character string)是一个或多个字符的序列,它使用一对双引号包裹起来,以 '\0' 作为字符串的结束标志。C++ 中我们可以使用 字符数组 来保存字符串,也就是使用一个一维字符数组保存字符串中的每一个字符。此时,编译器会自动为其添加 '\0' 作为结束符。
数组由连续的存储单元组成,字符串的字符被储存在相邻的存储单元中,每个单元储存一个字符。数组末尾位置的字符 '\0'。这是空字符(null character),C语言 用它标记字符串的结束。空字符不是数字 0 ,它是非打印字符,其 ASCII 码值是(或等价于)0。C++ 中的字符串一定以空字符结束。这意味着数组的容量必须至少比待存储字符串的字符数多 1。
#include <iostream>
using namespace std;
int main(void)
{
char str[] = "hello world!";
cout << str << endl;
return 0;
}