C++ 变量、运算与顺序结构

前言

本文记录 C++ 相关的变量、运算输入输出的相关知识。

在阅读过程中有任何问题都可以发布到评论区,有价值的问题将会放到文章末尾Q&A之中!

什么是编程

编程是编写程序代码的中文简称,就是让计算机代码解决某个问题,对某个计算体系规定一定的运算方式,使计算体系按照该计算方式运行,并最终得到相应结果的过程。

通俗来讲,编程就是人类和计算机沟通的一种语言

C++语言基本框架

1
2
3
4
5
6
7
8
#include <iostream>		// 头文件

using namespace std; // 使用 std 命名空间

int main(){ // 函数入口【主函数】
……; // 程序编写区
return 0; // 返回值
}

头文件

C++ 语言中定义了一部分头文件,在这些头文件之中包含一部分已有的函数【功能】,可以在编写程序的过程中直接调用即可。

程序内片段

在上述代码片段中,首行代码就是调用头文件的过程,格式为:#include <头文件名>

1
#include <iostream>

<iostream> 头文件中内置了基本的输入、输出、换行函数:cin、cout、endl

学过 Python 的同学,在 Python 学习的过程中也需要调用库C++ 中头文件的作用是和 Python 中库的作用是类似的。

常用头文件

在 C++ 中,常用的头文件有如下一些:

1
2
3
4
#include <iostream>		// 内置输入输出流函数:cin、cout、endl等等
#include <cstdio> // 内置格式化输入输出函数:scanf,printf等等
#include <math> // 内置一些常用的数学符号:根号 sqrt、幂 pow、绝对值 abs 等等
#include <algorithm> // 内置一些简单算法:排序 sort、取最大值 max、最小值 min 等等

命名空间

命名空间是 C++ 中一个相对新的概念。其主要作用是为了避免命名冲突

在 C++ 运行的过程中,为了避免变量的命名与关键词冲突,会调用命名空间来限制冲突,可以更好的编写和维护代码。

程序内片段

在上述代码片段中,第二行代码就是调用头文件的过程,格式为:using namespace 命名空间名;

1
using namespace std;

std 命名空间中包含基本的 cin cout endl 等等函数名。

可以尝试运行缺少调用命名空间的程序。

1
2
3
4
5
6
#include <iostream>		// 头文件

int main(){ // 函数入口【主函数】
cout << "Hello World!" << endl;
return 0; // 返回值
}

运行之后会发现 coutendl 函数未被定义,同时提示调用命名空间

调用方法

调用命名空间有两种常用的方法

第一种就是像上述代码片段中,直接在头文件之后使用 using namespace XXX; 进行调用。

1
2
3
4
5
6
7
8
#include <iostream>

using namespace std; // 使用 std 命名空间

int main(){
cout << "Hello World!" << endl;
return 0;
}

第二种方法就是在使用函数时,在函数前加上该命名空间名,并且用 :: 链接。

1
2
3
4
5
6
#include <iostream>

int main(){
std::cout << "Hello World!" << std::endl; // 直接程序内调用
return 0;
}

主函数【程序入口】

主函数是 C++ 中必须要有的部分,必须以 main() 进行命名。

主函数是所有程序内容的入口,一段 C++ 程序就是从 main 函数 开始运行的。

主函数必须定义为 int 类型,同时在程序结束是返回值为 0【return 0;】

对于函数类型的知识点,在之后的函数篇章内具体讲解。

程序内片段

在上述代码中,主函数片段如下:

1
2
3
4
int main(){
……;
return 0;
}

任何函数都是通过大括号 { }来规定函数范围的。

学习过 Python 的同学,在 Python 中函数内容是通过缩进来规定函数范围的,在 C++ 中所有的函数都是通过大括号来规定的。

返回值

在 C++ 的函数运行过程中,返回值是标记程序是否正常结束的标志。

返回值为 0 时,表示程序正常结束

否则,当其为非 0 值时,表示程序出现错误

其他

括号

在 C++ 程序编写的过程中,要区分各种括号的区别。

< > 一般用于头文件的调用等等。

{ } 一般用于判断、循环、函数的范围限制等等。

[ ] 一般用于数组的定义等等。

( ) 一般用于运算、函数参数的传递等等。

分号

在 C++ 程序编写的过程中,要注意  ;  的使用。

具体的使用规则在后续每个模块学习的过程中会详解。

英文输入

在 C++ 程序编写的过程中,除注释外,所有的内容都要用英文输入,包括所有的符号。

注释

在 C++ 中,注释有两种写法。

  • 单行注释:使用 // 表明注释范围,// 后的内容为注释内容,不参与编译。
  • 多行注释:使用/* ... */表明注释范围。

变量

不管使用编程语言进行编程时,都需要用到各种变量存储各种信息。变量保留的是它所存储的值的内存位置

这意味着,当您创建一个变量时,就会在内存中保留一些空间

数据类型

在 C++ 中,常用的数据类型有如下几种:

类型 关键字 示例
布尔型 bool true, false
字符型 char ‘a’, ‘A’, ‘ ‘, ‘\n’
整型 int 1, 3, 1231231,123
浮点型 float 1.2, 231.45, 1.235e2
双浮点型 double 1.2, 231.45, 1.235e2
无类型 void -

数据范围

在 C++ 中,不同的数据类型所能表示的数据范围也是不同的,这具体取决于不同的数据类型在内存中所占的位数

在这里注意内存中单位的转化。

1 位 = 1 字节 = 8 比特

【1 Byte = 8 bit】

类型 范围
char 1 个字节 -128 到 127 或者 0 到 255
int 4 个字节 -2147483648 到 2147483647 【-2^31 ~ 2^31 - 1】
float 4 个字节 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字)
double 8 个字节 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字)

那这个范围是如何计算的呢?为什么负数范围比正数多一个呢?

在计算机内部,数据都是以补码的形式存储到内存中的,每一种类型可以表示的范围都是不同的

原码,反码,补码

在计算机中,数据都是以二进制形式存储的,也就是都是以 01 序列 字符串存储的。

在此基础上,对于数据有三种不同的存储方式,也就是原码、反码和补码

在编码过程中,用首位作为符号位,首位为 0 表示正数、首位为 1 表示负数

对于正数来说,原码、反码和补码的表示形式都是相同的

对于负数来说:

反码是在原码的基础上,符号位不变,其他所有位取反得到的

补码是符号位不变,反码+1 得到的。

十进制 原码 反码 补码
90 01011010 01011010 01011010
-90 11011010 10100101 10100110

因此,对于负数来说,可以全部都为 1 表示最大的负数

但是,对于正数来说,因为第一位为符号位,只能为 0,最大值仅为 01111111……,所以正数范围的最大值要 -1

变量定义

在 C++ 中,定义变量时要有固定的格式:变量类型 变量名 赋值;

多个同类型变量定义时用 , 隔开。

浮点数的赋值可以用科学计数法

赋值可以省略。

1
2
3
4
5
6
7
8
9
10
// 定义类型为整数型,变量名为 a 的变量,不赋值
int a;
// 定义三个整数型变量,用逗号隔开,同时给 c 变量赋值,d 变量赋值为 c 变量的值
int b, c = 10, d = c;
// 定义三个双精度浮点数的变量
double e, f = 1.2345, g = 1.23e4;
// 定义一个字符型变量
char h;
// 定义一个布尔型变量
bool i;

作用域

变量处于不同的位置有着不同的效果,可以作用的范围也不同。该范围一般称为作用域

在 C++ 中,变量常用的作用域有局部变量,全局变量,形式变量【形式参数】

局部变量

在函数或一个代码块内部声明的变量,称为局部变量

通俗来讲,在一个 { } 内部定义的变量就被称为局部变量,其作用域也仅限于该 { } 内部

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

using namespace std;

int main(){
// x 作用域为整个 main 函数内部
int x = 10;
if(x >= 10){
// y 作用域为 if 函数内部
int y = 100;
}
for(int i = 0; i < 10; i ++){
// z 作用域为 for 函数内部
int z = 1000;
}
cout << x << endl;
cout << y << endl;
cout << z << endl;
}

运行上述代码,x 可以正常输出,y 和 z 会报错。

全局变量

在所有函数外部声明的变量,称为全局变量

一般来说,全局变量直接定义到头文件和命名空间下方

全局变量在任何一个函数中都可以使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

// 全局变量声明
int g;

int main ()
{
// 局部变量声明
int a, b;

// 实际初始化
a = 10;
b = 20;
g = a + b;

cout << g << endl;

return 0;
}

在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;

// 全局变量声明
int g = 20;

int main ()
{
// 局部变量声明
int g = 10;

cout << g << endl;

return 0;
}

形式变量【形式参数】

在函数参数的定义中声明的变量,称为形式参数

具体的使用方法在后续的函数课程内容中会讲解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

using namespace std;

// x 和 y 为 add 函数的形式参数
int add(int x, int y){
return x + y;
}

int main(){
int n = 10, m = 15;
int ans = add(n, m);
cout << ans << endl;
return 0;
}

输入/输出

C++ 常用的输入输出方式有两种

  • 第一种是基于 iostream 头文件下的输入输出流函数
  • 第二种是基于 cstdio 头文件下的标准输入输出函数

输入输出流

使用输入输出流函数来实现程序的输入输出时,无需考虑变量类型,输入输出都是同样的格式。

  • 输入:cin >> 变量名1 >> 变量名2;
  • 输出:cout << 变量名1 << 变量名2;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 调用 iostream 头文件
#include <iostream>

using namespace std;

int main(){
int a;
double b;
char c;

// 输入函数 cin
cin >> a >> b >> c;

// 输出函数 cout,换行函数 endl
cout << a << b << c << endl;
return 0;
}

标准输入输出

使用标准输入输出来实现程序的输入输出时,需考虑变量类型,不同的类型对应的格式不同。

在输入输出的过程中都需要声明变量类型

在输入的过程中,要注意标明地址符【&】

因为在输入的过程中是需要在计算机的内存中申请一块地址后将变量存储到该地址的,所以要声明地址符。

输入格式:scanf(“标准格式”, &变量名);

在输出的过程中,无需声明地址符

因为在输出的过程中说明该变量已经存储到内存中,直接读取该变量值即可。

输出格式:printf(“标准格式”, 变量名);

变量类型 声明 标准格式
整数型 int %d
单精度浮点数 float %f
双精度浮点数 double %lf
字符型 char %c
长整数型 long long %lld
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <cstdio>

using namespace std;

int main(){
// 变量声明
int a;
float b;
double c;
char d;
long long e;

// 标准输入
scanf("%d", &a);
scanf("%f", &b);
scanf("%lf", &c);
scanf("%c", &d);
scanf("%lld", &e);

// 标准输出, \n 表示换行
printf("%d\n", a);
printf("%f\n", b);
printf("%lf\n", c);
printf("%c\n", d);
printf("%lld\n", e);

return 0;
}

区别

在 C++ 中,上述两种方式都可以控制输入输出,那么区别是什么呢。

保留小数位

使用输入输出流函数时,想要保留小数位需要调用函数进行保留。

需要使用 iomanip 库中的 setprecision 函数和 fixed 函数。 setprecision 用于设置数字的精度,而 fixed 用于保证数字以固定点的方式输出。

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <iomanip>

using namespace std;

int main() {
double num = 3.14159;
cout << fixed << setprecision(2) << num << endl;
return 0;
}

使用标准输入输出函数时,想要保留小数位只需在输出函数中表明要保留的位数即可。

格式:printf(“%.2lf”, c);

1
2
3
4
5
6
7
8
9
#include <cstdio>

using namespace std;

int main() {
double num = 3.14159;
printf("%.2lf\n", num);
return 0;
}

格式化输出

使用输入输出流函数时,想要格式化输出需要调用函数。

可以使用iomanip库中的函数来实现格式化输出。以下是一些常用的格式化操作:

  • setprecision(n): 设置浮点数的精度为n位。
  • fixed: 使用定点表示法来表示浮点数。
  • scientific: 使用科学表示法来表示浮点数。
  • setw(n): 设置下一个输出值的宽度为n个字符。
  • left: 输出左对齐。
  • right: 输出右对齐。
  • setfill(c): 在未填充的部分使用字符c来填充。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <iomanip>

using namespace std;

int main() {
int width = 10;
cout << right << setw(width) << "Hello" << endl; // 输出宽度为10的右对齐字符串

char fill_char = '*';
cout << setfill(fill_char) << setw(width) << "World" << endl; // 使用'*'来填充宽度不足的部分

return 0;
}

使用标准输入输出函数时,想要保留小数位只需在输出函数中表明要使用的格式即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <cstdio>

using namespace std;

int main(){
int a = 12, b = 123, c = 1234;
double d = 1.2345;

// 宽度为 5 左对齐输出
printf("%5d\n", a);
printf("%5d\n", b);
printf("%5d\n", c);

// 宽度为 5 ,不足位补 0 输出
printf("%05d\n", a);
printf("%05d\n", b);
printf("%05d\n", c);

// 宽度为 5 右对齐输出
printf("%-5d\n", a);
printf("%-5d\n", b);
printf("%-5d\n", c);

// 宽度为 5,保留两位输出
printf("%5.2lf\n", d);

return 0;
}

运算

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。

基本的运算符包括简单的加【+】减【-】乘【*】除【/】

在 C++ 语言中,额外的运算还包括取余数【%】自增1【++】自减1【–】

除此之外,C++ 中还有一些特殊的基本运算符,例如 sizeof 用来求变量所占字节数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>

using namespace std;

int main(){
int a = 21;
int b = 10;
int c;

c = a + b;
cout << "Line 1 - c 的值是 " << c << endl ;
c = a - b;
cout << "Line 2 - c 的值是 " << c << endl ;
c = a * b;
cout << "Line 3 - c 的值是 " << c << endl ;
c = a / b;
cout << "Line 4 - c 的值是 " << c << endl ;
c = a % b;
cout << "Line 5 - c 的值是 " << c << endl ;

int d = 10; // 测试自增、自减
c = d++;
cout << "Line 6 - c 的值是 " << c << endl ;

d = 10; // 重新赋值
c = d--;
cout << "Line 7 - c 的值是 " << c << endl ;

int e = 10;
char f = 'a';
int g[100];
cout << "e 所占字节长度为:" << sizeof e << endl;
cout << "f 所占字节长度为:" << sizeof f << endl;
cout << "g 所占字节长度为:" << sizeof g << endl;

return 0;
}

强制转化

Q&A