内容简介

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++程序中,我们可以同时储存很多变量。因此,就需要区分这些变量,以便之后调用时可以分得清谁是谁。因此,在C++程序中,每个变量拥有一个名字。这个名字就有点像上图中的抽屉外面贴的标签,使我们能够找到所要的抽屉。

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

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

变量名

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

变量也有名字,而给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++的变量类型如下图所示:

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

常用类型

可以存储的数值

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 <iostream>using namespace std;int main()
{int userAge(16);return 0;
}

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

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

  1. 可以储存整数

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

  3. 抽屉里储存的值是16

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

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


我们来解释一下上图的意思:

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

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

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

#include <iostream>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');

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

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

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

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

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

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

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

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

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

字符串的情况

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

#include <string>

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

#include <iostream>
#include <string>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 <iostream>
#include <string>using namespace std;int main()
{     string qqName;  // QQ用户名string qqNumber; // QQ号bool isVIP;     // 是不是QQ的VIP会员return 0;
}

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

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

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

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

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

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


显示变量的值

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

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

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

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

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

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

cout << userAge;

这么简单,你敢信?

是的,就是这么简单。

#include <iostream>using namespace std;int main()
{int userAge(16);cout << "你的年龄是 : ";cout << userAge;return 0;
}

运行以上程序,显示:

你的年龄是 : 16

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

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

运行以上程序,显示:

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


引用

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

这个知识点就是:引用

《引用》的英语是reference。

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

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

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

我们可以用下图来演示:

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

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

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

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

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

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

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

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

我们来看一个例子程序:

#include <iostream>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);


第一部分第五课预告

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

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

转载于:https://blog.51cto.com/4526621/1726888

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

  1. Linux 探索之旅 | 第一部分第四课:磁盘分区 + 完成 Ubuntu 安装

    -- 作者 谢恩铭 转载请注明出处 内容简介 第一部分第四课:磁盘分区+完成Ubuntu安装 第一部分第五课预告:Unity桌面,人生若只如初见 磁盘分区+完成Ubuntu安装 上一课Linux探索之 ...

  2. C语言探索之旅 | 第一部分第三课:你的第一个程序

    作者 谢恩铭,公众号「程序员联盟」. 转载请注明出处. 原文:https://www.jianshu.com/p/c73fecacd006 <C语言探索之旅>全系列 内容简介 前言 控制台 ...

  3. shell 做加法运算_C语言探索之旅 | 第一部分第七课:运算那点事

    上一课是 C语言探索之旅 | 第一部分第六课:变量的世界(三),显示变量内容 今天,我们一起来学习 C语言(对大多数编程语言也类似)中的运算. 之前的课中,我们已经说过:电脑是一台"笨笨&q ...

  4. c语言min函数_C语言探索之旅 | 第一部分第十课:第一个C语言小游戏

    内容简介 前言 准备工作和建议 我的代码 改进方案 第一部分第十一课预告 1. 前言 上一课是 C语言探索之旅 | 第一部分第九课:循环语句 . 经过前面这么多课的努力,我们终于迎来了第一个比较正式的 ...

  5. c 字符串数组_C语言探索之旅 | 第二部分第四课:字符串

    内容简介 前言 字符类型 显示字符 字符串其实就是字符的数组 字符串的创建和初始化 从 scanf 函数取得一个字符串 操纵字符串的一些常用函数 总结 第二部分第五课预告 1. 前言 上一课 C语言探 ...

  6. C语言探索之旅 | 第一部分第二课:工欲善其事,必先利其器

    -- 作者 谢恩铭 转载请注明出处 上一课C语言探索之旅 | 开宗明义及第一部分第一课:什么是编程?中,我们说了,程序员需要具备三个特质: 耐心,逻辑,冷静. 我突然感觉到还需要第四大特质---谦虚 ...

  7. C++探索之旅 | 第一部分第二课:C++编程的必要软件

    作者 谢恩铭,公众号「程序员联盟」(微信号:coderhub). 转载请注明出处. 原文:https://www.jianshu.com/p/bcdfbf661888 <C++探索之旅>全 ...

  8. Linux 探索之旅 | 第一部分第二课:下载 Linux,免费的噢

    -- 作者 谢恩铭 转载请注明出处 内容简介 第一部分第二课:下载Linux,免费的噢 第一部分第三课预告:测试并安装Ubuntu 下载Linux,免费的噢 大家好,上一课 Linux探索之旅 | 开 ...

  9. Python探索之旅 | 第一部分第二课:安装Python和Python的常用开发软件

    作者 谢恩铭,公众号「程序员联盟」(微信号:coderhub). 转载请注明出处. 原文:https://www.jianshu.com/p/68fcd46254f5 <Python探索之旅&g ...

  10. c语言 如何创建adt_C语言探索之旅 | 第二部分第六课:创建你自己的变量类型

    内容简介 前言 定义一个 struct 结构体的使用 结构体指针 union enum 总结 第二部分第七课预告 1. 前言 上一课是 C语言探索之旅 | 第二部分第五课:预处理 ,应该是比较轻松的. ...

最新文章

  1. MIT自动驾驶船下水!可乘坐5人,阿姆斯特丹运河航行3小时误差不到0.17米
  2. python生成条形码
  3. 201621123037 《Java程序设计》第10周学习总结
  4. APR-Util 1.5.1 发布
  5. 从LASSO回归到结构性稀疏:线性回归的正则项都带来了什么?
  6. 关于Android手机CPU不同架构的问题
  7. CUBA 7.2 –有什么新功能?
  8. Java命令行界面(第19部分):jClap
  9. 组合数学 - 组合数的个数
  10. 企业为什么需要IT资产管理
  11. sqlserver约束
  12. 奔驰车载逻辑单元 (OLU) 源代码遭泄露
  13. react + better-scroll 横向滚动案例
  14. 百度网盘推出领取七天会员
  15. Typora设置高亮
  16. wifi连接一段时间才能上网_家里的WiFi老是突然断网,WiFi还是连着的,但是关WiFi又连不上去,必须重启路由器才能上网...
  17. PS证件照红底转蓝底
  18. PS渐变羽化制作单车
  19. 重磅!L4级自动驾驶硬件方案来啦!
  20. 微软自带dns服务器,微软改进Windows 10加密DNS服务器配置(DoH) 现在设置起来更方便...

热门文章

  1. Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient报错,问题排查...
  2. C++学习笔记-继承
  3. etcd和redis的比较和日常使用场景
  4. JDBC初学者的basedao工具类
  5. bzoj1003题解
  6. MacPort 的使用
  7. K线理论--单根K线形态
  8. AI时代的稀缺人才:解读数据科学家成长的4个阶段
  9. 电商后台原型 rp_电商选型:一站式线上商城的重要性
  10. Jeecg_3.6新版本功能专题讲解 - 公开课(自定义表单、数据权限)