在上一讲中,我们介绍了数据的存储原理、不同类型数据的数据范围以及由于数据范围的限制而产生的溢出现象。其中在定点存储的结尾我们简单提到了一句关于字符型数据的存储方式。那么,字符型数据在内存中是怎么存储的呢?存储的内容和我们看见的字符又有什么关系呢?
一、字符数据的存储原理
1、存储原理
字符型数据的存储原理本质上与整数型完全相同,只不过在存储之前需要进行转换:计算机会将我们看到的、输入进计算机的字符图像按照字符集转化为整数型数据,再对其进行存储。以字符的方式进行输出时,再将其还原成字符图像进行输出。
2、常见的字符编码表(字符集)
编码对应的文字图像是有限制的,占用字节数较小。由于空间大小的限制,1字节的数据类型去掉符号位最多显示256个字符、2字节的最多存储65536个字符。
常见的字符集如下:
在我们C语言的学习中,主要研究ASCII编码表体系中的字符与数据关系,ASCII码与符号的对应关系(即ASCII码表)如下:
3、字符型数据的算术运算
由于字符型与整数型数据的存储原理相同,所以字符型的数据也可以进行算术运算,例如:
#include <stdio.h>
int main()
{
//1-------------------
char aa = 'a';
aa = aa + 2;
printf("%d %c\n", aa, aa);
//2-------------------
int bb = 3;
bb = bb + '!';
printf("%d %c\n", bb, bb);
//3-------------------
char cc = 'A';
cc = 'A' + '0';
printf("%d %c\n", cc, cc);
return 0;
}
在上面的代码中我们共举了三个例子:
(1)定义一个char类型的变量aa,初始化为字符’a’,将aa的值+2,再分别以十进制和字符的方式输出(格式化输出方式,下一讲中会进行讲解);
(2)定义一个int类型的变量bb,初始化为3,将bb的值加上字符’!’,再分别以十进制和字符的方式输出;
(3)定义一个int类型的变量cc,初始化为’A’,将bb的值加上字符’0’,再分别以十进制和字符的方式输出;
这里要注意的是:在代码中需要表示字符或字符串时,必须用英文状态下的单引号’ ’(字符)或双引号” ”(字符串)引起来。
输出结果如下:
由于字符’a’的ASCII码值为97,将其+2后结果为99,该ASCII码对应的字符为’c’,所以第一行输出结果为:99 c
由于字符’!’的ASCII码值为33,将其与3相加的结果为36,该ASCII码对应的字符为’$’,所以第一行输出结果为:36 $
由于字符’A’的ASCII码值为65,字符’0’的ASCII码值为48,二者相加的结果为113,该ASCII码对应的字符为’q’,所以第一行输出结果为:113 q
4、汉字字符的存储方式
由于汉字的文字较多,1字节的数据范围无法存储所有的汉字字符,所以通常使用2字节来存储汉字字符,保存汉字用的数据类型为wchar_t类型(宽字符类型,长度为两个字节,主要用在国际 Unicode 编码中)。
举例:
#include <stdio.h>
#include <locale.h>
int main()
{
wchar_t w = L'阿'; //L表示该字符为宽字符,需要使用两个字节的空间来存储
setlocale(LC_ALL, "chs"); //设置本地语言为简体中文
printf("\n%wc\n", w); //输出形式%wc
return 0;
}
输出结果:
二、转义字符
在C语言中,字符除了可以用字符本身表示以外,也有一些其他的表示方式。常见的表述方式可分为五类:
(1)字符本身:例如’a’ ’A’ ’0’
(2)十进制的编码:例如97 65 48
(3)八进制的编码(转义字符):例如’\141’ ’\101’ ’\60’或’\060’
(4)十六进制编码(转义字符):例如’\x61’ ’\x41’ ’x30’
(5)转义字符:
这里需要注意的是:除了十进制编码的表示方式之外,其余任何表示方式都需要在单引号’ ’或””双引号内表示。
我们来简单试验一下:
#include <stdio.h>
int main()
{
char c1 = 'b';
char c2 = 65;
printf("%c %c \146\t\x69\n\' \\", c1, c2);
return 0;
}
上面这段代码中,我们使用字符本身初始化了变量c1,使用十进制的方式初始化了变量c2,然后使用printf()进行格式化输出,输出的字符串中 \146 表示使用八进制表述字符’f’, \x69 表示使用十六进制表述字符’i’, \t \n \’ \\ 均为转义字符,分别表示水平制表、换行、单引号、反斜杠。输出结果如下: