[深入浅出C语言]浅析字符型

126 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

前言

        本文为数据类型讲解的第四篇,主要介绍了字符类型是什么以及在内存中如何存储的,内容不多,实际上关于字符串还有一些没有讲的知识,打算放到后面再单独讲,可以期待一下哦。

        由于笔者水平有限,文章拙劣而纰漏难免,欢迎指正,希望于你有益。

关于字符型char

基本介绍

        char类型用来存储字符,但要注意,char是整数类型,实际上存储还是整数。

        还记得前面文章讲的吗,计算机存储数据都是数字数据,由无数的0和1按一定规定排序组成的,那为啥要叫字符类型?为什么说是用它来存储字符呢?

        实际上是这样的,计算机使用数字编码来处理字符,而我们用特定的整数表示特定的字符,最常用的编码是ASCII编码,比如65代表大写字母A,所谓的存储A实际上存储的是整数65。

        标准ASCII码范围是0~127,而C语言规定char类型占用内存为1字节。

image.png

        在C语言中,用单引号括起来的单个字符被称为字符常量,编译器会自动将其转化成对应的代码值,如'A'。

        因为字符是以数值的形式存储的,所以给char类型变量赋int型整数也是没问题的,只是要注意一下范围0~127。

        比如char cat = 65;如果系统能识别ASCII码的话就会认为是把A赋给的cat,但是最好不要这样赋,我也说了如果二字,有些系统不一定用的是ASCII编码,所以用字符'A'赋值最妥当。

为什么要有ASCII码表

        计算机本质只认识二进制,那么计算机为何需要字符呢?直接全部二进制不香吗?

        因为计算机是为了解决人的问题,可是,人怎么知道计算机解决了人的问题?你输出二进制结果,人能直接看懂吗?

        所以,为何计算机需要需要字符,本质是为了让人能看懂。

        那为什么又是英文的呢?中文不香吗?

        最早的计算机是美国人发明的,他们的语言是英语,大家想想,英语,不就是26个英文字母+一大堆标点符号组成的吗?

        另外,计算机刚刚开始发明,人家美国人只要能解决他们的问题就行,所以就有了现在的简单字符。

        计算机只认识二进制,而人只认识字符。所以,一定要有一套规则,用来进行二进制和字符的转化,这个就叫做ASCII码表。

image.png

        但是随着全球化和计算机互联网行业的蓬勃发展,世界上各个国家的人都需要使用计算机,那么不同国家语言不同,你这ASCII码表只能对应英语字母以及一些符号,那又如何显示其他语言比如中文呢?理论上是不是有多少种语言就制定多少张映射表呢?

        为了方便,人们制定了通用的编码标准比如UTF-8,几乎所有语系都能囊括。

非打印字符

        注意到了吗,ASCII表里有些奇怪的字符根本就打印不出来,如行为字符退格,换行,振铃等,那怎么表示这些字符呢?

        方法一:使用ASCII码,比如振铃对应ASCII码值为7,那就char beep = 7;。

        方法二:使用特殊的符号序列表示字符,即转义序列也叫转义字符。 

        转义字符顾名思义就是转变意义的字符,一般由+某个字符组成。

image.png

        活跃位置指的是显示设备(如屏幕)中下一个字符将出现的位置,就是平时所说的屏幕光标位置。

image.png

接下来介绍一下常用的转义字符

        首先,问大家一个问题,回车和换行有什么区别?

        可能有人会觉得回车不就是换行吗...

        但其实回车和换行...

        不是一回事!!

v2-bc7c684dd140632d558e51f67bef91b3_720w.jpg

真相是

        换行:活跃位置移动至下一行

        回车:\r 把活跃位置移到当前行的开始处,会把前面打印的清除掉。

image.png

        而敲回车键输入的\n就是将活跃位置移到下一行的开始处,也就是换行+回车。

image.png

        \t把活跃位置移到下一个水平制表点(通常是第1个,第9个,第17个,第25个等)

有趣的例子

#include<stdio.h>
#include<windows.h>
int main()
{
    int index = 0;
    const char* lable = {"|/-\\"};
    while (1)
    {
        index %= 4;//每满四清零
        printf("[%c]\r", lable[index]);
        index++;
        Sleep(50);
    }
}

        怎么样,是不是想起了“大风车吱呀吱呀吱呀转~”

大风车吱呀吱呀转.gif

继续讲转义字符

        因为  \,',"  都有特殊作用,所以在打印的时候无法直接打印,这就要用到转义字符了。

        想打印",就要用"

        想打印\,就要用\

        想打印',就要用'

        看看最后两个转义字符:

        \0oo,\后面是一个八进制数,比如\130,printf("%c", '\130');得到结果是打印出了大写字符X,为什么呢?\130先把130转变为十进制数也就是88,然后变成对应ASCII码值的字符。

        '\0oo'就代表一个字符,前面的0表示是八进制,省略了也是八进制数。 

         \xhh,\x后面是一个十六进制数,类同上面。

        实际上就是用八进制或十六进制的ASCII码来表示一个字符。

        举个例子就是'\101'等价于65等价于'A'。

巩固一下:

        C语言中有字符类型,但是没有字符串类型,使用双引号括起来的就是字符串。

//程序输出什么?
int main()
 {
    printf("%s\n","c:\test\628\test.c");     
    return 0;
 } 

image.png

        提示:八进制里没有8,'\628'明显不存在,只能是'\62',对应字符'2'。

ASCII码和转义字符的斟酌

        一般选择后者,假设使用'\f'或'\104',明显转义字符更好记并且可移植性更高,因为不使用ASCII码的系统中仍然有效。

        如果要使用ASCII码,一般写成'\032'比032更好,一是前者直接能看出来你想使用的是字符编码,二是前者能嵌入C的字符串中,如printf("hello!\007\n");,能明显把它们和普通字符区分开。

        在使用printf()打印字符的时候,使用不同的转换说明%c或%d打印结果不同。

image.png

关于char的有无符号

        有些C编译器把char当成有符号类型,范围为-128~127 ,而有些编译器把它当成无符号类型,范围为0~255,可以查阅一下limits.h头文件。

        根据C90标准,C语言允许在char前面加上unsigned和signed修饰以区分出无符号和有符号类型而不用管编译器如何。

        因为char实际上存储的是整数,所以可以用在不超过1字节范围大小的小整数的处理上,以节省空间。


以上就是本文全部内容了,感谢观看,你的支持就是对我最大的鼓励~

v2-b8a13c5e82d4e0449e840c2500a8a564_720w.gif