关于C的指针和编译的问题

miaoli78056414 2007-11-28 05:30:43
假设有函数int fun(int n){int a=100} 在编译时,应该给fun分配一个入口地址,是不是函数名字fun就是那个地址,也就是说fun是一个指针,那fun是不是被赋予了一个实际的地址空间(假设为2字节)存放地址,还是说在编译时没有给fun实际的地址空间存放入口地址,而只是在编译字符表里面指定fun的地址呢
因为我打出fun,它是一个地址,如显示为a,然后我又看&fun和*fun都是同一个值,都是a,那上面&fun 和*fun读出来的值到底是什么???还是根本就是一种语法错误,而后编译器就默认给他们都是fun的值呢?????
上面函数中的int a=100在编译时应该也被赋予了一个int型的地址空间,那那个形参int n有没有被赋予实际的地址空间呢???
同样象定义一个数组 int a[3],它在被编译的时候,编译器给它开辟了3个在内存中实际存在的int型空间a[0],a[1],a[2],而数组名字a是一个指针,那a有没有在内存中有实际的地址,从而让a存放数组首地址&a[0]呢,那我打出a的话,它是一个地址(数组首元素的),如显示为b,然后我又打&a他也是显示为b(这是根本就是错C没有这种语法???还是说实际给a分配了内存空间,叫它读a自己的空间地址,但为什么还是和读a是一样的值呢???)
...全文
141 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
mzyong 2007-11-30
  • 打赏
  • 举报
回复
fun 是一个地址,常量地址,是函数的入口地址,&fun对地址取地址还是它本身,
to:miaoli78056414
每次运行时数组或者函数的地址不变是因为这里的地址都是逻辑地址,并不是真正的物理地址,无论运行多少次同一个程序,它的逻辑地址都是独立的,即每一个进程的空间和数据是独立的,地址值一样很正常,只是他们的逻辑地址相同而已,真正运行时的物理地址是不同的,这有操作系统的内存管理决定的,
何哀何欢 2007-11-30
  • 打赏
  • 举报
回复
所有的fun会被编译器替换为 一个数, 所有的 &fun *fun, whatever fun 也会被替换。
chlaws 2007-11-29
  • 打赏
  • 举报
回复
呵呵,理论上不是那么回事, 只不过编译器在编译过程中为了方便 所以你看到的&a 没变,如果你把电脑再重起下 肯定就变了
miaoli78056414 2007-11-29
  • 打赏
  • 举报
回复
哦,另外
colxy你说的
“操作系统在你编译程序时,分配的地址应该是随机的,但是在实际中,经常可以看见多次大一地址是一致的”
我在实际编程当中也对这个问题感到迷惑
象我 int a=100 然后看a的地址&a,假设为100。(这个是在VC6.0中写的程序,编译的时候生成那个黑黑的DOS框的那个)然后,我不关掉那个执行窗口,然后多次点击debug下生成的那个.exe文件,所有的结果都是100(我问老师,他说上面的编译是模拟dos的环境,所以每次执行一样)(但我知道DOS是单道的,只能执行一个程序,难道每次执行都模拟一个DOS环境,所以地址都是100吗,那实际执行我运行10个那个.exe程序,在windows中肯定为分配10个a的地址空间,那怎么看全都是100呢???这个问题可能对我来说不好理解了,可能要去学虚拟存储、模拟和仿真了)),然后老师叫我写了window application他说这样每次执行地址肯定不会都是100,但我用WINAPI WinMain()那个写了个程序看a的地址,然后把debug下生成的那个.exe文件多次点击执行,结果地址还是100。哎,晕了。。。。。。
miaoli78056414 2007-11-29
  • 打赏
  • 举报
回复
我问老师的时候,他是这样说的
int a[5]={1,2,3,4,5};
编译的时候在编译字符表里面指定a本身是一个常量指针,a没有被在内存中分配实际地址(a是指向数组首元素地址的即&a[0],假设&a[0]地址为100,那么a=100,如果给a实际分配了内存地址的话,那么肯定有个地址来存a这个变量本身,那么可以用&a来读这个地址,但实际是&a=a,即a变量本身的地址和a指向的数组首元素地址是一样的),他说实际分配的只有&a[0],&a[1],&a[2],&a[3],&a[4]这5个内存地址,而a本身没有被分配。。。

所以实际到底是怎么样的呢???
colxy 2007-11-28
  • 打赏
  • 举报
回复

a作为临时变量,它在main()调用时,在运行期间它给其分配实际的物理空间,当运行结束后,释放其地址空间。
fun()本身就是函数指针,你甚至可以在你的程序将其作为函数的参数,如:

#include<stdio.h>

int add(int a,int b){
return (a+b);
}
int main(){
int a=2,b=3;
int c;
c=(*add)(a,b);
printf("%d\n",c);
return 0;
}
由于struct 类型要有精确的内存空间,所以一般在其内不能定义一般的函数,而是要定义函数指针。所以,函数指针在存储时是要有精确的大小的,即:函数fun要为其函数指针分配(int)大小的空间。
我的博客对此有进一步解释:http://blog.chinaunix.net/u1/54577/showart_427964.html
此外,按照理论上讲,操作系统在你编译程序时,分配的地址应该是随机的,但是在实际中,经常可以看见多次大一地址是一致的,你完全可以不理睬这点,因为只要你保证不发生内存泄露,你对内存的操作都是安全的。
由于数组a是一个指针,它要存储自己的首地址,当然应该开辟空间了。

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧