百科问答小站 logo
百科问答小站 font logo



C/C++中,int a=15;a储存在哪? 第1页

  

user avatar   yao-dong-27 网友的相关建议: 
      

a 只是个名字,为了让你方便使用,程序编译之后a这个名字是不存在了,变成了一个具体的内存地址,这个内存地址里的值是 15.

如果C语言语法允许,你也可以写成这样,直接指定固定的地址。

int [0x1000xxxx] = 15;


user avatar   Ivony 网友的相关建议: 
      

一般来说,a直接存在编译后的代码里面,写死偏移量……


user avatar   arrayJY 网友的相关建议: 
      

你的问题其实在问,符号a被放到什么地方了呢。答案取决于你把a放到了什么地方,以及你编译时的参数。如果你将他放在全局区,他会被编译到符号表的.data区,如果他只是个局部变量,一般符号表不会把他保存起来,但你可以通过编译选项-g使得符号表也会将局部变量保存进来。

举两个简单的例子:

1.局部变量

       int main(){     int a = 15; }      

编译出的汇编是:

       main:         push    rbp         mov     rbp, rsp         mov     DWORD PTR [rbp-4], 15         mov     eax, 0         pop     rbp         ret     

不知道你能不能看懂汇编,不懂也没关系。你可以找找里面有没有类似于a的东西?貌似没有吧。然后你找找15,这回有了,在第四行的mov DWORD PTR [rbp-4], 15 中有一个15。这句汇编的意思是:把15这个值放到%rbp值偏移-4的地址上。(%rbp 是一个寄存器,其他的%rsp%eax也同样是寄存器),那%rbp的值是什么呢?再往上一行,把%rsp的值放入%rbp中。而在x86-64架构下%rsp默认是栈顶地址寄存器。那么这么分析一通,还是没有看到a在哪。其实在编译过程中,对局部变量的符号的操作就会被直接编译成对寄存器、栈的操作,而原有的符号会消失(除非你开启了-g编译选项,那么编译器会保存局部变量到符号表用于调试)。

2.全局变量

       int a = 15; int main(){}      

其汇编是:

       a:         .long   15 main:         push    rbp         mov     rbp, rsp         mov     eax, 0         pop     rbp         ret     

这回你可以清楚的在第一行就看到了a,那么为什么局部变量不会保存a的符号,而全局变量要保存呢?这涉及到链接问题。你应该知道C/C++可以多个源文件编译链接成一个可执行文件,那么假如不同文件中有相同名称的全局变量该怎么办?有一些文件可能引用了其他文件的变量又该怎么办?这个时候就需要符号表的帮助了。

更多的细节可以参考CSAPP第七章。




  

相关话题

  golang 为什么没有三元运算符? 
  为什么我写代码时总是手滑把main打成mian? 
  为什么在汇编语言中需大量使用跳转指令,而在C语言中却尽量避免使用goto语句呢? 
  C++在面向对象编程中,非虚继承和非虚析构函数的存在是为了解决什么问题? 能否都用虚继承和虚析构函数? 
  为什么很多大牛在写题的时候要加一堆宏? 
  c++ 为何开源库都要编译? 
  为什么C++的 extern "C" 里面可以使用C里面不存在的STL和引用&等C++才有的特性 ? 
  面向对象中,平行继承体系是否尽量完全抛弃? 
  C++ 几十年来为什么没给 break 语句加上参数? 
  C语言中,为什么指向指针的指针的类型是int **?类型的话直接int*不就行了? 

前一个讨论
有哪些看似聪明,实则很傻的行为?
下一个讨论
中国四大名著哪一篇能够获得诺贝尔文学奖?





© 2024-11-12 - tinynew.org. All Rights Reserved.
© 2024-11-12 - tinynew.org. 保留所有权利