目录
PPT 1|开场与主题引入 PPT 2|程序围绕数据运行 PPT 3|RAM 与地址 PPT 4|变量是地址抽象 PPT 5|变量生命周期 PPT 6|数据类型的两个底层问题 PPT 7|类型决定空间大小 PPT 8|类型决定解释规则 PPT 9|课堂总结 PPT 10|下节课引子PPT 1|开场与主题引入
同学们好,欢迎来到咱们《程序设计基础》的课堂。
今天这节课,我们要聊两个大家可能觉得“闭着眼睛都能写出来”、但其实非常核心的概念:变量和数据类型。
刚接触写代码的同学,肯定对这句代码不陌生:age = 20,或者在 C 语言、Java 里带个类型,int age = 20。
乍一看,这有啥难的?不就是建了个叫 age 的变量,然后把 20 塞进去嘛。
话是这么说,但如果我们仅仅停留在“把 20 塞进盒子”这个认知上,以后学到数组、指针、内存管理甚至编码的时候,你绝对会觉得特别吃力,觉得知识全散架了。
所以今天呢,我想带大家往下挖一挖,从“内存”这个更底层的视角,重新认识一下变量和数据类型。
上完这节课,我希望大家脑子里能有个清晰的画面:变量绝不是一个空洞的名字,它背后实打实地对应着一块内存空间;数据类型也不是死板的语法规定,它其实是在规定内存应该分多大、里面的 0 和 1 该怎么读。
换句话说,咱们今天不背概念,我们把变量和数据类型扔回到程序真实运行的环境里,看看它们到底帮计算机解决了什么大麻烦。
PPT 2|程序围绕数据运行
学计算机的同学可能听过一句名言,图灵奖得主尼古拉斯·沃斯说的:“程序 = 数据结构 + 算法”。
这句话虽然短,但基本把程序的底裤给看穿了——揭示了咱们写代码的本质。
咱们平时写的程序,真不是光让电脑一行行死板地执行命令。程序真正在干嘛?其实就是在倒腾数据——把数据组织好,然后按步骤处理掉。
大家想想平时用的系统。比如登录,你输入账号密码,程序收进来;然后去库里比对、校验;最后告诉你登录成没成功。
再比如淘宝买东西。程序拿到商品标价、你的下单数量;接着算总价、扣库存;最后给你弹个订单页。
就算是现在火得一塌糊涂的大语言模型,底层逻辑也是一样的。你敲一段话进去是数据,它在后台疯狂计算的是数据,最后吐出来给你的回答,还是数据。
所以,其实咱们可以说,程序运行就干三件事:收数据、盘数据、交结果。
既然天天跟数据打交道,那这些数据总得有个安身之处吧?
在程序跑起来的时候,数据基本都住在内存里,也就是 RAM。CPU 如果要干活,得先去内存里把数据揪出来,算完了,再把结果塞回内存,或者输出到屏幕上。
所以,要搞懂变量和数据类型,咱们得先建立一个共识:程序不是飘在半空中变魔术,它是在实打实的物理内存里,一点一滴地读写数据。
PPT 3|RAM 与地址
大家看屏幕上这个图,这是一个抽象过的内存画面。
说实话,真实的物理内存比这复杂得多。但咱们在基础课里,可以简单粗暴点:把内存想象成一长排小格子,每个格子都能存东西。
为了让 CPU 每次都能精准地找到某个格子,每个格子都必须有个门牌号。这个门牌号,在计算机里就叫“地址”。
地址这玩意儿,对计算机来说太舒服了。CPU 干活的时候就认这个:“去某某地址拿点数据”,“去某某地址写个结果”。
比如你们在图上看到的 0x7FFF001A,这就是个十六进制的地址。机器看着很亲切,但咱们人看着就头大,太反人类了对吧?
如果咱们写的程序里就存那么一两个数据,你死记硬背记住一两个地址也就罢了。
但稍微正经点的程序,数据都是海量的。搞个教务系统,学生的姓名年龄学号成绩全在里面;搞个订单系统,一堆商品价格库存。这要是全靠程序员去记那些十六进制的门牌号,那不仅头秃,代码还极其容易写出 Bug。
这时候,高级编程语言站出来了,给大家带来了“变量”这个大救星。
变量是干嘛的?说白了,就是为了让我们不用去背那些反人类的门牌号,而是给这些内存格子起个我们人能看懂的名字,用名字去操作数据。
PPT 4|变量是地址抽象
age = 20。】咱们来看个最简单的例子:age = 20。
从字面上看,咱们都懂:有个变量叫 age,里面装了 20。
但如果你透过屏幕看到内存里,其实发生了一堆事儿。
程序跑起来的时候,系统会在内存里满地找:“哎,哪儿有块空地能放下 20 啊?”找到了之后,编译器或者解释器就会把这块地的门牌号和 age 这个名字死死绑定在一起。
从这之后,你在代码里只要一喊 age,程序立马就能顺藤摸瓜,找到背后那块真实的内存地盘,把里面的值拿出来,或者塞个新值进去。
所以,变量到底是个啥?咱们可以给它下个定义:变量,就是内存地址的人性化代号。通俗点说,它就是某块内存空间的小名。
大家一定要记住这个概念。变量不是天上掉下来的符号,它背后一定实打实地占着一块地。
当然了,不同语言在底层的玩法不太一样。C 语言比较直接,变量基本就是地址的替身;但在 Python 或者 Java 里,这中间还隔着一层对象引用的机制。
不过万变不离其宗,它们的核心思路是一致的:用人话,去操作机器的内存。
这也就能解释为什么变量的值能“变”了。
你写 age = 20 的时候,内存格子里装的是 20;过会儿你写个 age = 21,age 这个名字还是那个名字,但它背后那个格子里装的内容,已经被替换掉更新了。
所以大家注意,所谓“变量”,不光是说它有个名字,更关键的是它背后那块地里种的庄稼,是可以在程序运行中随时换的。
PPT 5|变量生命周期
搞懂了变量和内存的关系,咱们再来看看变量的一生是怎么度过的。
一个变量从出生到没用,差不多分三步:声明、赋值、销毁。
第一步,声明。这就好比你去占座。
你告诉程序:“嘿,我要用个变量了。”系统就会根据规矩,在内存里给你划出一块地,并且把这块地和你起的名字绑定上。
第二步,初始化或者赋值。这就好比你往占好的座位上放东西。
初始化就是你第一次往里头塞数据。至于赋值嘛,那是可以反复折腾的。每一次赋值,其实就是把原来格子里存的东西扔掉,塞个新的进去。
就像刚才的 age,先是 20,后来变 21。你在代码里看着是值变了,在内存的视角看,就是那块地里的数据被覆盖了。
第三步,销毁。这就叫人走茶凉,收回地盘。
当这个变量离开了它的作用域,或者程序觉得这数据没用了,那这块内存早晚得还给系统。
不同语言收地盘的方式不太一样。C 语言属于那种你得自己打扫卫生的,全靠程序员手动管;Java、Python 这种就配了“保洁阿姨”,有垃圾回收机制,会自动帮你收。
但不管咋样,内存这玩意可是金贵资源,不可能让你无限占着,用完了都得还。
所以大家看,变量可是活生生的。它有出生,有干活,也有退场。
它能“变”,因为格子里能换东西;它有生命周期,因为它实打实地占着你电脑里的资源。
PPT 6|数据类型的两个底层问题
好了,讲到这儿,大家应该心里有数了:变量背后,其实就是内存空间。
紧接着,硬茬就来了,咱们今天要讲的第二个核心:数据类型。
很多刚学编程的同学可能会抱怨:“这数据类型不就是语言给我上的紧箍咒吗?整数非得写 int,字符非得写 char,好麻烦啊!”
但如果你从内存的视角来看,这根本不是什么语法限制,它其实是在解决底层的两个大问题。
这第一个问题啊,就是:这块内存,我到底该给你划多大?
你想想,存一个英文字母,存一个普通的整数,和存一个精确到小数点后十几位的小数,它们要占的地盘能一样吗?如果划小了,数据根本塞不下;要是划大了呢,又白白浪费了宝贵的内存空间。
第二个问题更深奥一点:这块内存里存的一堆 0 和 1,我到底该怎么去理解它?
要知道,电脑内存里存到底全是 0 和 1。如果没有人来解释,那一长串二进制就只是干巴巴的电信号,它不知道自己是个整数,还是个字母,又或者是个小数。
数据类型是干嘛的?它其实就是给这块内存发了一份“使用说明书”。
它一方面告诉系统:“哎,给这哥们儿划几个字节的地”;另一方面又告诉系统:“这地里的 0 和 1,你得按什么规矩来翻译”。
所以,大家今天记住我这句总结:数据类型 = 空间大小 + 解释规则。
咱们先来看看前半句,数据类型是怎么决定空间大小的。
PPT 7|类型决定空间大小
大家看一下屏幕上这个表,这是咱们最常见的几种数据类型和它们对应的占地面积。
先说最基础的 char,字符型。
在绝大多数入门的情况下,char 就占 1 个字节。1 个字节是啥概念?就是 8 个比特(bit),也就是能放 8 个 0 或者 1。它一般用来存存字符,或者在底层当最基础的搬砖材料用。
再看大家最爱用的 int,整数型。
这哥们儿通常占 4 个字节,也就是 32 个比特。要是它是带符号的(有正有负),那它能扛住的最大正数,差不多是 21 亿左右。
最后看 double,双精度浮点数。
它口气大,直接占 8 个字节。为啥要这么多地?因为它不仅要管小数,还得管精度,能表示的范围特别大。
这里得给大家提个醒:不同语言、不同操作系统下,这些类型到底占多大,可能会有点出入(比如 C 语言里的 int 就挺随便的)。
但咱们初学的时候,先脑子里建个模型就行:类型不同,占的坑就不同。
而且这坑的大小,不仅决定了费多少内存,还死死卡住了你能存多大的数。
举个例子,刚才说普通的 32 位 int 顶破天装 21 亿。现在地球上有 80 多亿人,你要是非得把全球人口塞进一个 int 里,会出啥事?
会“溢出”。
溢出可不是像水杯里的水真流一桌子,而是因为位数不够了,装不下那么大的二进制,最后高位被砍掉,算出来的结果直接离谱到家。在实际业务里,这往往就是个大灾难。
所以,数据类型的第一个大作用:量体裁衣,给数据挑个大小正合适的房子,既不浪费,也别挤爆了。
PPT 8|类型决定解释规则
01000001。】搞定了大小,咱们来看看第二个作用,也是更好玩的:决定解释规则。
大家看左边这串二进制:01000001。
我现在问你,它是个啥?如果你只盯着这 8 个位看,你绝对说不出来。它就是内存里静静躺着的 0 和 1。
但是,神奇的地方来了。
如果你告诉系统:“喂,按照整数的规矩给我翻译它!”系统一算,好,这串二进制对应的十进制数是 65。
如果你换个说法:“喂,按字符的规矩来!”系统就会去查 ASCII 码表,一看,嘿,65 对应的是大写字母 A。
发现没?这就是最核心的秘密:一模一样的一串二进制,换套规矩去解,意思就完全不一样了!
内存是个没脑子的仓库,只管存 0 和 1。真正赋予这些 0 和 1 灵魂的,是数据类型和编码规则。
所以平时我们说,这个变量是整型、那个是字符型、浮点型,其实我们是在给系统下指令:这块地里的数据,以后就按这个门派的武功心法来练!
整数有整数的规矩,字符要去查字符表。
遇到浮点数就更复杂了,系统还得把它切开,哪几位是符号,哪几位是指数,哪几位是尾数,按标准拼起来才能看。
所以,数据类型不仅管“要多大空间”,更管“这玩意到底怎么认”。
有时候你写代码,发现打印出来的东西乱七八糟、莫名其妙,其实不一定是内存搞错了 0 和 1,往往是你的解释规则用串台了,拿切菜的刀去剃头了。
行,讲到这儿,数据类型的底裤就被咱们看穿了:它就干两件事,分地盘,定规矩。
PPT 9|课堂总结
好嘞,咱们稍微收一收,总结一下今天这堂课。
第一,程序跑起来离不开数据。这些数据其实都是住在内存里,CPU 认得门牌号,也就是通过“地址”来抓取和修改数据。
第二,变量是干嘛的?它是为了给咱们程序员减负的。
机器认得那些鬼画符一样的地址,但我们人记不住。所以搞出个“变量名”,把复杂的地址藏在背后,让咱们能舒舒服服地用 age、score 这种人话去操作底层数据。
说白了,变量就是内存地址披上的一层人性化外衣,是咱们给人家的那块地起的小名。
第三,数据类型又是干嘛的?它是为了教机器怎么干活的。
数据类型就是份说明书,告诉系统:得给这小名划几个字节的坑,以及坑里的 0 和 1 到底代表个啥意思。
所以你们看,变量和数据类型,真不是写在书上折腾大家的枯燥概念。
变量帮我们找到数据,数据类型教系统用对数据。
我希望以后大家再敲下 int age = 20 的时候,脑子里别只飘过一行冷冰冰的代码,而是能有画面感:系统跑去内存里圈了块地,挂了个叫 age 的牌子,把 20 塞了进去,并且拿个喇叭喊了一声“以后这就按整数规矩来办啊”!
有了这种思维,你的代码才算真的写通透了。
PPT 10|下节课引子
最后呢,咱们留个小尾巴,给下节课做个预告。
今天咱们聊了整数、字符是怎么解释的。但要是再往底层挖一点,我们会碰到个大麻烦:负数怎么存?
就比如 -65 吧。
咱们刚才说了,内存里就只有 0 和 1,你上哪儿找个减号塞进去?根本没这个东西。
计算机内部为了存负数,可是花了大心思的。而且更有意思的是,计算机之所以能用一套非常死板的硬件逻辑,把加法和减法全给搞定,靠的全是底层对于整数存储的精妙设计。
这就是咱们下节课要深挖的重头戏:整数底层存储的“补码机制”,顺带还能把位运算给大家串一串。
好了,今天这节课咱们就先到这里。
希望大家下了课,再看到满屏的变量和数据类型时,眼里看到的都是底层的内存格子和二进制规矩。
大家辛苦了,下课!