前言
相信各位小伙伴一定看过这样的言论,某某B乎大佬xxx,发了一堆文字,一定要学好底层,一定要学好C语言!!,然后下面各种抬杠。
B乎大佬:C语言是最牛掰的,一定要从C语言开始学起。
杠精张三:学C有啥用,啥都干不成,直接学Java,然后上框架,直接开始开发。
杠精李四:@杠精张三,你会懂C吗,瞎胡扯,xxx一堆理由,反正,C是一定要学的,基础一定要打好。
...各路杠精大V正在赶来...
杠精王五:PHP万岁,PHP NB,PHP天下第一。
嗯...,可能各位小伙伴或多或少,都看到过这些言论,作为吃瓜群众,我们乐呵乐呵就好了,咱们回归正题叭!!
是否需要学习C语言,我的回答是,不是必要的,但是需要懂为什么要学习C语言。
为什么要学习C语言
嗯,,,今年是2020年,要是从目前的各种开发项目中开说,C语言的确是用的很少,除了嵌入式等一些一定领域,基本很少能见到C的踪影了,但是为什么还是一直能听到xx说要学好C语言呢?
按照我的理解,其实学习C语言,学的并不是这个语言,而是这个语言背后所代表的一些东西,代表的一些设计,代表的一些本质。
C语言学的好,究竟会带来什么优势
相信不少萌新在群里可能听到某个大佬说,我一星期学完了xx语言,然后直接上手干活,然后你默默的说了一句,装13,也可能,你们就在群里直接杠起来了。
那么,真的可以说,一周,或者两周时间,学会一门语言吗?。
我可以负责任的,告诉你,绝对没问题,但是需要建立在强大的基础上。
而指针,是一个特别重要的基础,现在不管哪个语言,其实本质都是指针的应用,只不过是封装的简单了而已。
但是这造成的就是根基如果不稳,就会造成一些莫名奇妙并且不懂的问题,尤其是对萌新来说。
所以,不管现在不管在任何阶段,没有学习C语言的一定要学学C,捡起曾经丢下的重要的基础。
那么,就先听我简单的入门一下吧。
所需要的技术栈
本次使用的技术栈是Go语言,理论来说是用C语言的,但是因为在指针这一块入门时,Go和C的本质基本一样,所以就采用更加人性化的Go语言。
后期会在加上Python,和Go对比一下,区别在哪,看看烧了一把火的Python是如何分配内存的。
当前,在看此文章时,我还是建议小伙伴有一定基础的,至少能看懂怎么定义变量啥的都行。
操作系统各硬件的关系
首先,我们需要了解一下计算机主要组成部分。
首先,简单的说,至少由 CPU 内存条 硬盘 显卡 显示器 操作系统(Linux,Windowns)等。
那么这些硬件是如何互相配合的呢。
嗯...大概是这样子的,有点丑。
简而言之就是:
- 系统上的每个应用(qq,微信,等)想要让电脑播放音乐了,显示器显示个东西了,像硬盘写入个文件了,都需要经过操作系统的同意。
- 操作系统调用CPU完成指令的执行,CPU将打开的应用读取到内存条中,所以,为什么原来在机械硬盘会那么卡,机械太慢了,现在的固态嗖嗖嗖的就完成了硬盘数据到内存条数据的转移。
- CPU分析读取到内存条中的应用数据,如果是CPU处理的数据,自己拿走计算,如果是显卡处理的数据,调用给显卡计算,如果是声音数据,给声卡计算,等。
- 通过以上协调,整个应用基本就能跑起来了,如果需要将数据写入硬盘,CPU在将内存条中的写入硬盘就行了。
好嘞,通过上述,我们基本可以了解到操作系统和各硬件的协调关系。
悄悄的说个秘密咯,我们写的代码,基本都是运行在内存条中的呢,同理,上述所说的应用,基本也是将应用的代码跑在内存条中的。
内存条
没错,就是这玩意,内存条。
同理,我还还可以这样理解内存条内部的结构。
我们可以将内存条理解成一个个房子,就像这样。
依然还是很丑...
但是我们的内存条是有的坐标的,也叫地址,每个小格子里放着一个个的值。
但是通常情况下,我们都是平面图理解的,就像这样。
地址(坐标)一般以十六进制表示,值该是啥就是傻。
代码简述
我们来看一段非常短Go的代码。
声明一个age变量并且赋值为18,并且输出。
- package main
- import "fmt"
- func main() {
- var age int = 18
- fmt.Println("我今年:",age,"岁")
- }
在内存中如何表示。
我们的变量名age指向了0x1001地址,并且输出了0x0001存储的值。
就像这样。
注:一定要理解这句话,变量名指向的就是内存条上的地址。
上述age指向就是地址0x1001。
但是我们在fmt.Println("我今年:",age,"岁")打印时,我们打印的是地址里面的值。
同理,我们在赋值,交换变量时,还是是地址里面的值。
例如:
上述代码内存分配图。
age2会重新申请一个地址存储age的值18。
可能有时候可能会有人问,星期八,有没有这种情况,他俩同时指向一个内存,这种不是更省内存嘛。
结果:当然会,这种情况,我们后面会讲到的,现在能看懂就行,一步一步来。
结论
变量名指向的是内存地址。
我们在赋值时,或者打印等操作变量时,操作的是地址上面的值。
本文转载自微信公众号「 Go语言进阶学习」,可以通过以下二维码关注。转载本文请联系 Go语言进阶学习公众号。