【C++探索之旅】第一部分第四课:内存,变量和引用

【C++探索之旅】第一部分第四课:内存,变量和引用_第1张图片


内容简介

1、第一部分第四课:内存,变量和引用

2、第一部分第五课预告:简易计算器



内存,变量和引用


上一课《【C++探索之旅】第一部分第三课:第一个C++程序》中,我们已经学习了如何创建,编译,运行我们的第一个C++程序。我们也解释了这个程序每一行的意义。


我们不但在IDE(Integrated Development Environment,集成开发环境。例如Visual Studio,Codeblocks,xCode等)中创建程序,也学习了如何在终端命令行中创建。


不过到目前为止,我们写的程序还非常简单,只能在屏幕上显示消息,还不能和用户进行交互。我们慢慢来弥补这一缺憾。


在此之前,我们首先来学习一个计算机科学的基本概念,就是:变量。


变量使用电脑的内存来存储信息,以便之后再次使用。大家应该用过计算器吧,我们平时不太使用的几个键:M+,M-,MR,MC,其实就是在使用变量和内存的概念(M是Memory的缩写,表示《内存》),这几个键的作用如下:


M+:把目前显示的值放在存储器中 (memory +)

M- :从存储器内容中减去当前显示值 (memory -)

MR:调用存储器内容 (memory recall)

MC:清除存储器内容 (memory clear)


以上这些按键,可以操作存储在计算器的存储器(内存)里的计算值。


我们将在电脑上学习类似的事情,毕竟我们的电脑兄说到底不过是一台大“计算器”,本质上就是做二进制(0和1)的运算,不然也不会叫“计算机”了对吧。



什么是变量


上面我们举了计算器的例子来更形象地说明,毕竟在信息技术的世界里,基本的原理是相通的。在我们的电脑里,也有一些电子元件,可以储存数值,并且能保存一段时间。当然,背后的科学原理是比较复杂的。


不过大家可以放心,我们没必要搞清楚这背后的一套复杂的原理,我们只需要学会怎么把数值存储到电脑的内存中就好了。至于复杂的部分就交由编译器和操作系统来处理了,是不是突然觉得生活很美好呢?


我们只需要知道变量其实就是电脑借给我们的一小段内存,里面储存了数值。我们可以想象电脑里面有一个大橱柜(比喻内存),如下图所示。这个大橱柜非比寻常,因为它拥有成千上万(甚至数十亿)个小抽屉,这些小抽屉就是内存中我们可以存放数值的地方。


【C++探索之旅】第一部分第四课:内存,变量和引用_第2张图片


电脑的内存的原理就有点像一个有着很多抽屉的大橱柜。


对于一个计算器来说,我么通常一次只能储存一个数值。但是我们的电脑可比普通的计算器厉害多了。不然也不会那么贵了,对吧?说的就是你,苹果电脑。


聪明如你应该料想到了:在C++程序中,我们可以同时储存很多变量。因此,就需要区分这些变量,以便之后调用时可以分得清谁是谁。因此,在C++程序中,每个变量拥有一个名字。这个名字就有点像上图中的抽屉外面贴的标签,使我们能够找到所要的抽屉。


我们的电脑还可以使我们储存不同的数值,比如我们想储存数字,字母,单词,句子,图片,声音,等等。这就涉及到变量的类型了。


你可以想象变量的类型就好比抽屉的不同样式,在生活中,我们放葡萄酒和书籍的抽屉是不一样的,不是吗?


变量名


对于人来说,名字很重要,名字起得好,有很多益处。名字起得不好,会很搞笑。


【C++探索之旅】第一部分第四课:内存,变量和引用_第3张图片


变量也有名字,而给C++中的变量起名字有如下规则:


  1. 只能包含字母,数字和下划线(_)

  2. 第一个字符必须是字母或下划线

  3. 不能和C++的关键字重复,比如不能是int,char,if,while等。


例如:


name,studentNum,year2015,_computerPrice 等都是规范的命名。


而:


+animal,@gmail,*1991,等都是通不过的命名。


除此之外,C++对于大小写敏感。也就是说,大写字母和小写字母在C++看来是不同的。有的编程语言不区分大小写。所以,在C++中,givenName,GIVENname,GiVenName是不同的变量名。


另外,希望大家养成良好的命名习惯,使自己的变量做到见名知意,这样程序就可以自注释了。比如,我们提倡这样的变量名:myName,computerPrice。而不推荐类似 name1,variable3,hehe2,之类不知所云的名字。


对于程序的编译器来说,这样并没有什么用,因为它才不管你名字起得是不是见名知意。但是,对于你自己和以后要阅读你的程序人来说,一个好的变量名会发挥很大的作用,不然过了一段时间再看自己的代码,可能都忘了这个变量是用来干嘛的。


小编自己有个变量命名习惯,此习惯不少程序员也遵守:


  1. 变量名由小写字母开头

  2. 如果变量名由几个单词组成,那么紧挨着写

  3. 除了第一个单词,其他单词的第一个字母大写


例如:


bestRestaurantName,secondBugReport,等等。


这样的命名法也称为《小驼峰式命名法(lower camel case)》。


变量类型


之前说了,变量除了有名字,还有类型。就好比“小明”这个名字,不知道是人呢还是一只宠物。


C++的变量类型如下图所示:


【C++探索之旅】第一部分第四课:内存,变量和引用_第4张图片


有点多是吗?初学时不用一下子都记住,我们慢慢来学习。一开始只要知道几种常用的变量类型就可以了。如下:


常用类型

可以存储的数值

bool

true(真)或false(假)

char

一个字符

int

整数

unsigned int

无符号整数(正整数或0)

double

带小数点的数(其实double是双精度浮点数)

string

字符串(0到多个字符)


一般,我们在IDE中输入以上这些变量类型时,IDE会用颜色来高亮显示。


这些类型可储存的数值有大小范围,也就是上下限。比如有的很大的整数,int类型就不能储存。这些上下限取决于你的电脑,操作系统和编译器。


当我们使用变量时,就需要考虑用哪种变量类型了。例如你要储存一个学校的学生数目,那么int和unsigned int会适合。要储存一个人的身高,那么用double会适合。要储存你自己的名字,那么string会适合。


那么bool这种变量类型是什么意思呢?


bool其实是boolean(布尔类型)的意思,它只能储存两种值:true(真)或false(假)。


我们可以用bool类型的变量来储存例如: 用户名是否正确,是不是程序员,有没有女朋友,之类。



变量声明


变量的英语是variable,是《可变的,变化不定的》,所以说,变量和女人的心有点像,不是吗?开个小玩笑。


因此,变量储存的数值是可以改变的。


好了,铺垫也够多了,该来正式请求电脑出借它的“抽屉”了(前面我们用抽屉比喻一块内存空间)。用术语来说,就是变量声明。


注意:我们暂时用《声明》这个词,其实要澄清一下:

==========================

对变量而言,声明与定义的关系稍微复杂一些。在声明部分出现的变量有两种情况:一种是需要在内存中建立存储空间的(如int a;);另一种是不需要建立存储空间的(如extern int a;  以后会讲到extern关键字)。前者称为定义型声明(defining declaration),或简称为定义(definition)。后者称为引用型声明(referenceing declaration)。


广义地说,声明包括定义,但并非所有的声明都是定义。对 int a; 而言,它是定义性声明,既可说是声明,又可说是定义。而对 extern int a; 而言,它是声明而不是定义。一般为了叙述方便,把建立存储空间的声明称为定义,而把不需要建立存储空间的声明称为声明。


在这一课中所有用到《声明》的地方,其实用的是《定义型声明》。以后的课会讲解《引用型声明》。

==========================


我们需要向电脑提供变量的类型,名字和它储存的值。这里的值会成为变量的初始值。


为了做到这一点,我们只需按照以下格式:


类型  名字  ();


以上的格式是C++中初始化一个变量的方式。


我们也可以用另一种从C语言继承过来的格式:


类型  名字  = ;


这两种格式的效果是一样的。我们推荐使用第一种格式,以后的课程中会讲述为什么选第一种格式更好。


可不要忘了句末的分号(;),这个错误即使是有经验的程序员也会犯。当然这个错误也不难发现,只不过它会让你的编译器不安分而已。


我们就来声明(定义型声明)一个变量,这个变量叫做userAge,用于储存《用户年龄》:


#include 

using namespace std;

int main()
{
    int userAge(16);
    
    return 0;
}


上面程序的第6行发生了什么呢?

答:电脑得知我们要向它的内存借一个“抽屉”,这个抽屉有以下特性:


  1. 可以储存整数

  2. 抽屉外面贴了一个标签,名叫 userAge

  3. 抽屉里储存的值是16


因此,一旦程序运行完了第6行代码,你就成为电脑内存中那个抽屉的主人了,如下图:


【C++探索之旅】第一部分第四课:内存,变量和引用_第5张图片


因为之后我们会继续向电脑借很多“抽屉”,所以我们需要把图画得简单些。如下:


【C++探索之旅】第一部分第四课:内存,变量和引用_第6张图片
我们来解释一下上图的意思:


  1. 大大的蓝色矩形代表的是电脑的内存,目前,内存几乎是空的。

  2. 黄色的小正方形代表电脑出借给我们的内存的一块空间。也就是我们之前比喻的一个抽屉。它里面储存的值是16,而它的标签是userAge。


既然我们画了如此好(chou)看(lou)的图,那岂能只声明一个变量。一不做二不休:


#include 

using namespace std;

int main()
{    
    int userAge(16);
    int money(432);  //钱数    
    double pi(3.14159);    
    bool isHoliday(true); //是不是假期    
    char letter('a');  
     
    return 0;
}


上面的程序中,我们在userAge这个变量之外,又声明了好几个新的变量。


有两点需要注意:


  1. bool类型的变量只能储存true或false中的一个值,不是true(真),就是false(假),除此之外不能储存其他值。

  2. char变量的值需要用单引号括起来,不要写成 char letter(c); 而是 char letter('c');


插一句题外话:写程序时要勤写注释,哪怕看似比较简单的地方,因为以后别人看你的程序,或者你自己回看自己的程序,假如没有注释,那可能会增加不少难度。


对于上面这个程序,我们也可以画一个图,只要在之前的图上增加新的变量即可。


【C++探索之旅】第一部分第四课:内存,变量和引用_第7张图片


可以看到,我们多声明了几个变量,内存里面开始变得丰富多彩起来了。马上要圣诞了,人多一些总是热闹。


上面的程序,我们如果编译,运行,可以看到它什么也没有输出。那是当然的,因为我们只是声明了一些变量,还没使用它们呢。


我希望你没有太失望,虽然这个程序没有显示什么,但其实在背后电脑是进行了很多操作的。只不过这些操作对用户隐藏起来了,我们也不太感兴趣而已。不过我们还是总结一下上面的变量声明究竟做了什么:


  1. 你的程序向操作系统(简称OS,是Operating System的缩写。例如Windows,Mac OS X,Linux等都是常见的操作系统)借一些内存来使用

  2. 操作系统查看内存是否有空余的空间,如果有则分配几个“抽屉”(代表内存空间)给你的程序

  3. 你的程序逐一将那些值存放进对应的抽屉。例如在贴有userAge标签的抽屉里,存放进16;在贴有money标签的抽屉里存放进432;等等

  4. 运行到最后一行(return 0;)时,你的程序把所有抽屉清空,并且还给操作系统


字符串的情况


前面说了,字符串这种变量类型的情况有点特殊。为了使用字符串变量,我们首先需要在程序中多加一行:


#include


表示引入string这个C++的标准库,这样我们才能使用其中的函数等。我们可以写个程序:


#include 
#include 

using namespace std;

int main()
{
    string userName("Steve Jobs");
    
    return 0;
}


可以看到,我们声明了一个字符串变量,它的名字是userName,里面存放的值是Steve Jobs(苹果的前CEO)。


可以看到,给string型变量赋值,用的是双引号",而之前给char型变量赋值时用的是单引号'。其实呢,字符串(string)就是由一串字符(char)组成的。


偷懒的小技巧


在继续下面的内容之前,我们介绍一种“偷懒”的小技巧,很多程序员都会用:


如果你有多个同一类型的变量要声明,那么可以将它们放在同一行里,彼此用逗号隔开。如下:


int a(2), b(4), c(6); //我们声明了三个整型变量a, b, c,分别存放了2, 4, 6三个值
string userNameApple("Steve Jobs"), userNameMicrosoft("Bill Gates");  
//我们声明了两个字符串变量userNameApple和userNameMicrosoft,分别存放Steve 
Jobs(史蒂夫乔布斯)和Bill Gates(比尔盖茨)。


这样我们就不用每次都写一遍变量类型名了,上例中是int和string。



声明但不初始化


上面我们学习了如何声明一个变量(其实是定义型声明),其实声明一个变量时你的程序陆续做了两件事:


  1. 首先,程序向操作系统请求拨给一块内存空间,称为“变量分配”。

  2. 然后,在这块内存空间上存入初始值,称为“变量初始化”。


但是,有的时候我们在声明变量时还没有想好要赋什么值。所以,我们也可以声明变量,但不初始化。


怎么做呢?很简单,只需要写变量类型和变量名,就可以了。如下:


类型  名字;


是不是很简单呢?我们来看例子程序:


#include 
#include 

using namespace std;

int main()
{     
    string qqName;  // QQ用户名
    string qqNumber; // QQ号
    bool isVIP;     // 是不是QQ的VIP会员
    
    return 0;
}


注意:有一个常见的错误是:

在变量名之后加空的括号,例如 string qqNumber();

这是不正确的,不要加括号,只需要类型和名字。


我们也用图解来演示上面的程序:



【C++探索之旅】第一部分第四课:内存,变量和引用_第8张图片


可以看到,在声明变量后,变量中的值是一个任意值。


但是通常我们最好在声明时给变量赋初值,特别是指针的情况,以后我们会学习。而且有的变量类型还必须在声明时就初始化。



显示变量的值


在上一课中,我们已经学习了如何在屏幕上显示文本,希望你没有忘记大明湖畔的夏雨荷。


是的,这位"夏雨荷"就是 cout<<


cout有点类似C语言的printf函数,是C++里面负责标准输出的。不过又有不同,我们可以看到cout后面不是加括号,而是连接了<<这个特殊的符号。


暂时我们不深入,因为cout其实不是一个函数,cout是一个ostream类的对象(关于类和对象,之后的课程会讲解),它有一个成员运算符函数operator<<(涉及到C++的运算符重载的技术,以后会讲)。(这一句指令暂时不需要理解,只要知道cout<<可以用来向屏幕输出内容即可)。


那么机智如你,应该猜到怎么显示变量的值了吧。


【C++探索之旅】第一部分第四课:内存,变量和引用_第9张图片


是的,就是把文本替换成变量名就行了。如下:


cout << userAge;


这么简单,你敢信?


是的,就是这么简单。


#include 

using namespace std;

int main()
{
    int userAge(16);
    cout << "你的年龄是 : ";
    cout << userAge;
    
    return 0;
}


运行以上程序,显示:


你的年龄是 : 16


当然了,我们也可以同时显示好几个变量的值,并且把一句话的内容都写在一行上。如下:


#include 
#include 

using namespace std;

int main()
{
    int userIQ(150);
    string userName("Albert Einstein");  // 阿尔伯特.爱因斯坦
    
    cout << "你名叫 " << userName<< ", 你的智商是 " << userIQ<< endl;
    
    return 0;
}


运行以上程序,显示:


你名叫 Albert Einstein, 你的智商是 150



引用


在结束这一课之前,我们还有一个很重要的知识点需要介绍。


这个知识点就是:引用


《引用》的英语是reference。


我们之前说过,变量可以被看成内存里的一个“抽屉”。这个抽屉外面可以贴标签,就是变量名。


实际生活中,我们可以在同一个抽屉外面贴上不止一个标签。那么,在C++中,我们也可以给同一个内存的“抽屉”上贴好多个标签。


因此,我们就多了一种访问变量的方式。就好像我们给变量取一个别名。但是别名听起来没有那么高大上,所以C++中称之为“引用”。听着是不是挺玄乎的,其实就是别名。


我们可以用下图来演示:


【C++探索之旅】第一部分第四课:内存,变量和引用_第10张图片


可以看到,在内存中的这个变量上,有两个标签。一个是userAge,声明此变量时起的变量名;另一个是myVariable,是它的别名,也就是引用。


比如,黄晓明,也可以叫小明,两个名字指代的都是那个人,都爱着Angelababy。


那么引用怎么声明呢?要用到一个特殊的符号:&


int userAge(16);  // 声明一个变量,名字是userAge

int& myVariable(userAge); // 声明一个引用变量,名叫myVariable,它是userAge变量的别名。


可以看到,userAge放在了myVariable后面的括号里,还记得变量如何初始化吗?就是在括号里填入初始值。因此,这里相当于把userAge“赋值”给了myVariable


说到底,userAge和myVariable指向的是同一个“抽屉”,同一个变量。它们的值都是16。


用术语说就是:myVariable引用了userAge。


引用变量的类型必须和它要引用的变量一样。而且,引用变量声明时必须赋初值。


我们来看一个例子程序:


#include 

using namespace std;

int main()
{    

    int userAge(16); // 一个变量,名字是userAge,包含一个整型数值16        
    int& myReference(userAge); // 变量userAge的一个引用    

    // 从现在开始,我们可以不加区分地使用userAge或myReference    
    // 因为它们实际上是一个内存中“抽屉”的两个标签,指向的是相同内容    

    cout << "你已经 " << userAge << "  岁了. (通过 变量名)" << endl;    
    // 惯常的方式    
    
    cout << "你已经 " << myReference << " 岁了. (通过 引用)" << endl;    
    // 用引用的方式来访问变量值        

    return 0;
}


运行以上程序,显示:


你已经 16 岁了. (通过 变量名)

你已经 16 岁了. (通过 引用)


那么,引用到底有什么用呢?


好问题。在上面的例子中,仿佛看不出引用有多大用处。


也许暂时你觉得引用比较抽象,也貌似没什么用。但是要知道,引用是C++中很重要的一块知识点,而且以后我们会“大宝啊,天天见”,会经常使用到“引用”的。而且还会区分什么时候用引用,什么时候用指针。


因此,先对引用的概念有个了解,对我们之后处理更复杂的用例是大有裨益的。



总结


  1. 变量是存储在内存里的一段信息

  2. 根据存储的信息的不同,变量有不同类型:int,char,bool,double,等

  3. 变量在使用前需要先声明,例如:int number(28); // 此处是定义型声明

  4. 可以用cout来显示变量的值

  5. 引用其实是变量的别名,有点像标签,使我们可以用另一个名字来调用变量,例如:int& numberReference(number);



第一部分第五课预告


今天的课就到这里,一起加油吧!

下一课我们学习:简易计算器

你可能感兴趣的:(C++探索之旅,程序员联盟,程序员,C++,变量,引用)