【C/C++教学】关于char,我们来聊一聊

简介: 刚刚发现,原来微信公众号的推文还可以用markdown写。激动得我赶紧装个13冷静一下(逃。不过话说回来,说到char这个东西,可能也是让很多新手朋友难(dan)受(ten)不已的东西。那么char和一般的变量类型又有什么区别呢?今天来一起聊聊。

0x00 前排吹水


刚刚发现,原来微信公众号的推文还可以用markdown写。激动得我赶紧装个13冷静一下(逃。不过话说回来,说到char这个东西,可能也是让很多新手朋友难(dan)受(ten)不已的东西。那么char和一般的变量类型又有什么区别呢?今天来一起聊聊。By the way, 0x表示16进制,再问......先看看下面的例子吧


微信图片_20220420190339.jpg

ch是一个char类型的变量,并且赋初值'a':

为什么cout输出ch+1 会输出98?

为什么同一个变量按照%d(整形输出)的结果是97?按照字符型%c输出又变成了'a'呢?


0x01 char究竟是个什么东西?


其实,char和int,float,double这些一样。如我们指针那篇说的一样,它是一种变量类型。那么,这种类型定义的变量,存的是什么呢?字符!就这么简单.....那么,什么是字符?低头看看你的键盘,上面显示的都是字符。比如a, b, c, A, B, C, *, ^, +,.....包括上面的逗号和点都是字符。And, 包括一些不可见的,比如\n回车符, \t制表符等等。char类型的变量就是存这些玩意儿的。


0x02 char和数字有什么关系?


在此之前,让小编问大家一个问题。我们都知道,变量存的值都是放在内存中的。既然char类型变量存的是字符,那么当我char ch = 'a'的时候,ch在内存中对应的东西是不是真的是一个字符'a'?


我只能说:


傻子都知道,计算机底层只认识0和1,说白了,在内存中除了0和1,再无其他...... 不信?我们写个程序到内存看看呗,在此之前让我打开宇宙中最强的IDE, Visual Studio 2015。貌似还没有之一(linux程序员就要过来打我了,逃 )


微信图片_20220420190511.png


两句cout<<内存地址 实在坑爹,给我来了一堆烫烫烫 f.....k.... 所以用了printf("p")表示输出内存地址。不过看到using namespace突然想起某乎上一个大神说的一句话:


敢于把using namespace写在头文件的人,都是敢于改变世界的人.......

貌似扯远了,回到正题,程序写好。砸门在printf后面下个breakpoint。然后在内存窗口中看看变量ch对应的内存中存的到底是什么玩意儿吧。


微信图片_20220420190522.jpg


睁大你们的眼睛,仔细瞧瞧。字符a呢???没有。里面存的是97,数字97,数字97。所以啊,char类型的变量,并不是你们想象中的那样,把一个个字符硬生生塞进内存中放着。说了,计算机底层只认识0and1,再也容不下任何的小三......所以,在内存中它只能存数字啊,数字啊,数字啊,字啊,啊.....


0x03 ASCII码表


这个表可不是泥萌去年买的那种表可以比的。~~前面说了,既然内存中只能存一堆01,那我的字符怎么办。哎,人的智慧总是无穷的。我们将一个个数字和我们需要的字符对应起来。比如我们要字符a对应的数字是97.那么我要存字符a的时候,是不是在内存中存一个97就能代表字符a了呢?ASCII码表就这样产生了。给大家找了张简单的让大家感受一下:

微信图片_20220420190738.jpg


所以啊,每个字符我们都用一一对应的数字对应了起来。这样要存字符的时候,我们就把字符相应的数字给塞进内存就行了。关于编码的相关知识,这里也有一段很长的历史,包括中国的GB2312,GBK,以及现在国际通用的uncode,and 还有什么utf-8.....估计讲到明天都扯不完。感兴趣的读者自行上网查一下吧。

0x04 相关疑惑的解释


我们再来明确一个问题,那上面说的,字符在内存中是数字的形式存的。那数字也是以数字的形式存的。当我访问这块内存的时候,我怎么知道里面放的97是对应字符a,还是实实在在的数字97?这里大家就明白类型的重要性了吧。比如下面代码

#include <iostream>
using namespace std;
int main()
{
   char ch = 97;
   int num = 97;
   cout<<ch<<num<<endl;
   return 0;
}


输出结果: a 97 为什么?变量ch和num在内存中存的都是数字97.这点毫无疑问,但是cout看到ch的时候,发现。卧槽这是一个char类型的变量,那我不能直接输出97,我要到ASCII码表里面找找,哦....97对应的是字符a,好吧我就把a给输出来吧。然后cout遇到num,这是一个int类型的变量啊,里面存的是97?哦,那把97输出来吧。

所以,取决于类型啊少年们......

回到一开始的疑问,


  • 为什么cout 输出ch+1是98?

我们上面说了,char类型定义的变量,其存的字符,都在ASCII码表里面有一一对应的值。我们只是把值存进去了,ch本身在内存中放的是97(字符a在ASCII码表中对应97),这个没问题。ch+1,内存中相应的值变成了98.然后cout输出ch+1的时候,不应该是b吗?(b在ASCII中对应的数字是98).我们上面说了,cout输出什么,是不是还要看类型?那么ch+1类型是什么?char类型?卧槽回家种田去吧.....说了多少遍,当char类型和int类型运算的时候,编译器会进行隐式的转换,把char类型变成int类型再进行运算,最终运算的结果自然也是int整形了。当cout遇到整形,那tm还管三七二十一,直接输出98了。


  • 为什么同一个变量按照%d(整形输出)的结果是97?按照字符型%c输出又变成了'a'呢? 我们之前讲过,printf输出的时候,不管里面存的是什么,只会老老实实按照我们给的格式输出。ch再内存中存的是97,那么按照整数%d输出,他就是输出97.按照字符型%c输出,他就老老实实到ASCII码表里面找对应的字符呗~~~


0x05 写在后面


好了今晚就聊这么多。第一次用markdown写推文,还是特么的有点紧张的。咳咳~其实很多东西,从本质上的理解更为重要,特别程序这块。比如最近看的8086汇编,感触最深的就是,在计算机底层,万物即bin(二进制)。各式各样的指令和数据也是变成一堆0和1放在内存中等着CPU去执行......扯远了,突然发现还有两篇英语课文没看......f....k...希望考试周的小伙伴们都能把GPA考得高高的。


最后送大家一句比较伤感的话:

有时候真的决定某些事情,就像char * 一样,从一开始就注定,无法改变。

相关文章
|
文件存储 C++
C/C++之分文件写静态通讯录详解(保姆级教学)
C/C++之分文件写静态通讯录详解(保姆级教学)
93 2
C/C++之分文件写静态通讯录详解(保姆级教学)
|
6月前
|
JSON C++ 数据格式
【C++】Visual Studio C++使用配置Json库文件(老爷式教学)
【C++】Visual Studio C++使用配置Json库文件(老爷式教学)
|
C++
C/C++指针进阶全(保姆级教学)
C/C++指针进阶全(保姆级教学)
64 0
|
6月前
|
关系型数据库 数据库 C++
【C++】Windows使用Visual Studio C++链接云数据库PostgreSQL(沉浸式老爷教学)
【C++】Windows使用Visual Studio C++链接云数据库PostgreSQL(沉浸式老爷教学)
|
6月前
|
人工智能 机器人 编译器
【C++】Windows端VS code中运行CMake工程(手把手教学)
【C++】Windows端VS code中运行CMake工程(手把手教学)
394 0
|
5月前
详细解读C++char类型函数
详细解读C++char类型函数
57 0
|
6月前
|
C++ Python
C++教学——从入门到精通 10.循环
学习编程建议先Python后C++,以避免C++思维影响。课程涵盖for、while和do while循环。for循环示例:`for(int i=0;i&lt;n;i++)`,用于计算114514天后的金币总数(1145140个)。死循环通过`for(int i=0;;i++)`实现,用`break`退出。while循环格式`while(条件)`,同样可解决金币问题。do while循环特点是先执行后判断,结构为`do{...}while(条件)`。
52 2
|
6月前
|
C++
【C++】std::string 转换成非const类型 char* 的三种方法记录
【C++】std::string 转换成非const类型 char* 的三种方法记录
172 0
|
6月前
|
人工智能 NoSQL 机器人
【C++】VS code如何配置使用C++(手把手教学)
【C++】VS code如何配置使用C++(手把手教学)
103 0
|
6月前
|
存储 自然语言处理 安全
【C++11保姆级教程】空指针(nullptr),long long类型,char16_t和char32_t类型
【C++11保姆级教程】空指针(nullptr),long long类型,char16_t和char32_t类型
161 0
【C++11保姆级教程】空指针(nullptr),long long类型,char16_t和char32_t类型