本系列为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(int4字节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的小数位数)