前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C/C++教学】关于char,我们来聊一聊

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

作者头像
短短的路走走停停
发布2019-05-14 19:10:03
6230
发布2019-05-14 19:10:03
举报
文章被收录于专栏:程序猿声

0x00 前排吹水

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

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程序员就要过来打我了,逃 )

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

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

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

睁大你们的眼睛,仔细瞧瞧。字符a呢???没有。里面存的是97,数字97,数字97。

所以啊,char类型的变量,并不是你们想象中的那样,把一个个字符硬生生塞进内存中放着。说了,计算机底层只认识0and1,再也容不下任何的小三......所以,在内存中它只能存数字啊,数字啊,数字啊,字啊,啊.....

0x03 ASCII码表

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

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

0x04 相关疑惑的解释

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

代码语言:javascript
复制
#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考得高高的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿声 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 前排吹水
  • 0x01 char究竟是个什么东西?
  • 0x02 char和数字有什么关系?
  • 0x03 ASCII码表
  • 0x04 相关疑惑的解释
  • 0x05 写在后面
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档