变量与类型
变量就是一个标识符或者名称,通过变量赋值,可以将要操作的数据与这个标识符关联起来,以后就可以用这个变量来代替这个数据进行运算了。
你可以把变量想像成一个小盒子,这个小盒子有不同的类型,用来存储各种各样的东西,为了方便,你可以给这个小盒子取一个名字,这样就可以更方便地找到东西。
比如,你可以创建一个名为 score
的变量来存储你的考试成绩,或者创建一个名为 age
的变量来存储你的年龄。当你需要使用这些数据时,只需要访问对应的变量,就可以得到存储在里面的值。
变量基础
我们在上一章中讲解算术运算时有这样一个例子:
#include <iostream>using namespace std;
int main() { cout << 5 + 2 << endl; // 求和 cout << 5 - 2 << endl; // 求差 cout << 5 * 2 << endl; // 求积 cout << 5 / 2 << endl; // 求商 cout << 5 % 2 << endl; // 求余
return 0;}
可以发现这里都是关于 5 与 2 的运算,如果要改成 8 与 3 的运算呢?就得一个一个把所有的 5 换成 8,2 换成 3,有点麻烦。
实际上,我们可以用变量来做一个替换,如下改动:
int a = 5;int b = 2;
cout << a + b << endl;cout << a - b << endl;cout << a * b << endl;cout << a / b << endl;cout << a % b << endl;
计算结果不变,但整个程序其实更「好」一些了,因为如果要将程序改为 8 和 3 的运算,只需要更改一下 a 和 b 就行了。
int a = 8;int b = 3;
剩下的都不用换了,这就是使用变量带来的好处。
变量定义
上图定义了一个变量,变量的类型为 int
,表示整数(integer),变量名为 height
,它的值为 175 。实际应用中,定义这个变量可能是为了表示身高,值为 175 代表 175cm。
需要注意的是,与我们在数学中所学的等式不一样,这里的等号 =
并不是判断左右两边的值是否相等,而是赋值操作符号,表示将等号右边的值 175
赋值给等号左边的变量 height
,经过赋值后,当使用变量 height
时,它的值就是 175 了。
后面会讲到,在 C++ 中,判断两个数或两个变量是否相等,我们是用两个等号
==
来表示的,例如height == 175
表示判断变量height
的值是否等于 175
理解了赋值操作,下面的代码就容易明白是什么意思了。
int height = 175;height = height + 5;
从数学上来看,上面的第 2 行代码是不成立的,而在编程中,第 2 行代码的含义表示:将等号右边的表达式 height + 5
的结果计算出来,应该是 180,然后赋值给等号左边的变量 height
。赋值后,变量 height
的值就是 180 了。
变量命名
变量命名,需要遵循一定的原则,
- 变量名只能由字母、数字 和 下划线 _ 组成
- 变量名不能以数字开头
- 不能使用语言相关的 保留关键字
比如,下面的几组变量名,看看是否合法?
3a
,错误命名,变量名不能以数字开头a3
,正确命名max-v
,错误命名,变量名只能由 字母、数字 和 下划线 _ 组成max_v
,正确命名_max
,正确命名name&size
,错误命名,变量名中不能包含不允许的特殊字符cout
,错误命名,保留关键字
除此之外,给变量命名时,尽可能有意义,容易识别。
顺序执行
从前面的程序大家应该有发现,我们编写的程序是按从上到下的顺序依次执行的。这种方式称之为顺序结构(Sqeuence)。下面是顺序结构的示意流程图。
就像我们按照说明书去拼乐高,一定是按照说明书中的步骤,按步骤1、步骤2、步骤3 … 这样的顺序依次去拼搭完成的。顺序结构也是我们在程序中接触到的一种最简单的流程结构。
如果有下面的代码,大家判断一下程序执行的结果应该是什么呢?
#include <iostream>using namespace std;
int main() { int a = 5; cout << a << endl; int b = 3; cout << b << endl;
b = a + 2; a = b * 5; cout << a << endl; cout << b << endl;
a = b + a; cout << a << endl;
return 0;}
这段代码执行后,最终 a
和 b
的值分别是多少呢?大家可以自己先判断一下,再动手去写一写,看看运行的结果是什么,是否与自己的判断一致。
变量类型
在 C++ 中,每个变量都有指定的类型,而变量的类型决定了变量存储所占用内存空间的大小,而变量的大小也决定了变量所能表示的数据范围。
下表列出了一些常见的变量基础类型及其表示范围,作为参考。
实际上变量的类型比上表中列出的要复杂很多,更多的变量类型及表示范围介绍见附录中的参考资源链接。
正是由于不同变量都有不同的大小及取值范围,我们在解决实际问题时,特别需要注意根据需求来选取不同的变量类型。
比如说,如果题目的输入描述写到:输入一个正整数 ,那我们在定义变量的时候,就不能选取 int
类型,因为 的取值范围已经超过 int
所能表示的数据范围了,可以选取 long long
类型。
变量的大小
每种变量类型都有对应的大小,当我们在创建一个变量时,会在内存中申请并开取对应大小的空间。
我们可以通过 sizeof()
来查看不同变量类型所占空间的大小。
#include <iostream>using namespace std;
int main() { cout << "char: " << sizeof(char) << " byte" << endl; cout << "int: " << sizeof(int) << " bytes" << endl; cout << "float: " << sizeof(float) << " bytes" << endl; cout << "double: " << sizeof(double) << " bytes" << endl; cout << "long long: " << sizeof(long long) << " bytes" << endl; cout << "long double: " << sizeof(long double) << " bytes" << endl;
return 0;}
程序运行结果:
char: 1 byteint: 4 bytesfloat: 4 bytesdouble: 8 byteslong long: 8 byteslong double: 16 bytes
字节(byte)是计算机中的一种计量单位,常于表示存储容量的大小,我们在后面有专门的章节会讲到不同的计量单位以及它们之间的转换关系。
变量类型转换
有时候需要对变量的类型进行转换,转换有隐式与显示(强制)转换两种方式。
隐式转换
变量的隐式转换是自动进行的,由 C++ 编译器根据类型的兼容性进行推断和自动执行的。通常来说,转换的目标类型精度比源类型更高一些。
例如,当把一个整数值(int)赋值给一个浮点数(float)变量时,会发生隐式转换:
int a = 10;float b = a; // 隐式将整数类型转换为浮点数类型
再看一个精度丢失的隐式转换例子:
int a = 5;int b = 2;cout << a / b << endl; // 结果为 2,丢失了精度
当两整数类型的数相除时,结果自动保留为整数,按理来说,5 除以 2 应该等于 2.5,但由于结果保留为整数,计算结果的小数部分自动丢掉了,一定要小心这样容易带来的问题。
显式转换
显式转换又称为强制转换,就是由开发人员明确指定转换操作符,强制改变变量的数据类型。
例如,下面的代码显式的将变量 a
转换为浮点数类型来进行计算。
int a = 5;int b = 2;cout << float(a) / b << endl; // 正确输出结果 2.5
在编写代码时,为了确保运算结果的正确性,我们需要选择适当的类型转换方式。无论是隐式转换还是显式转换,都需要注意类型转换可能带来的精度损失和数据溢出问题,在显式转换时应该谨慎使用。
常量
如果一个程序中的某个数据永远不需要改动,最好将其定义为常量,常量的定义方式非常简单,在变量定义的数据类型前加上关键字 const
即可。
例如,在计算圆的面积时,数字中的 应该是一个常量,可以像下面这样定义:
#include <iostream>using namespace std;
const float PI = 3.14; // 定义常量 PI
int main() { float r; cin >> r;
cout << PI * r * r << endl; return 0;}
通常来说,常量我们会用全大写字母来表示,这是一个好的习惯(并非必须),当在阅读程序时,很容易区分出程序中哪些是常量,哪些不是。
小结
变量是程序设计中一个非常重要的核心概念,它在程序中起到了存储和传递数据的作用,使得我们能够进行计算、逻辑判断和操作。合理的使用变量,可以提高代码的可读性、可维护性和重用性。