C语言【全局变量初值】和【入栈顺序对全局变量终值影响】的问题
本帖最后由 fergus1987 于 2017-6-30 14:03 编辑不知为何前两天发的贴被删掉了??首先感谢前一帖中为我解惑的大神(名字忘记抱歉)!在此重开一帖继续虚心求教两个问题!!
参考程序(将输入的十个数值用同一个函数分别输出均值、最大值、最小值)如下:
#include<stdio.h>
float Max,Min;
int main()
{
float ave(float a[],int n);
int i;
//float b={89,95,87.5,100,67.5,97,59,84,73,90},average;
float b;
printf("input 10 scores:");
for(i=0;i<10;i++)
{
scanf("%f",&b);
}
printf("Ave=%f\nMax=%f\nMin=%f\n",ave(b,10),Max,Min);
return 0;
}
float ave(float a[],int m)
{
int i;
float x=a;
Max=Min=a;
for(i=1;i<m;i++)
{
if(a>Max)
Max=a;
else if(a<Min)
Min=a;
x+=a;
}
x=x/m;
return(x);
}
疑问1、全局变量初值
如下图所示
程序并未对全局变量Max和Min赋初值,但在debug中发现系统自动为Max和Min赋0值,不知为何?
这与之前学习的局部变量不一样,印象中未赋初值的局部变量在debug中的值是一段内存地址?
疑问2、入栈顺序对全局变量终值影响
如下图所示
main函数中printf函数自右向左先后输出的是Min、Max和ave函数,因变量Max和Min在ave函数中被赋值,但按入栈顺序,此时输出的Max和Min值应为初始值0,所以可以看到dos框中该两个变量的值没有问题。
但debug中程序运行结束时可以看到查询变量值窗口中的Max和Min却是被赋给了经过ave函数处理后的值??
初学C,就这两个问题请教各位!请不吝赐教!
请参考 http://blog.csdn.net/u014181676/article/details/22103265 代码是错的
和入栈顺序无关
这是未定义行为 全局变量 静态变量
都会自动初始化为0值 时输出的Max和Min值应为初始值0
实际上 会输出什么无法确定
你运行结果输出 0 0
换一个编译器输出可能就这样了
这是一段错误的代码
你对这代码的理解只是牵强附会 求道于盲 发表于 2017-6-30 10:49
实际上 会输出什么无法确定
你运行结果输出 0 0
换一个编译器输出可能就这样了
谢谢指点!!对于你给出的代码有两点疑惑:
1、你所说的“会输出什么无法确定”是指printf函数的输出是没有出栈顺序的?从你的代码知道此时printf函数是从左向右输出的,因为输出结果,max和min被赋了新值了
2、为什么你的代码中没有在main函数中对foo函数进行申明?而直接进行定义了
0x0040140d <main+90>: movl $0x7,0x4(%esp)
0x00401415 <main+98>: lea -0x48(%ebp),%eax
0x00401418 <main+101>: mov %eax,(%esp)
0x0040141b <main+104>: call 0x4012f0 <foo>
0x00401420 <main+109>: fldl 0x404090
0x00401426 <main+115>: fstpl0x14(%esp)
0x0040142a <main+119>: fldl 0x4040a0
0x00401430 <main+125>: fstpl0xc(%esp)
0x00401434 <main+129>: fstpl0x4(%esp)
0x00401438 <main+133>: movl $0x403007,(%esp)
0x0040143f <main+140>: call 0x4019c0 <printf>
可以看到汇编里面是 先调用了 foo
然后
0x404090 入栈
0x4040a0 入栈
一直到调用printf
从这个运行截图可以看到
0x404090 是min的地址
0x4040a0 是max的地址
printf("%f %f %f\n", foo(arr, sizeof arr/sizeof *arr), max, min);
这里的入栈顺序是从右向左的
但函数foo会在函数入栈之前调用
而在你的编译器中 入栈顺序是从右向左的
但函数调用会在 min max入栈之后
这就是我为什么说输出什么无法确定
函数调用有可能发生在min max入栈之前
也有可能发生在min max入栈之后
另一个问题
本来就可以直接定义
书里面没说吗? 求道于盲 发表于 2017-6-30 17:37
可以看到汇编里面是 先调用了 foo
然后
0x404090 入栈
再次感谢!由于C刚入门,还没有学习过汇编,所以理解得不透彻!
关于第二个问题,书上是重点强调过调用函数前一定要先申明,但通过百度+自己验证了解到:函数调用出现在函数定义之后,可以不加申明
页:
[1]