C++学习笔记
编译:有编译器将整个源代码翻译成机器码,最终生成二进制文件,一次性提交给计算机执行。代表:C、C++
解释:由解释器将代码逐行解释成机器码,并交给计算机执行。代表:Python、JavaScript
#include<iostream>
using namespace std;
int main()
{
short a = -20;
cout << " a = " << a << endl;
cout << " a 的长度为:" << sizeof a << endl;
//整型
int a2 = 20;
cout << " a2 = " << a2 << endl;
cout << " a2 的长度为:" << sizeof a2 << endl;
long a3 = 20;
cout << " a3 = " << a3 << endl;
cout << " a3 的长度为:" << sizeof a3 << endl;
long long a4 = 20;
cout << " a4 = " << a4 << endl;
cout << " a4 的长度为:" << sizeof a4 << endl;
//无符号整型
unsigned short s1 = 32769;
cout << "s1 = " << s1 << endl;
cin.get();
}
由于类型太多,在实际应用中使用整型可以只考虑三个原则:
- 一般的整数计算,全部用
int
; - 如果数值超过了
int
的表示范围,用long long
; - 确定数值不可能为负,用无符号类型(比如统计人数、销售额等);
之前所有的整型默认都是有符号的,而char
并没有默认类型,需要C++编译器根据需要自己决定。把char
当做小整数时,有两种显式的定义方式:signed char
和 unsigned char
;至于char
定义出来的到底带不带符号,就看编译器的具体实现了。
//字符类型
char c = 65;
cout << "c = " << c << endl;
char c2 = c + 1;
cout << "c + 1 = " << c2 << endl;
输出为:
c = A
c + 1 = B
bool类型
在C语言中,用 “1” 表示 “真”, “0” 表示 “假”。C++里面引入了一种新的数据类型 – 布尔类型 bool
。 bool
类型只有两个取值: true
和 false
, bool
类型通常占有 8 位(1个字节)。
//布尔类型
bool b1 = true;
cout << "b1 = " << b1 << endl;
cout << "b1 占据的长度为: " << sizeof b1 << endl;
输出为:
b1 = 1
b1 占据的长度为: 1
浮点类型
跟整数对应,浮点数用来表示小数,主要有单精度 float
和 双精度 double
两种类型,double
的长度不会小于 float
。通常 float
会占用 4 个字节(32位), 而 double
会占用 8 个字节(64位)。
除了一般小数,在 C++ 中,还提供了另外一种浮点数的表示法,科学计数法,也叫作"E表示法"。比如:5.98E24
表示 5.98 * 10^24
。
//浮点类型
float f = 2.5;
double d = 3.79E-23;
cout << "f = " << f << endl;
cout << "d = " << d << endl;
输出:
f = 2.5
d = 3.79e-23
字面值常量
在给一个变量赋值的时候,会直接写一个整数或者小数,这个数据就是显示定义的常量值,叫做"字面值常量"。每个字面值常量需要计算机进行保存和处理,所以也都是有数据类型的。字面值的写法形式和具体值,就决定了它的类型。
-
整型字面值
整型字面值就是我们直接写的一个整数。
计算机底层是二进制的,所以还可以写成八进制和十六进制的形式。
以0
开头的整数表示八进制数;以0x
开头的代表十六进制数。例: -
30 十进制数
-
036 八进制数
-
0x1E 十六进制数
以上数的本质上都是十进制的30.
在 C++ 中,一个整型字面值默认是int
类型,前提是数值在int
能表示的范围内。如果超出这个范围,哪么就需要选择能够表示这个数的、长度最小的类型。
具体而言,对于十进制整型字面值,如果int
不够就选择long
, 还是不够,就选择long long
;对于八进制和十六进制字面值,会优先用无符号类型unsigned int
, 不够就用long
,之后依次是unsigned long
、long long
和unsigned long long
。
一般在定义整型字面值的时候,会给它加上一个后缀,明确地告诉计算机这个字面值是什么类型。 -
默认什么都不加,就是
int
类型; -
I 或者 L ,表示
long
类型; -
II 或者 LL, 表示
long long
类型; -
u 或者 U, 表示
unsigned
类型;
一般用 大写L
,避免和数字 1 混淆; 而u
可以和L
或者LL
组合使用。例如9527uLL
就表示这个数是unsigned long long
类型。
转义字符:
换行符 | \n |
横向制表符 | \t |
报警(响铃)符 | \a |
纵向制表符 | \v |
退格符 | \b |
双引号 | " |
反斜线 | \ |
问号 | ? |
单引号 | ’ |
回车符 | \r |
进纸符 | \f |
类型转换
//赋值时的自动类型转换
//1.整数值赋给bool变量
bool btrans = 25;
cout << "btrans = " << btrans << endl;
//2.将bool类型的值赋给算数整型
short strans = false;
cout << "strans = " << strans << endl;
//3.浮点数赋值给整数类型
int itrans = 3.14;
cout << "itrans = " << itrans << endl;
//4.整数值赋值给浮点类型
float ftrans = 3;
cout << "ftrans =" <<ftrans << endl;
//5.赋值超出了整型范围
unsigned short ustrans = 65536;
cout << "ustrans = " << ustrans << endl;
strans = 32768;
cout << "ustrans = " << ustrans << endl;
输出为:
btrans = 1
strans = 0
itrans = 3
ftrans =3
ustrans = 0
ustrans = 0
转换规则可以总结如下:
- 非布尔类型的算术值赋给布尔类型,初始值为0 则结果为
false
, 否则结果为true
; - 布尔值复制给非布尔类型,初始值为
false
则结果为 0, 初始值为true
则结果为 1; - 浮点数赋给整数类型,只保留浮点数中的整数部分,会带来精度丢失;
- 整数值赋给浮点类型,小数部分记为 0.如果保存整数需要的空间超过了浮点类型的容量,可能会有精度丢失。
- 给无符号类型赋值,如果超出它表示范围,结果是初始值对无符号类型能表示的数值总数取模后的余数。
- 给有符号类型赋值,如果超出它表示范围,结果是未定义的(undefined)。此时,程序可能继续工作,也可能崩溃。
变量和数据类型
一段程序的核心有两个方面:一个是要处理的信息,一个是要处理的计算流程。计算机所处理的信息一般叫做"数据"。
对于计算机来说,需要明确地知道把数据存放在哪里、以及需要多大的存储空间。在机器语言和汇编语言中,我们可能需要充分了解计算机底层的存储空间,这非常麻烦;在C++程序中,我们可以通过"声明变量"的方式来实现这些。
表达式和运算符
cout << "1 + 2 =" << 1 + 2 << endl;
cout << "1 + 2 - 3 x 4" << 1 + 2 - 3 * 4 << endl;
int a = 20, b = 6;
cout << "a + b = " << a + b << endl;
cout << "a + 1 = " << a + 1 << endl;
cout << "a/b =" << a / b << endl;
short a2 = 3;
long long b2 = 23435;
cout << "a2 * b2 = " << a2 * b2 << endl;
cout << "b2 / b = " << b2 / b << endl;
float a3 = 20;
cout << "a3/b =" << a3 / b << endl;
cout << "a % b =" << a % b << endl;
cout << "-a % b =" << -a % b << endl;
输出为:
1 + 2 =3
1 + 2 - 3 x 4-9
a + b = 26
a + 1 = 21
a/b =3
a2 * b2 = 70305
b2 / b = 3905
a3/b =3.33333
a % b =2
-a % b =-2
基本概念
在程序中,一个或多个运算对象的组合叫做 “表达式”。对一个表达式进行计算,可以得到一个结果,有时也把它叫做表达式的值。
C++中定义的运算符,可以是像"+“这样连接两个对象,称为"二元运算符”;也可以只作用于一个对象,称为"一元运算符"。另外,还有一个比较特殊的运算符可以作用于三个对象,称为"三元运算符"。
算数运算符相关规则如下:
- 一元运算符(正负号)优先级最高;接下来是乘、除和取余;最后是加减;
- 算数运算符满足左结合律
- 算数运算符可以用来处理任意算数类型的数据对象;
- 不同类型的数据对象进行计算时,较小的整数类型会被"提升"为较大的类型,最终抓换成同一类型进行计算;
- 对于除法运算"/“,执行计算的记过跟操作数的类型有关。如果它的两个操作数(也就是被除数和除数)都是整数,哪么得到的结果也只能是整数,小数部分会直接舍弃,这叫"整数除法”;当至少有一个操作数是浮点数时,结果就会是浮点数,保留小数部分;
- 对于取余运算 “%”,两个操作数必须是整数类型;
赋值
将一个表达式的结果,传递给某个数据对象保存起来,这个过程叫做“赋值”。
a = 1;
//1 = a //错误,1不是可修改的左值
a = b + 5;
//b + 5 = a; //错误
const int c = 10;
// c = b //错误
复合赋值运算符
我们经常需要把一次计算的结果,再赋值给参与运算的某一个变量。最简单的例子就是多个数求和
int sum = a;
sum = sum + b;
sum = sum + c;
//以上可以用一个来表示
sum += c;
递增递减运算符
++a; //a递增,相当于 a += 1
--b; //b递减,相当于 b -= 1
关系和逻辑运算
关系运算符
关系运算符的相关规则:
- 算数运算符的优先级高于关系运算符,而如果加上括号就可以调整计算顺序;
- 关系运算符的返回值为布尔类型,如果参与算数计算,
true
的值为1,false
的值为0;
逻辑运算符
- 逻辑非(!):一元运算符,将运算对象的值取反后返回,真值反转;
- 逻辑与( &&):二元运算符,两个对象都为
true
时结果为true
,否则结果为false
- 逻辑或(||):二元运算符,两个运算对象只要有一个为
true
结果就位true
,都为false
则结果为false
条件运算符
形势如下:
条件判断表达式?表达式1:表达式2
逻辑运算符
位逻辑运算符有:按位取反"~“, 位与”&“, 位或”|“和位异或”^"。
- 按位取反"~":一元运算符,类似逻辑非。对每个位取反值,也就是把 1 置为 0、0置为1;
- 位与"&":二元运算符,类似逻辑与。两个数对应位上都为 1,结果对应位为 1; 否则结果对应位为 0 ;
- 位或 “|”:二元运算符,类似逻辑或。两个数对应位上只要有1,结果对应位就位1;如果全为0 则结果对应位为0;
- 位异或“^”:两个数对应位相同,则结果对应位为0;不同则结果对应位为1;
类型转换
隐式类型转换
short s = 15.2 + 20;
cout << "s = " << s << endl;
cout << "15.2 + 20 = " << (15.2 + 20) << endl;
cout << "s 长度为:" << sizeof s << endl;
cout << "15.2 + 20 结果长度为:" << sizeof(15.2 + 20) << endl;
结果为:
s = 35
15.2 + 20 = 35.2
s 长度为:2
15.2 + 20 结果长度为:8
隐式类型转换的一般规则可以总结如下:
- 在大多数算数运算中,较小的整数类型(如bool、char、short)都会转换成
int
类型。这叫做“整数提升”;(而对于wcher_t
等较大的扩展字符类型,则根据需要转换成int
、unsigned int
、long
、unsigned long
、long long
、unsigned long long
中能容纳它的最小类型) - 当表达式中有整型也有浮点型时,整数值会转换成相应的浮点类型;
- 在条件判断语句中,其他整数类型会转换成布尔类型,即 0 为
false
、非0 为true
; - 初始化变量时,初始值转换成变量的类型;
- 在赋值语句中,右侧对象的值会转换成左侧对象的类型;
此外,要尽量避免将较大类型的值赋给较小类型的变量,这样很容易出现进度丢失或者数据溢出。
强制类型转换
//强制类型转换
int total = 20, num = 6;
double avg = total / num;
cout << "avg =" << avg << endl;
//C语言风格
cout << "avg = " << (double)total / num << endl;
//C++函数调用风格
cout << "avg = " << double(total) / num << endl;
//C++强制类型转换运算符
cout << "avg= " << static_cast<double>(total) / num << endl;
输出结果为:
avg =3
avg = 3.33333
avg = 3.33333
avg= 3.33333