关于定义变量 内存地址分配的问题

xiayiguo 2013-04-05 08:08:43

# include <stdio.h>

int main (void)
{
int var1;
int var2;
int var3;
printf ("%10s%15s\n", "variable", "address");
printf ("%10s%15p\n", "var1", &var1);
printf ("%10s%15p\n", "var2", &var2);
printf ("%10s%15p\n", "var3", &var3);
return 0;
}

为什么结果是这样啊?
----------------------
variable address
var1 0012FF7C
var2 0012FF78
var3 0012FF74
Press any key to continue
-----------------
先定义的变量,为什么地址是后分配的啊?还是内存分配的时候,地址是从后向前分配的?
...全文
262 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wugui414 2013-04-07
  • 打赏
  • 举报
回复
1#++
常如意 2013-04-07
  • 打赏
  • 举报
回复
Athenacle_ 2013-04-07
  • 打赏
  • 举报
回复

As to the historic rationale, I can't say for certain (because I didn't design them). My thoughts on the matter are that early CPUs got their original program counter set to 0 and it was a natural desire to start the stack at the other end and
 grow downwards, since their code naturally grows upward.

Note that this setting of the program counter to 0 on reset is not the case for all early CPUs.

One of the first things some historical CPUs would do would be to scan memory from the top until it found a location that would read back the same value written, so that it would know the actual RAM installed (e.g., a z80 with 64K address space didn't necessarily have 64K or RAM, in fact 64K would have been massive in my early days). Once it found the top actual address, it would set the stack pointer appropriately and could then start calling subroutines.
http://stackoverflow.com/questions/2035568/why-do-stacks-typically-grow-downwards
Athenacle_ 2013-04-07
  • 打赏
  • 举报
回复
一些体系结构的栈生长方向

x86          down
SPARC        in a circle, very clever architecture, see below.
PPC          down, I think.
System z     in a linked list, I kid you not.
             (but still down, at least for zLinux).
ARM          selectable (thanks, Michael Burr).
Mostek6502   down (but only 256 bytes).
RCA1802A     any way you want, subject to SCRT implementation.
PDP11        down.
来自 http://stackoverflow.com/questions/664744/what-is-the-direction-of-stack-growth-in-most-modern-systems/664779#664779
Athenacle_ 2013-04-07
  • 打赏
  • 举报
回复
自然规律 对于现代的CPU来说,这个仅仅是个历史问题
赵4老师 2013-04-07
  • 打赏
  • 举报
回复
对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单! 指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认: 有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物; 而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。 这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑! 这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!! 提醒: “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
jiemo1123 2013-04-06
  • 打赏
  • 举报
回复
引用 2 楼 AnYidan 的回复:
引用 1 楼 Athenacle_ 的回复:1. 不同编译器可能会有完全不同的结果。 2. 就一般来说,的确是这样的结果。一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址 一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址
++
xiayiguo 2013-04-06
  • 打赏
  • 举报
回复
引用 1 楼 Athenacle_ 的回复:
1. 不同编译器可能会有完全不同的结果。 2. 就一般来说,的确是这样的结果。一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址
我在网上搜这个知识,有人说栈从低地址从高地址生长,不符合自然规律,是什么意思啊?
xiayiguo 2013-04-06
  • 打赏
  • 举报
回复
引用 1 楼 Athenacle_ 的回复:
1. 不同编译器可能会有完全不同的结果。 2. 就一般来说,的确是这样的结果。一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址
明白了!
AnYidan 2013-04-05
  • 打赏
  • 举报
回复
引用 1 楼 Athenacle_ 的回复:
1. 不同编译器可能会有完全不同的结果。 2. 就一般来说,的确是这样的结果。一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址
一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址
Athenacle_ 2013-04-05
  • 打赏
  • 举报
回复
1. 不同编译器可能会有完全不同的结果。 2. 就一般来说,的确是这样的结果。一般的x86机器上,栈从高地址向低地址生长,看起来的结果就像先定义的变量在相对较高的地址

69,382

社区成员

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

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