且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《C++游戏编程入门(第4版)》——1.5 声明和初始化变量

更新时间:2022-09-22 22:14:34

本节书摘来自异步社区出版社《C++游戏编程入门(第4版)》一书中的第1章,第1.5节,作者:【美】Michael Dawson(道森),更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.5 声明和初始化变量

C++游戏编程入门(第4版)
变量代表了计算机内存的某一部分,该部分被保留下来用于存储、检索和操作数据。

如果需要记录玩家的得分,则可以为它专门创建一个变量。这样一来,就可以读取并显示玩家得分。如果玩家将空中的外星敌人击毙,还可以将得分更新。

1.5.1 Game Stats程序简介

Game Stats程序显示在太空射击游戏中需要记录的诸如玩家得分、击毁敌人数目以及玩家防护盾是否开启等信息。该程序使用了一组变量来完成这些任务。程序如图1.5所示。


《C++游戏编程入门(第4版)》——1.5 声明和初始化变量

图1.5 游戏中每条数据都存储在一个变量中

从Cengage Learning网站(www.cengageptr.com/downloads)上可以下载到该程序的代码。程序位于Chapter 1文件夹中,文件名为game_stats.cpp。

// Game Stats
// Demonstrates declaring and initializing variables
#include <iostream>
using namespace std;
int main()
{
   int score;
   double distance;
   char playAgain;
   bool shieldsUp;
   short lives, aliensKilled;
   score = 0;
   distance = 1200.76;
   playAgain = 'y';
   shieldsUp = true;
   lives = 3;
   aliensKilled = 10;
   double engineTemp = 6572.89;
   cout << "\nscore: "      << score << endl;
   cout << "distance: "    << distance << endl;
   cout << "playAgain: "    << playAgain << endl;
   //skipping shieldsUp since you don't generally print Boolean values
   cout << "lives: "      << lives << endl;
   cout << "aliensKilled: "<< aliensKilled << endl;
   cout << "engineTemp: "   << engineTemp << endl;
   int fuel;
   cout << "\nHow much fuel? ";
   cin >> fuel;
   cout << "fuel: " << fuel << endl;
   typedef unsigned short int ushort;
   ushort bonus = 10;
   cout << "\nbonus: " << bonus << endl;
   return 0;
}```
###1.5.2 基本类型
每个创建的变量都属于某一类型,类型代表了在变量中可以存储的信息的类别。类型告诉编译器需要为变量准备的内存大小,并且定义了能够对变量进行的合法操作。

内置在C++中的基本类型包含了表示布尔值(true或false)的bool型、表示单个字符的char型、表示整数的int型、表示单精度浮点数的float型以及表示双精度浮点数的double型。

###1.5.3 类型修饰符
可以使用修饰符对类型进行修改。short是一个修饰符,它能够缩小变量所能保存值的数目。long也是一个修饰符,它能够扩大变量所能保存值的数目。short能够缩小变量的存储空间,而long则会扩大。short和long可以修饰int型。long还可以修饰double型。

signed和unsigned是只能用于整型的修饰符。signed表示变量既可以存储正数也可以存储负数,而unsigned表示变量只能存储正数。无论signed还是unsigned都无法改变变量所能保存值的数目,而只能改变取值的范围。整型默认使用signed修饰。

是不是对这些类型感到有些迷惑?不用担心。表1.1归纳了常用的类型和修饰符,其中还提供了类型各自的取值范围。

表1.1 常用类型

<div style="text-align: center">
 <img src="https://yqfile.alicdn.com/540c2c55664fe5f230be399f4ea05ea5212cdd3b.png" >
</div>

陷阱
 表中所列取值范围依据的是本书使用的编译器。您的编译器决定的变量取值范围可能不同,具体请查阅所使用编译器的文档。


技巧
 为简洁起见,short int可以缩写成short,long int可以缩写成long。
###1.5.4 变量声明
现在对类型做了初步的介绍,接下来再回到程序。程序所做的第一件事情就是用下面一行代码声明一个变量(请求创建一个变量):

 `  int score;`
这行代码声明了一个名为score的int型变量。我们通过变量名来访问这个变量。可以看到,声明一个变量需要指定变量的类型,然后在其后跟上所选择的变量名。因为声明是语句,所以必须以分号结尾。

接下来的3行代码声明了3种类型的3个变量:distance是double型变量,playAgain是char型变量,shieldsUp是bool型变量。

游戏(以及所有大型应用程序)通常需要大量的变量。好在,C++允许在一条语句中声明同一类型的多个变量,正如下面一行代码所示:

  ` short lives, aliensKilled;`
这一行声明了两个short型变量:lives和aliensKilled。

尽管本例在main()函数开头部分定义了一些变量,但并不意味着必须在一个地方定义所有变量。在该程序后面将看到,我们经常在使用之前才定义某个变量。

###1.5.5 变量命名
要声明一个变量,必须为变量提供一个名称,也就是变量的标识符。合法的标识符只需要满足以下几个规则:

标识符只能包含数字、字母和下画线。
标识符不能以数字开头。
标识符不能是C++关键字。
关键字是C++为其本身使用保留的特殊词汇。关键字不多,详见附录C。

除了创建合法变量名必须遵循的规则外,下面给出一些准则来选择好的变量名。

选择描述性的名称。变量名应该让其他程序员容易理解。例如,使用score而不是s(该规则的一个例外是临时使用的变量。这种情况下,可以使用单字母变量名,如x)。
前后一致。对于多单词变量名的写法,有两种思想流派。是high_score还是highScore?本书使用第二种方式,其中第二个单词(以及其他单词)的首字母是大写。这就是匈牙利命名法。但是只要保持前后一致,使用哪种方法并不重要。
遵循语言的传统。有些命名习惯已经成为传统。例如,大多数语言(包括C++)中,变量名以小写字母开头。另一个传统是避免变量名的首字符使用下画线。以下画线开始的名称有特殊含义。
使用短变量名。尽管playerTwoBonusForRoundOne描述性很强,但是它让代码很难读。另外,长变量名会增加录入错误的风险。作为一条准则,请把变量名限制在15个字符以内。然而,编译器会有一个变量名长度的最终上限。
技巧
 自描述的代码使得在不看注释的情况下也很容易理解程序的用途。良好的变量命名是向这样的代码迈出的一大步。
###1.5.6 变量的赋值
接下来的一组语句对声明过的6个变量进行了赋值操作。下面对几种赋值操作进行详细说明,并讨论它们的变量类型。

1.整型变量的赋值

下面这条赋值语句把0赋给了score。

 ` score = 0;`
现在,score存储的是0。

在变量名之后跟上赋值运算符(=)和一个表达式就可以完成变量的赋值(从技术上来讲,0也是表达式,它的值是0)。

2.浮点型变量的赋值

下面这条语句把1200.76赋给了distance。

 `  distance = 1200.76;`
因为distance是double类型,所以它用来存储带小数部分的数,正如赋值语句那样。

3.字符变量的赋值

下面这条语句将单个字符值'y'赋给了playAgain。

playAgain = ’y’;
正如这行代码所示,可以将用单引号包围的单个字符值赋给char型变量。

char型变量可以分别存储128个ASCII字符值(假设系统使用ASCII字符集)。ASCII的全称是American Standard Code for Information Interchange,是一种字符编码方式。完整的ASCII列表详见附录D。

4.布尔型变量的赋值

下面这条语句将true赋给了shieldsUp。

`shieldsUp = true;`
在本程序中,它代表玩家的防护盾处于开启状态。

shieldsUp是bool型变量,也就是布尔变量。bool型变量可以表示true或false。尽管这很有趣,但是第2章才会介绍关于这种变量的更多内容。

###1.5.7 变量初始化
一条初始化语句可以用来同时完成变量的声明和赋值。下面语句就是如此。

  ` double engineTemp = 6572.89;`
这一行代码声明了一个名为engineTemp的double型变量,并将值6572.89存储其中。正如可以在一条语句中声明多个变量一样,还可以在一条语句中初始化多个变量。甚至在单条语句中声明和初始化不同变量也是允许的。将声明和初始化随意混合使用都可以!

提示
  尽管在声明变量时可以不赋值,但只要有可能,***用一个初始值初始化新的变量。这样可以让代码更加清晰易懂,并且消除了使用未初始化变量带来的风险。未初始化的变量可能是任何值。
###1.5.8 显示变量值
要显示基本数据类型变量的值,只需要将变量发送给cout,如程序余下代码所示。注意,程序没有试图显示shieldsUp的值,因为一般不会显示bool型值。

技巧
 这一部分的第一条语句使用了转义序列,即一对以反斜线(\)开头的字符。转义序列表示特殊的可打印字符。

`cout << "\nscore: "   << score << endl;`
这里使用的转义序列是\n,它表示一个换行符。当它作为字符串的一部分发送给cout时,就如同在控制台窗口中按下回车键。另外一个有用的转义序列是\t,作用和制表符一样。

还有其他转义序列可供使用。转义序列列表详见附录E。
###1.5.9 获取用户输入
另一种给变量赋值的方式可以通过用户输入来实现。所以接下来,程序基于用户输入对新变量fuel赋值,如下面一行代码所示:

`   cin >> fuel;`
cin和cout一样是iostream中定义的对象,且都属于std名称空间。在cin后面跟上>>(提取运算符)和变量名可以将值存储在变量中。也可以使用cin和提取运算符将用户输入存储在其他基本数据类型的变量中。为了证明一切都正常工作,程序将fuel显示给用户。

###1.5.10 为类型定义新名称
可以为已有类型定义新的名称。实际上,下面这行代码就是这么做的:

 `  typedef unsigned short int ushort;`
这段代码将标识符ushort定义为类型unsigned short int的另外一个名称。重命名已有类型的方法如下:在typedef后面跟上当前类型,再跟上新名称。typedef通常用于给比较长的类型名定义较短的新名称。

新类型名的使用和原始类型一样。程序初始化了一个名为bonus的ushort型变量(其实就是unsigned short int型变量),然后显示它的值。

###1.5.11 类型的选择
对于基本数据类型,有很多种选择。但如何知道选用哪种类型呢?如果需要整型,***使用int。int占据的内存空间能被计算机最有效地处理。如果需要表示的整数比int型最大值还要大或者只表示正数,那么请使用unsigned int。

如果内存资源较少,可以使用存储空间较小的类型。然而,对于大多数计算机来说,不会出现内存不够的问题(在游戏控制台或移动设备上编程则另当别论)。

最后,如果需要使用浮点数,***使用float。float占据的空间也能被计算机最有效地处理。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。