自动变量的初始化?

时间:2021-07-14 19:45:55
自动变量:x;
j静态自动变量:x;
它们的初始化,有什么不同?
如:
int  main()
 {
   int  x=1;
   while (x<3)
     {
       static  int  x;
       ++x;
       printf("%.d",x); 
     }
 }
-----------------
自动变量初始化:x=1。
静态自动变量:static int x,程序执行到这句语句时,它是不是保存了1的值?

25 个解决方案

#1



00411380  push        ebp  
00411381  mov         ebp,esp  
00411383  sub         esp,0CCh  
00411389  push        ebx  
0041138A  push        esi  
0041138B  push        edi  
0041138C  lea         edi,[ebp-0CCh]  
00411392  mov         ecx,33h  
00411397  mov         eax,0CCCCCCCCh  
0041139C  rep stos    dword ptr es:[edi]  
  int x=1;
0041139E  mov         dword ptr [x],1  
  while (x<3)
004113A5  cmp         dword ptr [x],3  
004113A9  jge         main+57h (4113D7h)  
  {
  static int x;
  ++x;
004113AB  mov         eax,dword ptr [x (417138h)]  
004113B0  add         eax,1  
004113B3  mov         dword ptr [x (417138h)],eax  
  printf("%.d",x);  
004113B8  mov         esi,esp  
004113BA  mov         eax,dword ptr [x (417138h)]  
004113BF  push        eax  
004113C0  push        offset string "%.d" (41573Ch)  
004113C5  call        dword ptr [__imp__printf (4182B0h)]  
004113CB  add         esp,8  
004113CE  cmp         esi,esp  
004113D0  call        @ILT+295(__RTC_CheckEsp) (41112Ch)  
  }
004113D5  jmp         main+25h (4113A5h)  
  return 0;
004113D7  xor         eax,eax  
 }

#2


两码事了
 while (x<3)这里的x是int x=1;

所以永远为真,就是死循环!
static int x;这里是静态变量,默认初始化为0

所以x++后会一直递增

#3



int x = 1;


while (x < 3) /* 这个x是外面的x,进入死循环 */
{
    /* 进入新的作用域,这里有一个x,则外面的x被屏蔽,在这个作用域这个x说了算 */
    static int x; /* static变量自动初始化为其默认值,这里是0,并且只在第一次进入作用域时初始化 */
    ++x;
    printf("%d ", x);
}

#4



#include <stdio.h>

int main(int argc, char **argv)
{
int test = 1;
/* 普通的自动变量 */
int x = 1;

/* 进入循环 */
printf("第一次进入循环x = ");
TEST:
while (x < 3)
{
static int x;
printf("%d ", x);
if (x >= 10)
break;
++x;
}

/* 我们回去看看现在x等于多少 */
if (test)
{
test = 0;
printf("\n第二次进入循环x = ");
goto TEST;
}
return 0;
}

/* 
程序输出:
第一次进入循环x = 0 1 2 3 4 5 6 7 8 9 10
第二次进入循环x = 10 请按任意键继续. . .
*/

#5


你的static定义了一个静态局部变量,可以沿用全局变量的值,但程序结束后,局部变量不能被引用!
你编写的程序其中while循环中的X是引用的全局变量,在我看来程序应该是个死循环!

#6


纠结,忘了说俩个x是毫无关系的,是不可以沿用的,上面是我打错了!不好意思啊,希望没人因为我而误导了啊

#7


自动变量系统不会给它初始化,因此如果不显式初始化它,它的值将是不确定的。
static int类型的变量,系统会默认的初始化为0。static变量只会初始化一次。


int main()
{
int x=1;
while (x<3)                     // 2. 但这里的x,判断的是自动变量x,而不是下面的静态变量x
{                                     //     所以会死循环。
static int x;
++x;                      // 1. 这里的静态变量x会每循环一次加1
printf("%.d",x); 
}
}

#8


int x=3;
//变量:x,全局局变量!它的初值是:3。
int  main ()
{  
  int x=1;
//变量:x,是局部变量!它的初值是:1。
  while (x<3)
    { 
      static int x;
//变量:x,是静态局部变量!它的初值是什么?是3么?与全局变量有关么?
      ++x;
      printf("%.d",x);
      if  (x>=10)
         break;
    }
}

#9


变量一共分:
全局变量
静态全局变量
静态局部变量
局部变量

对否?
如果不初始化,它们的初值是什么?

#10


引用 9 楼 aaimmi 的回复:
变量一共分:
全局变量
静态全局变量
静态局部变量
局部变量

对否?
如果不初始化,它们的初值是什么?

如果变量时int类型的,那么全局变量、静态全局变量、静态局部变量,都会被系统初始化为0,
局部变量如果不初始化,其值时不确定的。

测试代码如下:

#include <iostream>
#include <string>
using namespace std;

int a;
static int b;

int main()
{
static int c;
int d;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;

return 0;
}


对于其它类型的变量,楼主自己去做个类似的实验就知道了。

#11


静态变量是,系统为她分配固定一块内存,直到程序结束。
而局部变量,而只是在某个局部有用,过了局部,这片空间就被系统回收了。
所以静态变量是为了共享数据。因为内存那片空间固定,大家都可以访问。

#12


引用 2 楼 babilife 的回复:
两码事了
 while (x<3)这里的x是int x=1;

所以永远为真,就是死循环!
static int x;这里是静态变量,默认初始化为0

所以x++后会一直递增

++

#13


11楼:
你的头像真帅!
肯定没看过电影:小男人啦!

#14


楼主,实际上就是作用域的问题。

#15


静态变量 在所在函数结束后,其值依然保存,在下一次进入该函数时,保存上次这个函数中处理后的值。 而普通的局部变量在函数结束后销毁。

#16


如果程序:++x,改为:x++。
程序也是打印1-10。
如果静态局部变量,其初值是:0。应该是打印:0-10啊?

#17


static int x初始化为0 并只初始化1次

#18


学习了。。、

#19


改为:x++,打印的结果是:1-10!为什么?
++x,x++,有区别么?

#20


x++,先取x值 再x=x+1
++x, 先x=x+1, 再取x值 (此时为新值)

#21


搞清楚存储期(storage duration)和作用域(scope)的区别。
自动和静态就是矛盾的。一个变量是自动变量,就不可能是静态变量。
至于全局变量,严格来说是C++等其它语言的说法,C语言中并不存在,等价的是file scope variable,只不过在链接时的行为和C++的全局对象(global namespace object)有很多相同之处(例如都可以在整个程序中可见,都不可能是自动变量),所以习惯上也叫“全局”的。
引起LZ误解的可能是static这个关键字在C语言中的不同意义。block scope中,static修饰的对象具有静态存储期,且它的名称无链接;在file scope中,无论是否static修饰,对象都具有静态存储期,而static限制实体(包括变量和函数等)的名称具有内部链接(即仅在当前翻译单元可见)。(顺便,C++03即置namespace scope的static为deprecated,以unnamed namespace代替;C++0x中则进一步废除了这个特性,static根本没有限制链接的功能)。
在block scope中,如果变量的声明没有被存储期关键字修饰,或者被auto修饰,那么变量就是自动变量,具有自动存储期,在block结束处变量的生存期结束。除此之外,存储期和作用域并没有显著的联系。
对于静态存储期的对象,语言的实现会保证在用户使用它前被初始化一次。file scope的“全局”变量会在整个程序初始化(main之前)时被初始化,函数内static变量会在第一次进入函数时初始化。如果用户没有显式初始化,则静态存储期对象会隐式初始化,其中指针类型的值初始化为空指针(注意某些平台空指针的实际存储并不一定为0,所以单独列出),其它基本类型为0,结构体或数组中每个元素按上面递归初始化。自动存储期的对象不进行隐式初始化,具有indeterminate value,为trap representation,使用未初始化的自动存储期对象的值引起undefined behavior。


#22


引用 2 楼 babilife 的回复:
两码事了
 while (x<3)这里的x是int x=1;

所以永远为真,就是死循环!
static int x;这里是静态变量,默认初始化为0

所以x++后会一直递增


++

#23


无汇编,无真相!

#24


引用楼主 aaimmi 的回复:
自动变量:x;
j静态自动变量:x;
它们的初始化,有什么不同?
如:
int  main()
 {
   int  x=1;
   while (x<3)
     {
       static  int  x;
       ++x;
       printf("%.d",x); 
     }
 }
-----------------
自动变量初始化:x=1……


lz你自己编译成asm看看,
以我本机的编译结果为例:
x=1编译之后把x编译为符号_x$,然后给它设值1;
static  int  x编译之后是_?x@?3??main@@9@4HA,
在while block内部x其实是指
?x@?3??main@@9@4HA
所以++x 其实更改的是?x@?3??main@@9@4HA,
你这是死循环

#25


学习了

#1



00411380  push        ebp  
00411381  mov         ebp,esp  
00411383  sub         esp,0CCh  
00411389  push        ebx  
0041138A  push        esi  
0041138B  push        edi  
0041138C  lea         edi,[ebp-0CCh]  
00411392  mov         ecx,33h  
00411397  mov         eax,0CCCCCCCCh  
0041139C  rep stos    dword ptr es:[edi]  
  int x=1;
0041139E  mov         dword ptr [x],1  
  while (x<3)
004113A5  cmp         dword ptr [x],3  
004113A9  jge         main+57h (4113D7h)  
  {
  static int x;
  ++x;
004113AB  mov         eax,dword ptr [x (417138h)]  
004113B0  add         eax,1  
004113B3  mov         dword ptr [x (417138h)],eax  
  printf("%.d",x);  
004113B8  mov         esi,esp  
004113BA  mov         eax,dword ptr [x (417138h)]  
004113BF  push        eax  
004113C0  push        offset string "%.d" (41573Ch)  
004113C5  call        dword ptr [__imp__printf (4182B0h)]  
004113CB  add         esp,8  
004113CE  cmp         esi,esp  
004113D0  call        @ILT+295(__RTC_CheckEsp) (41112Ch)  
  }
004113D5  jmp         main+25h (4113A5h)  
  return 0;
004113D7  xor         eax,eax  
 }

#2


两码事了
 while (x<3)这里的x是int x=1;

所以永远为真,就是死循环!
static int x;这里是静态变量,默认初始化为0

所以x++后会一直递增

#3



int x = 1;


while (x < 3) /* 这个x是外面的x,进入死循环 */
{
    /* 进入新的作用域,这里有一个x,则外面的x被屏蔽,在这个作用域这个x说了算 */
    static int x; /* static变量自动初始化为其默认值,这里是0,并且只在第一次进入作用域时初始化 */
    ++x;
    printf("%d ", x);
}

#4



#include <stdio.h>

int main(int argc, char **argv)
{
int test = 1;
/* 普通的自动变量 */
int x = 1;

/* 进入循环 */
printf("第一次进入循环x = ");
TEST:
while (x < 3)
{
static int x;
printf("%d ", x);
if (x >= 10)
break;
++x;
}

/* 我们回去看看现在x等于多少 */
if (test)
{
test = 0;
printf("\n第二次进入循环x = ");
goto TEST;
}
return 0;
}

/* 
程序输出:
第一次进入循环x = 0 1 2 3 4 5 6 7 8 9 10
第二次进入循环x = 10 请按任意键继续. . .
*/

#5


你的static定义了一个静态局部变量,可以沿用全局变量的值,但程序结束后,局部变量不能被引用!
你编写的程序其中while循环中的X是引用的全局变量,在我看来程序应该是个死循环!

#6


纠结,忘了说俩个x是毫无关系的,是不可以沿用的,上面是我打错了!不好意思啊,希望没人因为我而误导了啊

#7


自动变量系统不会给它初始化,因此如果不显式初始化它,它的值将是不确定的。
static int类型的变量,系统会默认的初始化为0。static变量只会初始化一次。


int main()
{
int x=1;
while (x<3)                     // 2. 但这里的x,判断的是自动变量x,而不是下面的静态变量x
{                                     //     所以会死循环。
static int x;
++x;                      // 1. 这里的静态变量x会每循环一次加1
printf("%.d",x); 
}
}

#8


int x=3;
//变量:x,全局局变量!它的初值是:3。
int  main ()
{  
  int x=1;
//变量:x,是局部变量!它的初值是:1。
  while (x<3)
    { 
      static int x;
//变量:x,是静态局部变量!它的初值是什么?是3么?与全局变量有关么?
      ++x;
      printf("%.d",x);
      if  (x>=10)
         break;
    }
}

#9


变量一共分:
全局变量
静态全局变量
静态局部变量
局部变量

对否?
如果不初始化,它们的初值是什么?

#10


引用 9 楼 aaimmi 的回复:
变量一共分:
全局变量
静态全局变量
静态局部变量
局部变量

对否?
如果不初始化,它们的初值是什么?

如果变量时int类型的,那么全局变量、静态全局变量、静态局部变量,都会被系统初始化为0,
局部变量如果不初始化,其值时不确定的。

测试代码如下:

#include <iostream>
#include <string>
using namespace std;

int a;
static int b;

int main()
{
static int c;
int d;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;

return 0;
}


对于其它类型的变量,楼主自己去做个类似的实验就知道了。

#11


静态变量是,系统为她分配固定一块内存,直到程序结束。
而局部变量,而只是在某个局部有用,过了局部,这片空间就被系统回收了。
所以静态变量是为了共享数据。因为内存那片空间固定,大家都可以访问。

#12


引用 2 楼 babilife 的回复:
两码事了
 while (x<3)这里的x是int x=1;

所以永远为真,就是死循环!
static int x;这里是静态变量,默认初始化为0

所以x++后会一直递增

++

#13


11楼:
你的头像真帅!
肯定没看过电影:小男人啦!

#14


楼主,实际上就是作用域的问题。

#15


静态变量 在所在函数结束后,其值依然保存,在下一次进入该函数时,保存上次这个函数中处理后的值。 而普通的局部变量在函数结束后销毁。

#16


如果程序:++x,改为:x++。
程序也是打印1-10。
如果静态局部变量,其初值是:0。应该是打印:0-10啊?

#17


static int x初始化为0 并只初始化1次

#18


学习了。。、

#19


改为:x++,打印的结果是:1-10!为什么?
++x,x++,有区别么?

#20


x++,先取x值 再x=x+1
++x, 先x=x+1, 再取x值 (此时为新值)

#21


搞清楚存储期(storage duration)和作用域(scope)的区别。
自动和静态就是矛盾的。一个变量是自动变量,就不可能是静态变量。
至于全局变量,严格来说是C++等其它语言的说法,C语言中并不存在,等价的是file scope variable,只不过在链接时的行为和C++的全局对象(global namespace object)有很多相同之处(例如都可以在整个程序中可见,都不可能是自动变量),所以习惯上也叫“全局”的。
引起LZ误解的可能是static这个关键字在C语言中的不同意义。block scope中,static修饰的对象具有静态存储期,且它的名称无链接;在file scope中,无论是否static修饰,对象都具有静态存储期,而static限制实体(包括变量和函数等)的名称具有内部链接(即仅在当前翻译单元可见)。(顺便,C++03即置namespace scope的static为deprecated,以unnamed namespace代替;C++0x中则进一步废除了这个特性,static根本没有限制链接的功能)。
在block scope中,如果变量的声明没有被存储期关键字修饰,或者被auto修饰,那么变量就是自动变量,具有自动存储期,在block结束处变量的生存期结束。除此之外,存储期和作用域并没有显著的联系。
对于静态存储期的对象,语言的实现会保证在用户使用它前被初始化一次。file scope的“全局”变量会在整个程序初始化(main之前)时被初始化,函数内static变量会在第一次进入函数时初始化。如果用户没有显式初始化,则静态存储期对象会隐式初始化,其中指针类型的值初始化为空指针(注意某些平台空指针的实际存储并不一定为0,所以单独列出),其它基本类型为0,结构体或数组中每个元素按上面递归初始化。自动存储期的对象不进行隐式初始化,具有indeterminate value,为trap representation,使用未初始化的自动存储期对象的值引起undefined behavior。


#22


引用 2 楼 babilife 的回复:
两码事了
 while (x<3)这里的x是int x=1;

所以永远为真,就是死循环!
static int x;这里是静态变量,默认初始化为0

所以x++后会一直递增


++

#23


无汇编,无真相!

#24


引用楼主 aaimmi 的回复:
自动变量:x;
j静态自动变量:x;
它们的初始化,有什么不同?
如:
int  main()
 {
   int  x=1;
   while (x<3)
     {
       static  int  x;
       ++x;
       printf("%.d",x); 
     }
 }
-----------------
自动变量初始化:x=1……


lz你自己编译成asm看看,
以我本机的编译结果为例:
x=1编译之后把x编译为符号_x$,然后给它设值1;
static  int  x编译之后是_?x@?3??main@@9@4HA,
在while block内部x其实是指
?x@?3??main@@9@4HA
所以++x 其实更改的是?x@?3??main@@9@4HA,
你这是死循环

#25


学习了