2.1.7 字符串变量

前面讲过,字符型常量是由一对单引号包含起来的单个字符,如'a'。

那什么是字符串常量呢?字符串常量是用一对双引号包含起来的一堆字符(可以是1个字符或者是多个字符),如"Helloworld!"、"zhangsan"、"我爱我的祖国"等。

看看如下范例:

不要混淆字符常量和字符串常量,'a'是字符常量,"a"是字符串常量,二者不同。看看如下范例:

图2.17 字符'a'和字符串"a"的内存占用情况

那么,'a'和"a"有什么区别呢?这里一定要注意,这个知识点非常关键:字符'a'在内存中占1字节,而"a"在内存中占2字节,如图2.17所示,一个小方块代表占用1字节。

"a"的最后一个字符为'\0',这是一个转义字符,也就是说,"a"其实是由两个字符构成,但是'\0'如果出现在printf中进行输出,却并不会输出出来,而是作为字符串结束标记来标记这个字符串内容结束,看看下面这行代码:

可以很明显地看到,上面的代码行输出的结果是“abcdefg”,而后面的“hij”并没有输出出来,原因就是系统在输出整个printf中的字符串时,一旦遇到'\0',则系统认为整个字符串输出结束,所以'\0'后面出现的任何内容都不会被输出。

注意,在写一个字符串常量时,不要手工去增加'\0',这是画蛇添足,'\0'是系统增加的。通过上面这些解释可以看到,"a"代表两个字符——'a'和'\0',把它赋给一个只有1字节长度的字符型变量,显然不可以。

特别值得一提的是,调试程序时学会查看内存中的内容对深入掌握C/C++语言编程好处巨大。看看下面两行代码,按F9键把断点设置到printf语句所在行:

按F5键执行整个程序,断点会停留在printf所在行上,此刻,程序正处于调试中,如图2.18所示。

图2.18 正处于调试状态中

在此种状态下,按下快捷键Alt+6或选择“调试”→“窗口”→“内存”→“内存1”命令,则在整个Visual Studio 2019的下方,就打开了“内存”查看窗口,只需要在其中输入内存地址,就可以看该地址所对应的内存中内容,如图2.19所示。

在图2.18所示的第78行,双击aaa变量名,直接按住鼠标左键往图2.19中左上角“地址”右侧的编辑框中拖动,若图2.19框住的那部分内存中内容没变化,则按一下Enter键,此时,变量aaa所代表的内存地址中的内容便显示到“内存”查看窗口中,如图2.20所示。

图2.19 在调试时可以打开调试窗口中的“内存”查看窗口来查看内存中的内容

图2.20 变量aaa在内存中的内容

在图2.20所示的“内存”查看窗口中,左上角的“地址”部分显示的0x00D3F288是变量aaa所代表的内存地址。往下看,分成三部分:左侧部分显示的内存地址,是变量aaa的地址和紧邻的内存地址;中间部分显示的是内存地址中保存的十六进制数字内容(内存中保存的数据都是二进制数据,但为了方便观察,Visual Studio 2019把这些二进制数据以十六进制形式显示出来,四位二进制数字显示成一位十六进制数字);右侧部分显示的是内存中的十六进制数字所代表的一些可显示字符,从中可以找到"safasdfa\0def"字样,通过逐个字符比较,可以看到,'\0'这个转义字符在内存中显示的十六进制数字是00,其他的字符,如图2.20中'a'字符在内存中显示的十六进制数字是61,十六进制数字61正好对应十进制数字97,而十进制数字97正好就是字符'a'的ASCII码(见表2.4),所以在内存中存放一个字符时,存放的其实就是该字符的ASCII码。

字符串的存放需要用到字符数组,字符数组在后面章节中介绍。