科技 · 编程

C++ 基本概念

本系列面向没有 C++ 基础的入门学习者,简要介绍 C++ 的程序框架、数据类型、变量与常量、运算符、类型转换及输入输出。

C++ 基本概念
本系列面向没有 C++ 基础的入门学习者,简要介绍 C++ 的程序框架、数据类型、变量与常量、运算符、类型转换及输入输出。

本系列为 C++ 的入门学习者服务,旨在于为此前无 C++ 基础的学习者简单介绍关于 C++ 语言基础的部分知识,如果已入门 C++,则不需要阅读本系列。

1.1 C++ 语言概述与框架

1. 典型实例

C++
#include <iostream> //头文件包含指令 | “//”:注释符号 | “#”:编译指令using namespace std; //指定名字空间 | int:对应main函数返回整数int main() //main函数 | 程序中有且仅有一个main函数{int i, j; //说明变量cout << "输入i和j: "; //输出提示信息cin >> i >> j; //从键盘上输入变量值 | cin >>:输入cout << "sum: " << i + j << endl; //输出变量值 | cout <<:输出 | endl:输出换行return 0; //返回结果}//分号“;”:“语句”结束(#include是指令,int main()也是指令,不用分号)

2. C++ 程序的组成部分

常见的 C++ 程序的默认框架

C++
#include <iostream>using namespace std;int main(){	//语句在此 xxxxxx;return 0;}

3. C++ 中的注释

注释的文字不会在程序运行的时候被执行,能起到解释代码的作用。

① 单行注释:以//开始,换行后结束。

C++
int a; //我是注释我是注释我是注释

② 多行注释:以 /*开始,以*/结束。

C++
int a;/*我们是注释我们是注释我们是注释我们是注释我们是注释我们是注释*/int b;

4. C++ 的字符集.符号.关键字

字符集:只允许直接使用英文字符和阿拉伯数字。(其他字符不推荐使用)

标点符号:必须使用西文符号。

关键字:具有特定含义的英文单词,如 int,不能另作他用。


1.2 C++ 中的数据类型

C++ 程序中的数据具备三种属性:数据类型,名字,值。

1. 数据类型的意义

C++ 为强类型语言,所有变量应“先定义后使用”,数据类型定后无法修改。

2. C++ 中的基本数据类型

数据类型代码表示
整数型int
字符型char
实数型float(单浮点数) double(双浮点数)
逻辑型bool

注: 以上仅包含基本数据类型。

(1) 整数型 int

A. 定义:存放整数数据,存储数据长度和计算机字长有关系。

若定义 1 字节=8 位二进制数(即位数=字节*8),int 长度为 4 字节,容纳的范围就为-2^(31)~2^(31)-1。若数据超出范围,则会溢出。

注:有关于溢出以及字长问题,请参考:计算机补码相关知识

B. 修饰:整型数据经修饰后可以有许多形式。

int 前可以用 short,long,signed,unsigned 修饰

类型长度范围
(signed) short (int)2-2^(15)~(2^(15)-1)
unsigned short (int)20~(2^(16)-1)
(signed) long (int)4-2^(31)~(2^(31)-1)
unsigned long (int)40~(2^(32)-1)
(signed) (int)4-2^(31)~(2^(31)-1)
unsigned (int)40~(2^(32)-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 都用来存放实数,但精度不同。

类型长度范围精度
float4约-10^(38)~10^(38)6~7
double8约-10^(308)~10^(308)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。
  • 实数常量使用的时候应避免不精确问题。
C++
bool a;a = ( 0.1 + 0.2 == 0.3 ); //0.1 + 0.2 实数相加并不是准确 = 0.3cout << a; //结果为0(false)

(3) 字符常量

用一对单引号引的单个字符,类型是 char,在内存中保存的值是字符的 ASCII 码值。如:'a' '@'

注: 转义字符:控制字符无法直接显示和输入,用转义字符间接表示。

常用的转义字符:

转义字符含义备注
'\n'回车
'\t'横向制表一个制表为 8 位,输出整齐
'\nnn'任意字符 8 进制(ASCII)转义如:‘\101’代表字符 A
'\xnn'任意字符 16 进制(ASCII)转义如:‘\x41’字符字符 A(x 必须小写)

例:C++ 中的三个“零”:

形式类型长度值
0整数40
'0'字符148
'\0'字符10

(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-减双目

注: 算术运算符的语法说明

  1. 运算表达式中乘号*不能省略。如:v = a*b*c 不能写为 v = abc。

  2. 当两操作数均为整数,*/*为整除,结果为整数,且是舍去小数的整数。如:5 / 4 = 1; 1 / 2 = 0。 若想让结果不取整,则在操作数部分改为 1.0,2.0 等。如:1.0 / 2 = 0.5。

  3. %为整数求余,只对整数有效,最后符号与被除数同。如:-7 % 6 = -1。

  4. 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||逻辑或双目一真则真,全假则假

注: 逻辑值与数值的转换

逻辑值转数值:

逻辑值数值
true1
false0

数值转逻辑值:

数值逻辑值
非 0true
00

例:逻辑运算符判断连续的关系运算符

判断 a > b > c 写法为 a > b && b > c

注:逻辑表达式的优化和副作用

在求逻辑表达式值的过程中,一旦表达式的值能够确定,就不再进行之后的运算。

例: 如下程序

C++
int a=10, b=20, c=30, d;d = a < b || c++;cout << 'd' << ' ' << 'c' << endl;

求解过程中 a<b 为真,||两侧只要有一侧是真结果便确定,所以右边的 c++ 将不会被计算,c 仍然为 30,结果 d = true,故 d=1。

(6) 位运算符

优先级运算符名称类型
3~按位取反单目
7<<左移双目
7>>右移双目
10&按位与双目
11^按位异或双目
12|按位或双目

常见的位运算符算法:

  • 按位取反 = - n - 1

  • 左移 = a * 2^(n)

  • 右移 = a / 2^(n)

(7) 逗号运算符

用逗号运算符连接起来的表达式称为逗号表达式(优先级最低,为 18)

  • 格式:表达式1,表达式2,……,表达式n
  • 作用:逗号表达式中由左向右每一个表达式都会被运算,整个表达式的值为最后一个表达式的值,常用来连接多个表达式。

例:

C++
int a, x;a = (x = 3, x += 6, 5 + 6)

最后结果 a = 11 x = 9

(8) sizeof() 运算符

常用于计算一个操作数类型或一个变量的字节数。

例: 在 32 位编译器中

C++
sizeof(int) // 4sizeof(float) // 4sizeof(double) // 8

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 时:

C++
int a, b, c;cin >> a >> b >> c;

输入时应输入 1 2 3,才能分别将 1 2 3 赋值到 a b c,如果输入 123 则只能将 a 赋值为 123。

(2) 同时输入多个字符则不需要分隔。

输入字符 char 时:

C++
char a, b, c;cin >> a >> b >> c;

输入时输入 123 或 1 2 3 都可以分别输入成功。

(3) 如果输入过程中如果需要输入空白字符在内的任意字符,则需要使用 cin.get()函数。

  • c = cin.get()
  • cin.get(c)

例:

C++
char a, b, c;cin.get(a);b = cin.get()cin.get(c)cin >> a >> b >> c;

输入时如果输入 1 2 3,则 a 被给 1,b 被给空格,c 被给 2,剩下的空格与 3 丢弃。

2. 输入输出格式控制

<iomanip> 的两个常用函数

(1) setw(int n) 函数

控制输出内容的最短宽度为 n 位,用来帮助对齐。

例: (自己实践,可以打出完美的制表)

C++
for (int i = 1; i <= 100; ++i)cout << i << '/t'

(1) setprecision(int n) 函数

用来控制输出内容的有效数字或小数点的有效位数。

A. 当输出模式为定点小数(fixed)时,控制小数位数。(四舍五入)

例:

C++
cout << fixed << setprecision(2) << 100.0 / 7 << endl;

输出结果为 14.29。

B. 当输出模式为默认时,控制有效数字。

例:

C++
cout << setprecision(2) << 100.0 / 7 << endl;

输出结果为 14。

当输出模式为科学技术(scientific)时,控制实数部分小数位数。

例:

C++
cout << scientific << setprecision(2) << 100.0 / 7 << endl;

输出结果为 1.43e+01。(控制实数 1.43 的小数位数)

分享文章