📄 第5章 变量和常量.htm
字号:
<P>类似这样的问题还有制表符(键盘上的Tab键)等等。</P>
<P>解决的方法是使用<B>转义符.</B>C/C++使用反斜杠'\'作为转义符。如:</P>
<P>'\'' : 表示单引号;</P>
<P>'\"' : 表示双引号;</P>
<P>'\n' : 表示换行(n : line);</P>
<P> </P>
<P>下面列出常用的C、C++特殊字符:</P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD width="13%">字符</TD>
<TD width="13%">数值</TD>
<TD width="74%">意义</TD></TR>
<TR>
<TD width="13%">'\a'</TD>
<TD width="13%">7 </TD>
<TD width="74%">响铃(输出该字符时,屏幕无显示,但喇叭发音)</TD></TR>
<TR>
<TD width="13%">'\n'</TD>
<TD width="13%">10</TD>
<TD width="74%">换行(n: line)</TD></TR>
<TR>
<TD width="13%">'\t'</TD>
<TD width="13%">9</TD>
<TD width="74%">制表符(横向跳格)</TD></TR>
<TR>
<TD width="13%">'\r'</TD>
<TD width="13%">13</TD>
<TD width="74%">回车(return)</TD></TR>
<TR>
<TD width="13%">'\\'</TD>
<TD width="13%">92</TD>
<TD width="74%">输出转义符 '/' 本身</TD></TR>
<TR>
<TD width="13%">'\"'</TD>
<TD width="13%">34</TD>
<TD width="74%">双引号</TD></TR>
<TR>
<TD width="13%">'\''</TD>
<TD width="13%">39</TD>
<TD width="74%">单引号</TD></TR></TBODY></TABLE>
<P>这里顺便解释一下“回车换行”是什么,尽管我们对这个词耳熟得很。</P>
<P>“回车换行”是“回车”加“换行”。</P>
<P>换行好理解,但什么叫“回车”呢?它和“换行”又有什么关系?</P>
<P>原来,“回车换行”的概念源于早先的打字机。类似于现在打印机中有一个打印头,这个打印头平常停在打印机内的某一端。在打印一行时,则需要向外移动,打印一行结束后,打印头需要回到原来位置。由于打印头在英文中用“车”来表示,所以这个动作就称为“回车”,用金山词霸的中的解释就是:“将打印或显示位置移到同行起始位置的运动。”</P>
<P>所以对于打印机,假设有两行字,两行之间若光有“回车”,那么这两行字将重叠在一起(对于控制台程序的屏幕,则将回到行首)。如果光有“换行”,则第二行将不从起始位置打起,样子如下:</P>
<P> </P>
<P>这是第一行</P>
<P> 这是第二行。</P>
<P> </P>
<P>只有既输出“回车”又输出“换行”,才是我们常见的换行结果。当然,对于当今的大都软件,往往都把单独的回车或换行直接解释于二者的结合。</P>
<P> </P>
<P><B>转义符的另外一种用法是直接接数值。</B>但必须采用8进制或16进制。这里暂不讲解。</P>
<P> </P>
<P>如果需要使用数值表示,最直接的还是使用类似: c = 120; 的方法。比如要让变量c的值为单引号,我们至少可以有以下2种方法:</P>
<P>char c = '\''; //使用转义符</P>
<P>char c = 39; //直接赋给字符的ASCII的值。</P>
<P> </P>
<P>转义符的内容,看上去怪怪的?不过,多用几次我们就会明白。</P>
<P> </P>
<P>/////////////////char
类型///////////////////////////////////////////////////</P>
<P>int k = 120;</P>
<P>char j = 120;</P>
<P>cout << "k(int) = " << k << " j(char) = " << j
<< endl;</P>
<P> </P>
<P>char l = 'A';</P>
<P>char m = l + 1;</P>
<P>cout << "l = " << l << " m = " << m <<
endl;</P>
<P> </P>
<P><B>/////////////////转义符//////////////////////////////////////////////////////</B></P>
<P><B>cout << "TAB:" << '\t' << "AA" <<
endl;</B></P>
<P><B>cout << "换行:" << '\n' << "AA" <<
endl;</B></P>
<P><B>cout << "回车:" << '\r' << "AA" <<
endl;</B></P>
<P> </P>
<P><B>cout << "听到BEEP声了吗?" << '\a' << endl;</B></P>
<P><B>cout << '\'' << endl;</B></P>
<P><B>cout << '\"' << endl;</B></P>
<P><B>cout << '\\' << endl;</B></P>
<P> </P>
<P>getchar();</P>
<P>......<BR></P>
<P>在执行之前,有必要稍作解释。</P>
<P>首先那是“AA"做什么用。因为制表符、回车、换行等特殊字符,其输出效果是改变光标位置,所以我们需要一些上下文来显示出光标位置改变效果,这里就随便写个“AA”了事。</P>
<P>然后是在cout语句中,平常我们叫是使用双引号输出一行话,但如果当前要输出只是一个字符,我们也可以使用单引号。</P>
<P>至于所谓“BEEP”声,你可别抱太多期望,它只是计算机内置的小喇叭短促一个声音,听起来并不美妙。</P>
<P> </P>
<P>现在来看结果(请只关心转义符部分):</P>
<P> </P>
<P><IMG height=303 src="第5章 变量和常量.files/ls05.h2.jpg" width=404
border=0></P>
<P> </P>
<P>关于输出结果的几点说明:</P>
<P> </P>
<P>1、需要注意的是 '\t'
在控制台窗口的输出效果,如果前面的字符长度已超过一个制表位,那么后面的第一个'\t'将是没有效用的。(要理解这一点,你可以将代码中“TAB”加长一点,如"TABTAB")。</P>
<P>2、“AA车” 的输出结果是怎么来的呢?请大家考虑考虑。</P>
<P> </P>
<P>试验程序在这里结束。</P>
<H3><B><A name=5.2>5.2</A> 变量与内存地址</B></H3>
<P>前面讲到“白马、黑马”时,我们说一匹白马和一匹黑马具有共同的数据类型“马”,但二者是相对独立的个体。现在我们以共熟悉的“人”来继续这个话题,最终引出变量与内存地址的关系。</P>
<P>张三和李四的数据类型都是“人类”。但张三和李四显然是独立的量:张三吃了两块蛋糕,李四不可能因此就觉和肚子饱了;而李四在下班的路上捡到一个钱包,虽然正好是张三的,两人似乎通过钱包有了点关系,但谁得谁失仍然不容混淆。</P>
<P>这一切都很好理解。张三和李四之所以是不同的个体,根本原因在于两人有着不同的肉身。如果是一对连体婴儿,虽然也是两个人,但当左边的婴儿被蚊子咬一口时,右边婴儿是否也会觉得痒,就不好说了。</P>
<P>现在我们困难的是,如何理解两个不同的变量,也是互相独立的呢?</P>
<P>答案就在“内存地址”,“内存地址”就是变量的肉身。不同的变量,拥有不同的内存地址。譬如:</P>
<P> </P>
<P>char a;</P>
<P>char b;</P>
<P> </P>
<P>上面有两个字符类型的变量a和b,a拥有自已的内存地址,b也拥有自已的内存地址,二者绝不相同。而a、b只不过分别是那两个内存地址的“名字”,恰如“张三、李四”。</P>
<P> </P>
<P>让我们看图解:</P>
<P><IMG height=300 src="第5章 变量和常量.files/ls05.h1.gif" width=261 align=left
border=0>看,内存就像是开宾馆的。不过这有宾馆有点怪。首先它每一个“房间”的大小都是一个<B>字节</B>(因此,计算机能单独处理的最小内存单位为字节)。它的门牌号也不叫房号,而是叫<B>内存地址</B>。</P>
<P>在左图中,“房客”,变量a住在内存地址为1000002的内存中,而变量b则住在它的隔壁,地址为100003的内存中。另外,如果你足够细心,你还会发现:<B>内存地址由下往上,从小到大排列</B>。</P>
<P> </P>
<P>变量的内存地址是在程序运行时,才由操作系统决定。这就好像我们住宾馆。我们预定一个房间,但房间号由宾馆根据情况决定,</P>
<P><B>我们可以改变变量的值,但变量的地址我们无法改变。</B>对照宾馆一说,就是我们订了房间,可以不去住,还可以决定让谁去住在那个房间里。(当然,现实生活中宾馆可能不会允许你这么做)。</P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P>在前面图示的例子中,a、b是字符(char)类型。各占用1个字节。如果是
int类型,那么应该占4个字节。这4个字节必须是连续的。让我们再来看一个例子:<IMG height=438
src="第5章 变量和常量.files/ls05.h2.gif" width=261 align=right border=0></P>
<P> </P>
<P>int a;</P>
<P>int b;</P>
<P>char c;</P>
<P> </P>
<P>这回,我们声明了两个int类型和一个char类型的变量。同时和上面一样,我们事实上是假设了这三个变量被依次序分配在相邻的内存地址上(真实情况下,这和其它因素,如指定的字节对齐方式等有关)。从右图中可以看到整型变量a占用了1000001~100004这4个字节。</P>
<P> </P>
<P>在我们已学习的数据类型中,long
double占用10个字节,是占用内存空间最大的一种数据类型。以后我们学习数组,或者用户自定数据类型,则可能要求占用相当大的,并且同样必须是连续的空间。因此,如果操作系统仅仅通过简单的“按需分配”的原则进行内存管理,内存很快就会宣告不足。事实上,操作系统的内存管理相当复杂。幸好,一个普通的程序员并不要求去了解这些内幕。更多的有关内存管理的知识,我们会在下一部课程中学习。但是本章中有关内存的内容却相当重要。</P>
<P> </P>
<P>让我们来看看我们学了什么:</P>
<P>1、不同的变量,存入在不同的内存地址,所以变量之间相互独立。</P>
<P>2、变量的数据类型决定了变量占用连续的多少个字节。</P>
<P>3、变量的内存地址在程序运行时得以确定。变量的内存地址不能改变。</P>
<P> </P>
<P>除了这些以外,我们现在还要增加几点:</P>
<P>现在,我们可以明白,为什么需要变量,显然,这又是一个讨好人类的做法。在汇编和机器语言,就是只对内存进行直接操作。但你也看到了,内存地址是一堆长长的数,不好记忆;另外,管理内存复杂易错,让程序员直接管理内存显示不可能。而通过变量,不仅让内存地址有了直观易记的名字,而且程序员不用直接对内存操作,何乐而不为呢?事实上,这是所有高级语言赖于实现基础。</P>
<P>既然变量只不过是内存地址的名称,所以:</P>
<P>4、对变量的操作,等同于对变量所在地址的内存操作。</P>
<P>第五点是反过来说:</P>
<P>5、对指定内存地址的内存操作,等同对相应变量的操作。</P>
<P>尽管这简直就是在重复。但这一条却是我们今后理解C、C++语言相对于其它很多高级语言的,最灵活也最难学的“指针”概念的基石。</P>
<H3><B><A name=5.3>5.3</A> 常量</B></H3>
<P>说完变量,我们来学常量。</P>
<P>看一段代码片段。省略号表示可能会有的其它操作。</P>
<P>int a = 3;</P>
<P>....</P>
<P>a = 100;</P>
<P> </P>
<P>代码中,a 是变量。一开始我们初始化为3。后来出于什么需要,我们又将它赋值为100。a的值也就从3变成了100。</P>
<P>代码中,3 和
100就是一种常量。像这种直接在代码写出大小的量,称为<B>立即数</B>,也称为<B>常数</B>,而常数是常量的一种。</P>
<P> </P>
<P>常量的定义:常数,或代表固定不变值的名字。</P>
<P> </P>
<H4><A name=5.3.1>5.3.1</A> 几种数据类型常数的表达方法</H4>
<H5><A name=5.3.1.1>5.3.1.1</A> 整型常数的表达</H5>
<P>用10进制表示,当然是最常用也是最直观的了。如:7,356,-90,等等。
C,C++语言还允许我们使用8进制或16进制表示。这里且不讲。至于2进制形式,虽然它是计算机中最终的表示方法,但它太长,而且完全可以使用16进制或8进制方便地表达,所以计算机语言不提供用2进制表达常数的方法。</P>
<P> </P>
<P>有时,你也会看到一些老的代码中,在一些整型常后面加一个大写或小写的 L 字母。如:989L
这是什么意思呢?原来,一个常数如果其范围允许,那么计算机默认将其认为是 int 类型的,那么要让计算机把某个数认为是 long
int类型,就可以在其后面加 L 或 l。不过,这在以前的16位机器才有意义了。现在,我们的机器都是32位,long int 和 int
完全一样,都是占用4个字节,所以,我们没有必要这样用了。</P>
<H5><A name=5.3.1.2>5.3.1.2</A> 实型常数的表达</H5>
<P>实型常数一般只用10进制表示。比如 123.45,或 .123。后者是 0.123的简写。不过我个人认为,少写一个0的代价是很容看错。</P>
<P>实型数还可以使用科学计数法,或曰指数形式,如:123e4、或123E4 都表示 123 * 10<SUP>4</SUP>,即
1230000。</P>
<P>我们学过的实数数据类型有:float,double,long double。在C++中,默认的常数类型是double。比如你写:</P>
<P>1.234;</P>
<P>那么,C++按double类型为这个数分配内存,也就是说为它分配8个字节。如果要改变这一点,可以通过加后缀字母来实现。</P>
<P>加 f 或 F,指定为float类型。</P>
<P>加 l 或 L, 指定为double类型。</P>
<P> </P>
<P>以下示例:</P>
<P>12.3f //float类型</P>
<P>12.3 //默认类型(double)</P>
<P>12.3L //long double类型</P>
<P>12.3e400 //long double类型,因为值已不在double类型的取值范围内</P>
<H5><A name=5.3.1.3>5.3.1.3</A> 字符常量的表达</H5>
<P>关于字符的表示方法,我们已经在 5.1.3.4 节中的第3点讲过。这里简单重复。</P>
<P>字符常量用单引号括起来的一个字符,如:'a','b','c',' ','A'。等。</P>
<P>可以用转义符来表示一些无法打出的符号,如 '\n','\r','\t'。</P>
<P> </P>
<P>这里补充一点:值为0的字符,称为空字符,或零字符。它用 '\0' 表示。注意,它和阿拉伯数字字符
'0'完全是两个数。(请大家查一前面常用字符ASCII值表中,后者的值是多少)</P>
<H5><A name=5.3.1.4>5.3.1.4</A> 字符串常量</H5>
<P>字符串由字符组成。在C/C++语言中,字符串的是由一对双引号括起的来的字符序列。如:</P>
<P>"Hello, world!"</P>
<P>"How do you do?"</P>
<P>"Hello"</P>
<P>上面3行都是字符串常量。注意,双引号是英文字符。</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -