跳到主要内容

变量介绍

在本课中,我们将讨论如何在程序运行时存储不同的值——也就是说,如何使用变量。

动机

为了理解它们的用途,我们来编写一个程序,将一个数字提升到三次方,然后显示它。

main.cpp | 三次方
#include <iostream>

int main()
{
std::cout << 212 * 212 * 212;
}
结果(控制台)
9528128

如果我们现在想将另一个数字提升到三次方,我们将不得不更改代码中的三个地方。这很繁琐。

解决方案

为了避免每次都更改这么多东西,我们暂时假设我们要幂次的数字叫做x。那么代码会是什么样子呢?

#include <iostream>

int main()
{
std::cout << x * x * x;
}

这个阶段的上述程序将无法编译。要在计算中使用x,我们首先需要创建一个名为x变量

#include <iostream>

int main()
{
int x = 212;
std::cout << x * x * x;
}

上述程序将正确编译并运行。

变量定义

变量是一个命名的“容器”,用于保存程序中可以使用的特定类型的信息。它的值可以改变,但类型不能。

变量就像一个贴了标签的盒子,你可以根据需要往里面放东西或从中取出东西。

创建变量

在上面的程序中,我们这样创建了变量

int x = 212;
Scheme for creating a variable (with initialization)

这是一个重要的符号,在你的编程生涯中你会经常看到。在接下来的章节中,我们将解释这个符号的不同部分意味着什么。

变量类型

Overview of a variable definition - type

变量的类型告诉你变量可以存储什么。如前所述,变量是存储特定类型事物的容器。

intinteger(整数)的缩写,即没有小数部分的数字(一个整数)。

在此阶段,您应该记住以下变量类型

类型描述
int整数(整型)
float实数(带小数部分)
char单个字符
bool布尔值,即truefalse

未来我们将介绍更多类型及其相关事实。

注意

上述变量类型始终用小写字母书写。这很重要,C++ 是大小写敏感的!

创建变量的例子:

// Without initialization
// Variable will contain an unpredictable value
int x;

// We create a variable and assign the 30 value to it
int y = 30;

变量名

Overview of a variable definition - name

名称可以是任何你想要的,但有一些重要的限制

  • ❌ 不得有空格(禁止:❌ abc def
  • ❌ 不允许大多数符号
  • ✔ 可以由以下组成
    • ✔ 字符 a-zA-Z
    • ✔ 数字,但不能在开头(禁止:❌ 932abc
    • ✔ 下划线 _
关于下划线的额外注意事项

虽然下划线允许在名称中使用,但有少数情况是C++保留的

  • 以大写字母开头的下划线(禁止:❌ _Speed
  • 双下划线开头(禁止:❌ __xyz

您可以创建任意数量的变量,但它们必须具有不同的名称,因为它们是唯一的标识符(有一些例外,但我们稍后会详细介绍)。

大小写很重要,变量名是大小写敏感的

int x = 30;
float X = 12.34f;

在上面的代码中,变量xX是两个不同的变量!

良好实践(对于非英语使用者)

最好使用英文名称,例如

float average;

而不是

float srednia; // average in Polish

初始化(初始值)

初始化是创建变量的可选步骤。创建时,我们可以不设置初始值

int x;

或者给它赋一个初始值

int x = 30;
未初始化

一个未初始化的变量,在函数块内部(例如在main内部)最初会有一个不可预测的值,它不会被重置为0。

将变量不赋初始值可能会在代码后期导致问题。然而,有时我们可能会有意跳过它,但稍后会详细介绍。

当变量处于未初始化状态时,你绝不能从中读取!

末尾的分号

只是提醒一下😀

int age = 40;

机会

在本节中,我只会向您展示几种使用变量的方法,而它们的解释将在下一课中。

接收用户输入

要接收用户输入,我们可以创建一个未初始化的变量,然后告诉C++将用户的响应放入该变量中。

#include <iostream>

int main()
{
int age; // current age (note: uninitialized!)
std::cout << "Enter your age: ";
std::cin >> age;
std::cout << "In 10 years you will be: " << age + 10 << " years\n";
}

分解复杂方程

我们可以使用变量来表示复杂方程中的中间值。这有助于提高代码的可读性和可维护性。

🗒️ main.cpp
#include <iostream>

int main()
{
float current_pos = 10; // in meters
float target_pos = 20; // in meters
float current_speed = 2.5f; // in meters/second
float time_remaining = 0.5f; // in seconds

// Calculate where we will end up once time runs out
float ending_pos = current_pos + current_speed * time_remaining;

// Calculate how far away we landed from the target
float error = target_pos - ending_pos;

// Calculate the required speed needed to land directly on the target
float required_speed = (target_pos - current_pos) / time_remaining;

// Calculate the amount of extra speed we needed to land directly on the target
float extra_speed_needed = required_speed - current_speed;

std::cout << "We landed " << error << " meters away from the target.\n";
std::cout << "We needed to go " << extra_speed_needed << "m/s faster to land on the target.";
}
结果(控制台)
We landed 8.75 meters away from the target.
We needed to go 17.5m/s faster to land on the target.

总结

总而言之,我们学到了

附加信息

缺乏初始化

示例
int main() {
int x; // No initializer
}

一个未初始化的变量(开始时没有赋值),在函数块内部(例如在main内部)开始时会有一个不可预测的值(即,它不会被设置为零)。如果在使用它之前就读取它,那么将变量不赋初始值可能会在代码执行后期导致问题

虽然在语言中存在这种错误的可能性可能看起来很奇怪,但我们有时会故意这样做。从用户接收输入展示了其中一个原因。

类型转换

变量有一个特定的类型,不能在代码的不同地方随意更改。我们尝试写入它的值必须与其类型匹配。但是,如果您在不匹配类型的情况下赋值,许多类型将自动转换。例如,我们可以将整数值(int)写入float类型(实数)的变量。这会触发从intfloat的转换。

示例
float y = 30; // OK - 30 is converted to 30.0f

反向操作则有些问题。int类型的变量不能存储小数部分,所以当我们尝试将float值写入它时,它会被转换成一个没有小数部分的数字。

C++ 不是通过四舍五入来完成的——相反,它通过截断来完成。数字的小数部分被完全砍掉并丢弃。例如,3.1415 截断为 3

⚠ 隐式转换
int y = 30.5f; // OK, 30.5f is converted to 30, but information lost!

编译器可能会发出警告,提示存在隐式缩小转换。此警告的存在是因为程序员经常不小心编写此类代码,导致小数部分丢失,从而导致我们值中的错误。

注意

尽可能匹配类型!从 floatint 的隐式转换会导致信息丢失!这在最好的情况下会导致错误的结果,在最坏的情况下甚至会导致灾难。阿丽亚娜 5 型火箭 V88 号航班在发射后 37 秒发生灾难性爆炸,原因就是从 floatint 的错误转换,导致精度损失,使导航计算机停止工作。

变量介绍

在本课中,我们将讨论如何在程序运行时存储不同的值——也就是说,如何使用变量。

动机

为了理解它们的用途,我们来编写一个程序,将一个数字提升到三次方,然后显示它。

main.cpp | 三次方
#include <iostream>

int main()
{
std::cout << 212 * 212 * 212;
}
结果(控制台)
9528128

如果我们现在想将另一个数字提升到三次方,我们将不得不更改代码中的三个地方。这很繁琐。

解决方案

为了避免每次都更改这么多东西,我们暂时假设我们要幂次的数字叫做x。那么代码会是什么样子呢?

#include <iostream>

int main()
{
std::cout << x * x * x;
}

这个阶段的上述程序将无法编译。要在计算中使用x,我们首先需要创建一个名为x变量

#include <iostream>

int main()
{
int x = 212;
std::cout << x * x * x;
}

上述程序将正确编译并运行。

变量定义

变量是一个命名的“容器”,用于保存程序中可以使用的特定类型的信息。它的值可以改变,但类型不能。

变量就像一个贴了标签的盒子,你可以根据需要往里面放东西或从中取出东西。

创建变量

在上面的程序中,我们这样创建了变量

int x = 212;
Scheme for creating a variable (with initialization)

这是一个重要的符号,在你的编程生涯中你会经常看到。在接下来的章节中,我们将解释这个符号的不同部分意味着什么。

变量类型

Overview of a variable definition - type

变量的类型告诉你变量可以存储什么。如前所述,变量是存储特定类型事物的容器。

intinteger(整数)的缩写,即没有小数部分的数字(一个整数)。

在此阶段,您应该记住以下变量类型

类型描述
int整数(整型)
float实数(带小数部分)
char单个字符
bool布尔值,即truefalse

未来我们将介绍更多类型及其相关事实。

注意

上述变量类型始终用小写字母书写。这很重要,C++ 是大小写敏感的!

创建变量的例子:

// Without initialization
// Variable will contain an unpredictable value
int x;

// We create a variable and assign the 30 value to it
int y = 30;

变量名

Overview of a variable definition - name

名称可以是任何你想要的,但有一些重要的限制

  • ❌ 不得有空格(禁止:❌ abc def
  • ❌ 不允许大多数符号
  • ✔ 可以由以下组成
    • ✔ 字符 a-zA-Z
    • ✔ 数字,但不能在开头(禁止:❌ 932abc
    • ✔ 下划线 _
关于下划线的额外注意事项

虽然下划线允许在名称中使用,但有少数情况是C++保留的

  • 以大写字母开头的下划线(禁止:❌ _Speed
  • 双下划线开头(禁止:❌ __xyz

您可以创建任意数量的变量,但它们必须具有不同的名称,因为它们是唯一的标识符(有一些例外,但我们稍后会详细介绍)。

大小写很重要,变量名是大小写敏感的

int x = 30;
float X = 12.34f;

在上面的代码中,变量xX是两个不同的变量!

良好实践(对于非英语使用者)

最好使用英文名称,例如

float average;

而不是

float srednia; // average in Polish

初始化(初始值)

初始化是创建变量的可选步骤。创建时,我们可以不设置初始值

int x;

或者给它赋一个初始值

int x = 30;
未初始化

一个未初始化的变量,在函数块内部(例如在main内部)最初会有一个不可预测的值,它不会被重置为0。

将变量不赋初始值可能会在代码后期导致问题。然而,有时我们可能会有意跳过它,但稍后会详细介绍。

当变量处于未初始化状态时,你绝不能从中读取!

末尾的分号

只是提醒一下😀

int age = 40;

机会

在本节中,我只会向您展示几种使用变量的方法,而它们的解释将在下一课中。

接收用户输入

要接收用户输入,我们可以创建一个未初始化的变量,然后告诉C++将用户的响应放入该变量中。

#include <iostream>

int main()
{
int age; // current age (note: uninitialized!)
std::cout << "Enter your age: ";
std::cin >> age;
std::cout << "In 10 years you will be: " << age + 10 << " years\n";
}

分解复杂方程

我们可以使用变量来表示复杂方程中的中间值。这有助于提高代码的可读性和可维护性。

🗒️ main.cpp
#include <iostream>

int main()
{
float current_pos = 10; // in meters
float target_pos = 20; // in meters
float current_speed = 2.5f; // in meters/second
float time_remaining = 0.5f; // in seconds

// Calculate where we will end up once time runs out
float ending_pos = current_pos + current_speed * time_remaining;

// Calculate how far away we landed from the target
float error = target_pos - ending_pos;

// Calculate the required speed needed to land directly on the target
float required_speed = (target_pos - current_pos) / time_remaining;

// Calculate the amount of extra speed we needed to land directly on the target
float extra_speed_needed = required_speed - current_speed;

std::cout << "We landed " << error << " meters away from the target.\n";
std::cout << "We needed to go " << extra_speed_needed << "m/s faster to land on the target.";
}
结果(控制台)
We landed 8.75 meters away from the target.
We needed to go 17.5m/s faster to land on the target.

总结

总而言之,我们学到了

附加信息

缺乏初始化

示例
int main() {
int x; // No initializer
}

一个未初始化的变量(开始时没有赋值),在函数块内部(例如在main内部)开始时会有一个不可预测的值(即,它不会被设置为零)。如果在使用它之前就读取它,那么将变量不赋初始值可能会在代码执行后期导致问题

虽然在语言中存在这种错误的可能性可能看起来很奇怪,但我们有时会故意这样做。从用户接收输入展示了其中一个原因。

类型转换

变量有一个特定的类型,不能在代码的不同地方随意更改。我们尝试写入它的值必须与其类型匹配。但是,如果您在不匹配类型的情况下赋值,许多类型将自动转换。例如,我们可以将整数值(int)写入float类型(实数)的变量。这会触发从intfloat的转换。

示例
float y = 30; // OK - 30 is converted to 30.0f

反向操作则有些问题。int类型的变量不能存储小数部分,所以当我们尝试将float值写入它时,它会被转换成一个没有小数部分的数字。

C++ 不是通过四舍五入来完成的——相反,它通过截断来完成。数字的小数部分被完全砍掉并丢弃。例如,3.1415 截断为 3

⚠ 隐式转换
int y = 30.5f; // OK, 30.5f is converted to 30, but information lost!

编译器可能会发出警告,提示存在隐式缩小转换。此警告的存在是因为程序员经常不小心编写此类代码,导致小数部分丢失,从而导致我们值中的错误。

注意

尽可能匹配类型!从 floatint 的隐式转换会导致信息丢失!这在最好的情况下会导致错误的结果,在最坏的情况下甚至会导致灾难。阿丽亚娜 5 型火箭 V88 号航班在发射后 37 秒发生灾难性爆炸,原因就是从 floatint 的错误转换,导致精度损失,使导航计算机停止工作。