第六章 运动的诗章:运行时数据结构
a.out 它是assembler output 的缩写形式;
a.out 这个名字是unix “没什么理由,但我们就是这么做的”思维的一例;
超级块(superblock unix 文件系统中的基础数据结构)就是用下面这个神奇数字唯一标识的
#define PS_MAGIC 0x011954 这个数字式Berkeley fast 文件系统的实现者的生日;
在UNIX中,段标识一个二进制文件相关的内容块;
局部变量并不进入a.out,它们在运行时创建;
堆栈段有三个主要用途:1 为函数内部声明的局部变量提供存储空间;2 进行函数调用是,堆栈存储与此相关的一些维护信息; 3 堆栈也可以被用作暂时存储区;
int main() {
int i;
printf("The stack top is near %p\n", &i);
return 0;
}
以上小型测试程序,可以发现你的系统堆栈的大致位置;
C语言中所有函数在词法层次中都是位于最顶层的;
指针失去了有效性(引用不存在的东西),被称为“悬垂指针(dangling pointer)”;
唯一能用的auto的地方就是使你的声明更加清楚整齐;
goto 语句不能跳出C语言当前的函数(这也是longjmp 取名的由来,它可以跳得很远,甚至可以调到其他文件的函数中);
#include<setjmp.h>
#include<stdio.h>
jmp_buf buf;
banana() {
printf("in banana()\n");
longjmp(buf, 1);
printf("you'll never see this, because i longjmped");
}
int main() {
if(setjmp(buf))
printf("back in main\n");
else {
printf("first time through \n");
banana();
}
return 0;
}
setjmp 和longjmp 在C++ 中变异为更为普通的异常处理机制“catch”和“throw”;
在unix中,当进程需要更多空间时,堆栈会自动生长。程序员可以想象堆栈是无限大的。这是unix胜过其他操作系统如MS-DOS的许多优势之一;