c语言中变量的再度理解

最近看了一篇知乎,解答了我内心的疑问

question:

比如 int a = 5

我知道有一块内存,存了这个值5,a代表了这块内存。就好像给一个盒子起名叫a,这个盒子里装了5,现实中这个名字,也就是a只是存在人脑里的,不是实话的。
另外a,b等字符在计算机里用很小的整数储存,也就是a和65对应。

我的问题是 a = 5 的时候,有一块内存存了5,也就是这块内存是00000101,但计算机怎么知道这块内存叫a?这个名字a是在哪里储存的?
我的理解是否有一块专门存储变量名的内存,比如根据顺序第x块存了65,这个65又存了00000101的地址?但这样岂不是每个变量都是指针?

回答:
作者:周彬
链接:https://www.zhihu.com/question/34266997/answer/60437113
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我尝试从由底向上来解释题主的疑问,顺便推荐王爽的《汇编语言》,看了前几章题主应该就明白了,了解一点汇编,CPU工作原理和编译知识还是有必要的1.机器语言机器语言是机器指令的集合。电子计算机的机器指令是-列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。如应用8086CPU 完成运算s=768+12288-1280,机器码如下:101100000000000000000011000001010000000000110000001011010000000000000101每行代表一个指令,我只是搬运工,反正看不懂,现在估计也找不到几个不靠工具看得懂这玩意的人了~

[关于变量名]:机器语言中没有变量名的概念,一切操作都是直接对地址进行2.汇编语言早期的程序员们很快就发现了使用机器语言带来的麻烦,它是如此难于辨别和记忆,给整个产业的发展带来了障碍。于是汇编语言产生了。汇编语言与机器语言是每个指令是一一对应的,最终由汇编器把写有汇编语言的文本文件编译成可执行程序。例如:将寄存器BX内的数据到AX中(寄存器是CPU内部的一组存储器,大多数指令都需要先将内存里的数据读入寄存器后才能开始运算。AX,BX是其中两个寄存器的代号)机器指令:1000100111011000汇编指令:mov ax,bx[关于变量名]:汇编语言中就有变量的概念。在编译时由汇编器计算相关变量的偏移或实际地址,在编译出的二进制机器语言中直接使用该地址操作内存。3.C语言程序员们后来发现,用汇编语言写程序还是麻烦,因为它和机器指令意义对应,更加接近CPU的思维,而不是人的思维。于是发明了很多高级语言,C就是其中的一种。C语言编译的过程,实际上首先通过 “编译器”将C语言翻译成汇编语言,再通过“汇编器”将汇编语言转化成机器代码,对于编译器来讲,将C转化成汇编的时候,不是一一对应的关系,也就是说几行C代码,可能翻译成几十行汇编。而汇编语言指令和机器代码指令,从某种意义来讲,是一个东西,两者是一一对应的关系。[关于变量名]:C语言中处处是变量,即使是个指针,它自身也是个4字节的变量才能储存一个地址(32位程序)。编译后,有输出文件包括以下两种:可执行文件(xxxx.exe),一段二进制文件,其中代码段(代码段,数据段啥的也可以百度了解)的机器指令CPU可以直接识别执行。符号文件(xxxx.pdb),记录了变量和地址的对应信息。仅供调试使用,程序运行时不需要该文件。4.有了前面的介绍,我再来说说题主的问题题主问变量名储存在哪儿,变量名储存的机制是什么?回答如下程序运行时不需要知道某块内存对应的变量名,它只是按地址直接操作那块内存。C/C++编译器在编译时会计算出变量名对应的地址,在底层所有操作该变量的地方,都使用变量对应的地址参与运算。C/C++编译器还把变量名和地址对应的关系存在一个文件中的,这类文件叫符号文件。但是程序运行时不需要这些文件,没有这些文件程序一样可以正常工作。这些文件只是用来在调试时起作用的。看这份反汇编,也就是利用机器语言和汇编语言指令一一对应的关系,把机器语言还原成汇编语言的结果。可以看到,寻址都是通过直接用地址,或则寄存器+偏移量等操作完成的,关于变量名的信息在二进制可执行文件里已经完全没有了。如果在调试时想要恢复这些信息,就需要用到符号文件了。再看下面这份反汇编上图里有move eax,dword ptr [ebp-3C] 这样的指令, 而下图里有move eax,dword ptr [b]。也就是经过符号文件的帮助,在调试时可以把[ebp-3C]这样人看不懂的东西,还原成b这种人看得懂的变量名。在Windows下,符号文件的拓展名为pdb,一般xxxx.pdb这样的文件都是符号文件。如果要说计算机储存了变量名,在汇编/C/C++下应该指的就是这种了。再次强调程序运行时不需要知道某块内存对应的变量名,编译器已经将C语言翻译成二进制的机器语言,机器语言中没有变量名的概念,一切操作都是直接对地址进行,变量名只是保存在另一个与运行无关的文件里供人调试时使用的。当然上面是针对汇编/C/C++等编译语言说的。如果是Python等解释语言的话,其变量名和内存地址之类的信息解释器(解释器,编译器分不清楚自行百度)里是有相关记录的,具体是什么方式每研究过,Python可以参考《Python源码剖析》一书。如果题主是想知道编译时a的地址是怎么确定的,变量a及它的地址编译器是储存在一个什么数据结构里之类的话,可以好好看看编译原理,我没研究过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值