1、如何在下面的test函数里加入代码可以使程序运行起来输入和输出的相等?
(环境是vc6Debug方式下)
#include void test() {
int t;
scanf(“%d”,&t);
在这里加入代码
}
void main() {
int m;
test();
printf(“m=%d”,m);
}
2、请运行下面的代码,观察结果,有人说怎么是死循环,你同意吗?为什么?
#include int main() {
int i = 0;
int name[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (i = 0; i <= 10; i++) {
name[i] = 0;
printf(“ok\n”);
} return 0;
}
(我在VC6里编译运行了,程序不停地输出ok,调试后发现当i=10时,执行name[i]=0;后i就等于0了,不知道为什么会这样呢?)
答案:第一题解决的问题是到底变量t相对于变量m地址偏移了多少,首先他们都在栈中, 假设在执行int m之前esp=0×100,ebp=0×100,具体值是多少我们不关心,只关心变化了多少. 执行int m 然后esp=0xfc 然后进入test函数 进行ebp ebx edi esi压栈,为函数返回做准备,另外好像进入函数都有44h 的地址偏移,我不知道why,但是确实是这样子, 此时 esp=0xfc-0×10-0×44=0×100-0×04-0×10-0×44 也即偏移了0×04+0×10+0×44个字节 所以需要添加代码 *((&t)+0×01+0×04+0×11)=t; 0×04+0×10+0×44到0×01+0×04+0×11,你应该知道为什么吧,如果这不知道那你再好好看看指针.
第二题 就是数组下标越界访问,首先你得知道编译器是怎么存储的,高字节在高地址. 先说明一下,必须保证i和name数组在连续的空间,其实这个一般是连续的,但是不是绝对的. 好了,int i依然假设地址是0×100,然后name[9]=0xfc,name[8],…. 你还得知道为什么数组越界访问编译器不报错,因为实际上数组的访问还是被化作指针处理,比如name[9],编译器会做如下处理, *p=name,*(p+9); 好了你该知道为什么name[10]会访问i了吧! 循环中i=10时发生数组下标溢出,事实上修改了前一个压栈的局部变量(即i)的值