本系列为C++的入门学习者服务,旨在于为此前无C++基础的学习者简单介绍关于C++语言基础的部分知识,如果已入门C++,则不需要阅读本系列。
1.1 C++语言概述与框架
1. 典型实例
1 |
|
2. C++程序的组成部分
常见的C++程序的默认框架
1 |
|
3. C++中的注释
注释的文字不会在程序运行的时候被执行,能起到解释代码的作用。
① 单行注释:以//
开始,换行后结束。
1 | int a; //我是注释我是注释我是注释 |
② 多行注释:以 /*
开始,以*/
结束。
1 | int a; |
4. C++的字符集.符号.关键字
字符集:只允许直接使用英文字符和阿拉伯数字。(其他字符不推荐使用)
标点符号:必须使用西文符号。
关键字:具有特定含义的英文单词,如int
,不能另作他用。
1.2 C++中的数据类型
C++程序中的数据具备三种属性:数据类型,名字,值。
1. 数据类型的意义
C++为强类型语言,所有变量应“先定义后使用”,数据类型定后无法修改。
2. C++中的基本数据类型
数据类型 | 代码表示 |
---|---|
整数型 | int |
字符型 | char |
实数型 | float(单浮点数) double(双浮点数) |
逻辑型 | bool |
注:以上仅包含基本数据类型。
(1) 整数型 int
A. 定义:存放整数数据,存储数据长度和计算机字长有关系。
若定义1字节=8位二进制数(即位数=字节*8),int
长度为4字节,容纳的范围就为-231~231-1。若数据超出范围,则会溢出。
注:有关于溢出以及字长问题,请参考:计算机补码相关知识
B. 修饰:整型数据经修饰后可以有许多形式。
int
前可以用short
,long
,signed
,unsigned
修饰
类型 | 长度 | 范围 |
---|---|---|
(signed) short (int) | 2 | -215~(215-1) |
unsigned short (int) | 2 | 0~(216-1) |
(signed) long (int) | 4 | -231~(231-1) |
unsigned long (int) | 4 | 0~(232-1) |
(signed) (int) | 4 | -231~(231-1) |
unsigned (int) | 4 | 0~(232-1) |
signed int
表述整数格式为补码,即将模劈开一半左边表示负数。unsigned int
表示整数格式为纯数值类型(必然是正数),即将模全用于正数。注:以上数据可能仅在32位编译器中生效,随编译环境不同长度也可能不同。
(2) 字符型 char
字符类型保存单个字符,存储的为该字符的ASCII码数值,长度为一个字节。
字符类型本质上也属于整数,也可以用signed
和unsigned
修饰。
注:关于ASCII码:128个常用字符指定数值编码,范围0~127。
A. ASCII码前32位为控制字符,有特定功能但无法直接输入和表示。
B. 需要记住的ASCII码数值:字符0为48,字符A为65,字符a为97。(先大写后小写:小写比大写多32)
(3) 实数型 float
double
单精度float
与双精度double
都用来存放实数,但精度不同。
类型 | 长度 | 范围 | 精度 |
---|---|---|---|
float | 4 | 约-1038~1038 | 6~7 |
double | 8 | 约-10308~10308 | 15~16 |
(4) 逻辑类型 bool
取值只能为true
或false
。
存储字节数通常为1个字节。
bool
型在运算中可以和整型相互转化:false=0
,true=1
。
1.3 C++中的变量和常量
1. C++中的变量
变量必须先定义后使用且无法更改。
变量必须使用标识符进行标识,即变量名。
定义变量实例:
int a, b;
- 定义变量的同时赋值,即为初始化,可以避免随机值。如
int a = 0
。
初始化语句 | 含义 |
---|---|
int a; | 默认初始化(随机) |
int a = 3; | 赋值初始化 |
int a(3); | 构造初始化 |
int a{3}; | 列表初始化 |
int a = {3}; | 列表初始化的赋值写法 |
2. C++中的字面常量
字面常量指程序中直接给出的量,执行过程中值不变。
(1) 整数常量
整数常量 | 格式 | 示例 |
---|---|---|
十进制整数 | 与实际使用的格式一致 | 38 |
八进制整数 | 以0开始的整数为八进制整数 | 077 |
十六进制整数 | 以0X(大小写都可)开始的整数 | 0x5abc |
注:整数后缀 | 整数后加L(long)或U(unsigned)表示长整数或无符号整数(大小写都可) | 84L 0x32LU |
(2) 实数常量
定点格式与日常书写相同。如:
0.23
。指数格式为尾数乘10的次方,“十”用E或e表示,次方必须为整。如:
0.3e-2
。实数常量使用的时候应避免不精确问题。
1 | bool a; |
(3) 字符常量
用一对单引号引的单个字符,类型是char,在内存中保存的值是字符的ASCII码值。如:'a'
'@'
注:转义字符:控制字符无法直接显示和输入,用转义字符间接表示。
常用的转义字符:
转义字符 | 含义 | 备注 |
---|---|---|
‘\n’ | 回车 | |
‘\t’ | 横向制表 | 一个制表为8位,输出整齐 |
‘\nnn’ | 任意字符8进制(ASCII)转义 | 如:‘\101’代表字符A |
‘\xnn’ | 任意字符16进制(ASCII)转义 | 如:‘\x41’字符字符A(x必须小写) |
例:C++中的三个“零”:
形式 类型 长度 值 0 整数 4 0 ‘0’ 字符 1 48 ‘\0’ 字符 1 0
(4) 字符串常量
用一对双引号引起来的若干字符(可以为空)。如:"123"
""
在内存中存放字符串的时候,在最后存放了一个隐藏的'\0'
。
如:
"a"
长度为2,而'a'
长度为1。
(5) 常变量
用const
修饰变量使其无法更改,称之为常变量。
如:
const float PI = 3.14159;
常变量必须且只能在定义的时候初始化,且之后无法更改。
1.4 C++中的运算符和表达式
要点:掌握运算符功能,规定,优先级,结合性,分类。
1. 优先级和结合性
- 优先级:指不同运算符在运算中的优先关系。(从小到大越小越优先)
- 结合性:决定优先级相等的或相同运算符组合在同一运算式时的运算次序。
2. 基本运算符
(1) 算术运算符
指在计算机中参与数学运算的各类运算符,具体如下表
优先级 | 运算符 | 名称 | 类型 |
---|---|---|---|
3 | + | 正 | 单目 |
3 | - | 负 | 单目 |
5 | * | 乘1 | 双目 |
5 | / | 除2 | 双目 |
5 | % | 求余3 | 双目 |
6 | + | 加 | 双目 |
6 | - | 减 | 双目 |
注:算术运算符的语法说明
运算表达式中乘号
*
不能省略。如:v = a*b*c
不能写为v = abc
。当两操作数均为整数,*/*为整除,结果为整数,且是舍去小数的整数。如:
5 / 4 = 1
;1 / 2 = 0
。
若想让结果不取整,则在操作数部分改为1.0
,2.0
等。如:1.0 / 2 = 0.5
。
%
为整数求余,只对整数有效,最后符号与被除数同。如:-7 % 6 = -1
。C++中平方只能通过
a*a
或特定函数实现,而不是a^2
。
(2) 赋值运算符
将赋值号 =
右边的值送到左边变量中(由右向左结合)
赋值运算符的优先级很低(16),仅高于throw
和逗号,
运算符。
变量名代表的单元为左值,表达式的值为右值。即:左值 = 右值
。
左值只能是变量名或可寻址表达式,右值形式不限。
如:下列形式都是错误形式:3 = a
; a + b = c
注:复合赋值运算符:由双目运算符和位运算符与赋值运算符组合。(16级)
+= -= *= /= %= <<= >>= &= = ^= 运算规则:
变量_复合赋值运算符_表达式 等同于 变量 = 变量_运算符_表达式
如:
x += 5
等同于x = x + 5
;x *= 5 + 3
等同于x = x * ( 5 + 3 )
(3) 自增、自减运算符
– | ++ |
---|
意义:变量当前值加1或减1,再赋给该变量
要求:操作数只能是左值,是单目运算符。
注:前置与后置运算
前置
++i
:先增减后引用,即先对变量增减,用新的值参与运算。结合性:由右向左结合。
优先级:
3
(与普通单目运算符相同)前置运算表达式是左值,如:
++a
结果就是经过变换后的a
本身。
例:a = 1; ++a = 3; a = ?
a = 1; ++a = 2; (则 a=2) a=3; 故最终a = 3
后置
i++
:先引用后增减,即先用旧值运算,再对变量自加自减。结合性:由左往右结合。
优先级:
2
(高于前置运算)后值运算表达式是右值,如
a++
并不是a
,而是一个临时量,在参与完运算过程后再执行一次a+1
,而后临时量a++
被舍弃,故不可寻址。
例:int a = 2, b, c; b = a++ * 3; c = ++a * 2;
b = 2 * 3 = 6 同时 a = a + 1 = 3
c = 4 * 2 = 8
(4) 关系运算符
运算符 | 含义 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
运算结果:<bool>
true
或 false
优先级:
低于算术运算符,高于赋值运算符。
判断大小的符号高于判断相等的符号。
注:关系运算符不能连续
- 如:
a>b>c
会被解释为(a>b==true=1)>c=0
(5) 逻辑运算符
优先级 | 运算符 | 名称 | 类型 | 语义 |
---|---|---|---|---|
3 | ! | 逻辑非 | 单目 | 真则假,假则真 |
13 | && | 逻辑与 | 双目 | 全真则真,一假则假 |
14 | || | 逻辑或 | 双目 | 一真则真,全假则假 |
注:逻辑值与数值的转换
逻辑值转数值:
逻辑值 | 数值 |
---|---|
true | 1 |
false | 0 |
数值转逻辑值:
数值 | 逻辑值 |
---|---|
非0 | true |
0 | 0 |
例:逻辑运算符判断连续的关系运算符
判断
a > b > c
写法为a > b && b > c
注:逻辑表达式的优化和副作用
在求逻辑表达式值的过程中,一旦表达式的值能够确定,就不再进行之后的运算。
例:如下程序
1 | int a=10, b=20, c=30, d; |
求解过程中a<b
为真,**||两侧只要有一侧是真结果便确定,所以右边的c++
将不会被计算**,c
仍然为30
,结果d = true
,故d=1
。
(6) 位运算符
优先级 | 运算符 | 名称 | 类型 |
---|---|---|---|
3 | ~ | 按位取反 | 单目 |
7 | << | 左移 | 双目 |
7 | >> | 右移 | 双目 |
10 | & | 按位与 | 双目 |
11 | ^ | 按位异或 | 双目 |
12 | | | 按位或 | 双目 |
常见的位运算符算法:
按位取反 = - n - 1
左移 = a * 2n
右移 = a / 2n
(7) 逗号运算符
用逗号运算符连接起来的表达式称为逗号表达式(优先级最低,为18
)
格式:
表达式1,表达式2,……,表达式n
作用:逗号表达式中由左向右每一个表达式都会被运算,整个表达式的值为最后一个表达式的值,常用来连接多个表达式。
例:
1 | int a, x; |
最后结果 a = 11 x = 9
(8) sizeof() 运算符
常用于计算一个操作数类型或一个变量的字节数。
例:在32位编译器中
1 | sizeof(int) // 4 |
3. 运算符优先级简单总结
目前为止学到的运算符:
- 单目
>
算术>
关系>
逻辑>
赋值 - 所有单目符号无论类别,优先级都同,结合性都由右向左(后置符号除外)
1.5 C++中的类型转换
1. 自动类型转换
当二元运算符两边的操作数类型不同但属于类型相容时,系统将精度低的操作数变换到与另一操作数精度相同,而后再进行运算。
常见的类型转换 |
---|
char,short→int→long→float→double |
signed→unsigned |
字符自动变换成整型(转为ASCII码) |
2. 赋值类型转换
当赋值号左值右值类型不同但类型相容的时候,将将右值转换为左值类型。
类型 | 方法 |
---|---|
小数→整数 | 直接取整舍去小数 |
整数→小数 | 小数位补.0 |
整数高→整数低 | 舍去高字节 |
整数低→整数高 | 补充符号位(unsigned除外) |
例:char c = 250; int a = c; 求a=?
char c = 250
中,因为char
长度只有一个字节
,即8
位,存储范围为-128~127
,250
作为一个int
(4
个字节32
位)实际上已经溢出:
250
二进制为00000000 00000000 00000000 11111010
如果只存储
一个字节
(8
位)则舍去高字节变成:
11111010
则c
变成了-6
的二进制再赋值给
a
(int
4字节32位)的时候,补充了符号位
11111111 11111111 11111111 11111010
则a
被赋值成-6
3. 强制类型转换
将表达式强制转换为指定的类型(type)参与运算(临时值),但本身的值不变
格式:(type)表达式
或 type(表达式)
1.6 输入输出的详细问题
1. cin和数据的输入
cin >> a >> b;
(1) 如果需要同时输入多个整数或实数
,输入需要进行分隔,默认的分隔符号为空格、回车、TAB。
输入整型int
时:
1 | int a, b, c; |
输入时应输入1
2
3
,才能分别将1
2
3
赋值到a
b
c
,如果输入123
则只能将a
赋值为123
。
(2) 同时输入多个字符
则不需要分隔。
输入字符char
时:
1 | char a, b, c; |
输入时输入123
或1
2
3
都可以分别输入成功。
(3) 如果输入过程中如果需要输入空白字符在内的任意字符
,则需要使用cin.get()函数。
c = cin.get()
cin.get(c)
例:
1 | char a, b, c; |
输入时如果输入1
2
3
,则a
被给1
,b
被给空格
,c
被给2
,剩下的空格
与3
丢弃。
2. 输入输出格式控制
<iomanip>
的两个常用函数
(1) setw(int n)
函数
控制输出内容的最短宽度为n
位,用来帮助对齐。
例:(自己实践,可以打出完美的制表)
1 | for (int i = 1; i <= 100; ++i) |
(1) setprecision(int n)
函数
用来控制输出内容的有效数字或小数点的有效位数。
A. 当输出模式为定点小数(fixed
)时,控制小数位数。(四舍五入)
例:
1 | cout << fixed << setprecision(2) << 100.0 / 7 << endl; |
输出结果为14.29
。
B. 当输出模式为默认时,控制有效数字。
例:
1 | cout << setprecision(2) << 100.0 / 7 << endl; |
输出结果为14
。
当输出模式为科学技术(scientific
)时,控制实数部分小数位数。
例:
1 | cout << scientific << setprecision(2) << 100.0 / 7 << endl; |
输出结果为1.43e+01
。(控制实数1.43
的小数位数)