c中存储在内存中的函数在哪里?有人能用简单的语言解释吗?
#include stdio.h>
void g()
{
int a=7;
}
int main()
{
printf("%dn",sizeof(g()));
printf("%p",&g);
return 0;
}
以下程序的输出为
1
00007ff6ee001581
以及函数内部的变量被存储并与函数地址链接
函数内部的变量存储在堆栈中。
每个链接和寻址部分都由链接器完成。
简单地说,链接器决定给什么标签或函数什么绝对地址,编译器决定如何排列它们,并能够相互寻址。
编译需要四个步骤:
Preprocessing [in which header file and microprocessor worked upon].
Compiling[In which they are converted into assembly code]
Assembly[In which codes are converted into machine level language but have relative addressing in respect to there starting]
Linking[When absolute address is given so when loaded they can address each other and files and linked in one]
#我认为最后几行可以帮助你
函数和变量是标签,每个标签都被翻译成地址。在机器上运行的代码具有表示这些标签的地址。不仅仅是c,所有编译过的语言都会经历它。就像在机器上一样,它的机器代码或只是布线。
如果你什么都不懂就说。很乐意帮助您
以下程序的输出是
输出的第二行是指向函数g
的代码的指针。它是该函数的地址,它是对函数存储位置问题的字面回答。
以及函数内部的变量存储在何处并与函数地址链接
变量a
是一个局部变量,因此它只在函数执行时存在。通常编译器会在堆栈上为局部变量创建空间——这是拥有堆栈的主要原因之一。一旦函数返回,它的局部变量就会从堆栈中弹出,它们就不存在了。换句话说,a
根本没有连接到g
的位置。
局部变量通常通过堆栈指针的某个偏移量来引用。调用函数时,会在堆栈上创建堆栈帧。堆栈帧基本上包括所有函数局部变量的存储,以及上一个堆栈指针的地址和返回地址。然后,函数的代码开始执行,由于编译器知道每个变量的相对地址(即它在堆栈帧中的位置(,因此可以很容易地计算绝对地址。正是由于这个原因,大多数处理器都有使相对寻址变得容易的指令。当函数退出时,堆栈指针被设置回上一个堆栈帧,处理器跳到返回地址。但这只是一种可能的实现方式;在拥有大量寄存器的现代处理器上,局部变量甚至可能不会存储在堆栈中——它们可能最终会出现在寄存器中。
include <stdio.h>
void g()
{
int a=7;
}
int main()
{
//printf("%dn",sizeof(g()));
//you cant use sizeof(g()) its a functiona and
//function not have anysize
printf("%p",&g);
//even you can't use here int a=7 that you declared in void g() as it is local to
//that function and this function cant access any function local variable
//but what it returns
return 0;
}
如果你想看到寻址比看到这个:
0000000000001135 <g>:
1135: 55 push %rbp
1136: 48 89 e5 mov %rsp,%rbp
1139: c7 45 fc 07 00 00 00 movl $0x7,-0x4(%rbp)
1140: 90 nop
1141: 5d pop %rbp
1142: c3 retq
0000000000001143 <main>:
1143: 55 push %rbp
1144: 48 89 e5 mov %rsp,%rbp
1147: 48 8d 35 e7 ff ff ff lea -0x19(%rip),%rsi # 1135 <g>
114e: 48 8d 3d af 0e 00 00 lea 0xeaf(%rip),%rdi # 2004
<_IO_stdin_used+0x4>
1155: b8 00 00 00 00 mov $0x0,%eax
115a: e8 d1 fe ff ff callq 1030 <printf@plt>
115f: b8 00 00 00 00 mov $0x0,%eax
1164: 5d pop %rbp
1165: c3 retq
1166: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
116d: 00 00 00