1.基础数据类型:整形
1.1 有符号整型
short:2字节 16位 -2^15 -- 2^15 - 1(有一位是符号位) -32768 -- 32767
(这样理解:假设数据有4位,除去符号位有3位,那么2^3-1等于111)
int: 4字节 32位 -2^31 -- 2^31 - 1
long: 如果是32位的系统下:long = int,32位,如果是64位系统下,long:64位 ,long long:64位
-2^63 -- 2^63 - 1
1.2 无符号整型
unsigned short: 0 -- 2^16 - 1
例如:1000000000000001 有符号数:-1 无符号数:32769
1.3 获取整形尺寸
1.4 获取整形最大值,最小值:
1.5 整形的溢出:
注意:补码是除符号位外的原码取反加一,原码是除符号位外的补码取反加一,数据以补码形式存储,打印时输出的也是补码的值。
在整形溢出时,会根据最大,最小值范围循环,就比如第一行的INT_MAX + 1后,得到INT_MIN。
2.基础数据类型:字符(char)
2.1 有符号:char
占用1个字节,8位,范围是-128到+127(若赋值溢出,则循环)
(例如1 111 1111,其中最高位是符号位,剩下的111 1111是2^7 - 1,即127)
对于char类型,输出的是相应的字符,若是把结果赋给short类型,则输出的是对应的ASCII码值。
可以用put直接输出字符:
输出结果为: $ a b
对put传入short类型变量时,依然会输出其ASCII码对应的字符。
2.2 无符号:unsigned char
占用1个字节,8位,范围是0到255
3.C++ 中的特殊字符
3.1 根据ASCII获取字符
核心思想:把ASCII转换成char类型
要记住一些ASCII所对应的字符:
字符0对应48,字符0到9的ASCII值依次递增
字符a(注意大小写)对应的ASCII值为97,字符a - z的ASCII值依次递增
字符A(注意大小写)对应的ASCII值为65,字符A - Z的ASCII值依次递增
3.2 根据字符获取ASCII
核心思想:把字符转换成int类型
cout << (int) '\a' << endl //获取特殊字符'\a'的ASCII值,其中单引号表示\a为字符类型
3.3 特殊字符
\n : newline相当于std::endl
\t : tab 列对齐,水平制表符
\v : tab 垂直制表符
\b : backspace退格
\a : alert警告
\\ : 输出反斜杠 \
\' : 输出单引号
\" : 输出双引号
4.宽字符类型
单字符类型char只能保存单字节的字符,即ASCII所能表示的范围。如果超过这个范围,就很难保存。
所以需要宽字符类型:
4.1 宽字节:
wchar_t 有符号类型 32位 4字节 在定义时前加前缀 L
4.2 在C++11中的宽字节:
char16_t 无符号类型 2字节 在定义时前加前缀u
char32_t 无符号类型 4字节 在定义时前加前缀U
查看不同数据类型的宽度
如果直接用cout输出c1,会显示'a'对应的ASCII值,若想要以字符形式输出宽字符类型的数据,就需要用到wcout,且宽字符应该是有符号类型.
使用相应的宽输出就可以输出字符了
由上图可见,字符‘中’所对应的数值是20013,20013换算成16进制等于4E2D,那么就可以通过4E2D来输出字符‘中’。
其中\u前缀表示unicode编码。这样就实现了通过编码输出相应的文本,即利用宽字符类型,输出中文字符对应的编码,再将其转换为16进制,即得到这个中文字符的编码。再利用这个编码输出中文文本。
注意:char16_t和char32_t属于无符号类型,如果使用wcout输出这种类型,则输出的是字符对应的编码,若想要直接输出宽字符,则需要转换为wchar_t类型.
在C++中,用单引号括起来的内容为字符,双引号括起来的为字符串
5.基础数据类型:布尔(bool)
true false
6.基础数据类型:浮点类型
6.1 浮点类型有哪些
单精度浮点类型:float
双精度浮点类型:double
长双精度浮点类型:long double
6.2 浮点类型占用的字节数
float : 4
double : 8
long double : 16
6.3 浮点类型的 表达方式
float value1 = 234.56;
double value2 = 123.11;
// 科学计数法
//1. 尾数 2.E/e 3.指数
double value3 = 1234500000000000;
double value4 = 1.2345E15; //value3和value4相同
6.4 浮点类型取值范围
//浮点数的指数的取值范围(科学计数法中)
//float +38 -37
//double +308 -307
//long double +4932 -4931
float f_max = FLT_MAX_10_EXP; //float类型的正指数的最大值(以10为底),为38
float d_max = DBL_MAX_10_EXP; //double类型的正指数的最大值(以10为底),为308
float ld_max = LDBL_MAX_10_EXP;
6.5 浮点类型精度
/*
精度
float: 6到7
一个float32位:1位符号位,8位指数位,23位存尾数即1.2345中的‘2345’
2的23次方等于8388608,一共7位,如果精确到7位,那么2的23次方表示不了9999999这个数
即精确到7位的话,不是所有数都能表示,所以精确到6-7位
double:15到16
long double: 18到19
*/
int f_dig = FLT_DIG; //6
int d_dig = DBL_DIG; //15
int ld_dig = LDBL_DIG; //18
float v1 = 1.1234323432;
double v2 =1.123432343234512678;
printf("%.18f\n", v2); //输出18位的double类型数据,但只能准确显示到.....126,后面的内容
//随机输出
6.6 浮点类型值之间的比较
float fv1 = 123.4;
float fv2 = 123.4;
if(fv1 == fv2)
{
cout << "equal" << endl;
}
6.7 习题
float f_v1 = 20;
float f_v2 = 20.3;
float f_v3 = 20.5;
double d_v1 = 20;
double d_v2 = 20.3;
double d_v3 = 20.5;
cout << ((f_v1 == d_v1)?"true":"false") << endl; //运行结果:true
cout << ((f_v2 == d_v2)?"true":"false") << endl; //运行结果:false
cout << ((f_v3 == d_v3)?"true":"false") << endl; //运行结果:true
// 1. 输出true,还是false
// 2. why
// 3. 如果让输出false的语句仍然通过比较输出true
可以通过 cout << ((f_v2 == (float)d_v2)?"true":"false") << endl;让第二个运行结果显示true。
6.8 浮点数是如何存储的
float:32位,4字节
符号位:1
指数位:8
尾数位:23
double:64位,8字节
符号位:1
指数位:11
尾数位:52
long double:128位,16字节
符号位:1
指数位:64
尾数位:63
6.9 如何将十进制浮点数转换为二进制浮点数
将十进制整数转换为二进制整数
bitset<32> myset(443); //将十进制443转换为32位的二进制数
cout << myset << endl;
将十进制浮点数转换为二进制浮点数
20.5
20 = 10100
0.5 * 2 = 1.0 (1)
0 * 2 = 0 (0)
0 * 2 = 0 (0)
即 0.5(十进制) = 0.1(二进制)
20.5 = 10100.1
20.3
20 = 10100
0.3 * 2 = 0.6 (0)
0.6 * 2 = 1.2 (1)
0.2 * 2 = 0.4 (0)
0.4 * 2 = 0.8 (0)
0.8 * 2 = 1.6 (1)
0.6 * 2 = 1.2 (1) //进入循环
0.2 * 2 = 0.4 (0) //进入循环
0.4 * 2 = 0.8 (0) //进入循环
0.8 * 2 = 1.6 (1) //进入循环
0.3 = 01001100110011001......1001
20.3 = 10100.010011001....1001
6.10 将浮点数存储在一组字节中(解释了习题的答案)
20.5 = 10100.1(二进制) = 1.01001E100(2^4)
存储:符号位-指数位(移位存储)-尾数位
移位存储:对于float,加上127,对于double,加上1023,再进行存储。
127对应二进制为:01111111 ,127+4 = 131 对应二进制为 10000011
存储方式(float): 0-10000011-01001000000000000000000
存储方式(double):0-10000000011-01001000000000000000000...000000
20.3
0.3 = 01001100110011001......1001
20.3 = 10100.010011001....1001 = 1.0100010011001...E100(科学计数法)
存储方式(float):0-10000011-01000100110011001100110
存储方式(double):0-10000000011-010001001100110011001100011110011...1
(注:2的10次方是1024,那么2^10 - 1等于1023,即1111111111,1111111111 + 4 = 10000000011)
6.11 如何将浮点数以二进制形式输出
float v1 = 20.5;
unsigned int *n = (unsigned int*)(&v1);
for(int i = 31; i >= 0;i--)
{
//float有32位,右移31位表示把最高位移到了最低位,又与了1,表示只保留最低位,后面的'-'是为了把符号位
//和指数位和尾数位用'-'区分开
cout << (*n>>i & 1) << (i == 31 || i == 23?"-":"");
}
cout << endl;
输出结果:0-10000011-01001000000000000000000
double v2 = 20.3;
unsigned long long *m = (unsigned long long*)(&v2);
//这里为什么要用long long类型呢??
for(int i = 63; i >=0;i--)
{
cout << (*m>>i & 1) << (i == 63 || i == 52?"-":"") ;
}
cout << endl;
0-10000000011-0100010011001100110011001100110011..
(这里有疑问)
7.变量初始化
7.1 与C语言兼容的初始化方式
int n = 20;
int m = 30;
int k = n + m - 50;
int x;
x = n - m;
7.2 C++不同于C语言的初始化方式
float price(30.2);
7.3 C++ 98的初始化方式
int count = {20};
count = {400};
7.4 C++ 11的初始化方式
int day = {20};
int year{}; //默认为0
8.常量
#include <iostream>
using namespace std;
#define ABC 20 //可以通过宏的方式定义常量
int main(int argc, const char * argv[])
{
// 常量
const int n = 10; //可以使用const关键字将变量定义为常量
return 0;
}
9.C++中的基本操作符
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
/*
C++中的基本操作符
1. +:加
2. -:减
3. *:乘
4. /:除
5. %:取余(取模)
6. 指定数值为float和long类型(F/f和L/l)
7. 通过操作符计算后的浮点数精度
*/
int value1 = 4 + 1;
int value2 = 4 *2;
int value3 =5/2;
int value4 =10-4;
int value5 = (3 +4)*2;
int value6 = 10 %3;
cout << value6 << endl;
float f_v = 123.4F;
long l_v = 34L;
/*float尾数有23位,2的23次方等于8388608,精确到6-7位,那么65292484256转换为2进制后,必然超过了精度范围
*/
float v1 = 565.292484256;
printf("%0.7f\n", v1);
//输出小数点后7位,尾数:65292484256,精确到6-7位指的是科学计数法中尾数的6-7位.
//所以,会打印565.29244805,其中565.292448为原数,05为随机生成。
printf("%0.12f\n", 1e7 / 9.0); //结果:1111111.111111111008
//输出小数点后12位,float类型在科学计数法中精确到6-7位,double在科学计数法中精确15-16位
printf("%0.12f\n", 1e7F / 9.0F);
//打印:1111111.125000000000,float类型在科学计数法中精确到6-7位
return 0;
}
10.类型自动转换
10.1 将一个值赋给某一类型的变量时,C++会自动转换
short s_v = 20;
int i_v = 20.3; //20.3的精度会丢失
float v = 123456789456;
//输出123456790528.000000 其中7后面应该是8,显示9是因为8后面的9四舍五入给了8
//把小数点放到1后面(科学计数法)的话,这个浮点数精确到了7位
float v1 = 1.2345678E20; //可以这样写
bool b_v = 0; //bool类型赋值0为假。赋值非0为真
b_v = 200;
if(b_v == false)
{
cout << "false" << endl;
}
char c1{127}; //字符类型最大就127
char a{200}; //这个语句会报错,使用C11的初始化方式时,会检查初始值是否超出了类型范围
wchar_t c2{3000}; //宽字符类型
long x = 2000;
char c3 = x; //传统初始化方式就不检查范围,不会报错
//变量类型的取值范围大于被赋值变量类型的取值范围时, {...}中不允许直接使用变量,只允许使用值
char c4{c1};
// 表达式中有多种类型,C++会自动转换为取值范围最大的类型
// 在表达式中,如果有一个变量是long double数据类型,则表达式中所有其他变量的值都会转换成long double
// 表达式中的类型转换遵循以下逻辑;
if(long double)
{
expr = long double
}
else if(double)
{
expr = double
}
else if(float)
{
expr = float
}
else if(操作数都是有符号或都是无符号的值)
{
short + int + long = long
unsigned short + unsigned int = unsigned int
}
else if(操作数包含有符号和无符号的数,无符号类型的取值范围可以容纳有符号类型的值)
{
unsigned long + short + int = unsigned long
}
else if(操作数包含有符号和无符号的数,无符号类型的取值范围不能容纳有符号类型的值)
{
unsigned short + int + long = long
}
else
{
unsigned int + int = unsigned int
}
11.强制类型转换
11.1 传统的C语言类型强制转换
int x = 65;
char c{x}; //会报错
char c{(char)x}; // C语言中的类型强制转换方式
cout << c << endl; //会输出A
11.2 C++中的类型强制转换
int y = 97;
char c1{char(y)}; // C++语言中的类型强制转换方式
11.3 强制转换操作符static_case(var)
cout << 'X' << endl; //输出大写字母X
cout << int('X') << endl; //输出大写字母X对应的ASCII码
char c_x = static_cast<char>(x); //将x转换为char类型,并用这个初始化c_x
12.C++11中的auto关键字
12.1 auto关键字的使用
int n = 200; //传统赋值方式
//如果写成“auto n = 200L;”,会识别成int类型;如果写成“int n = 200L;”,n为int类型
auto n = 200L;
//auto关键字要求必须在定义变量时初始化
12.2 类型自动识别(auto)的好处
12.2.1. 简化了代码
12.2.2. 当无法清楚地记得类型名时,可以直接使用auto
// STL(传统的写法)
vector<string> products;
//vector<string>::iterator product = products.begin();
// C++ 11 STL
auto product = products.begin(); //清爽了许多
12.2.3. 当改变初始化表达式返回值的数据类型时,不必再重新修改变量类型
int value = 20 + 45; //表达式返回值是int
cout << value << endl;
double value = 20 + 45.6; //表达式返回值是double
cout << value << endl;
int value = 20 + 45.6; //表达式返回值是int
cout << value << endl; //此时要保证返回值精度的话,左侧就需要把int转换为double
auto value1 = 20 + 45.9;
cout << value1 << endl;
12.3 一旦类型被识别,将无法更改
auto s = "abcd"; //s为字符串类型
s = 4; // 这里会报错