C/C++ 中堆和栈及静态数据区详解分享

     上面的程序中变量num和函数add()在声明是采用了static存储类型修饰符,这使得它们具有文件作用域,仅爱定义它们的文件内可见。

     由于我们提到的大多数程序都只有一个编译文件组成,所以这种写法没有实际意义。但是实际工程上的文件有很多,它们不是由一个人写成的,由很多人共同完成, 这些文件都是各自编译的,这难免使得某些人使用了一样的全局变量名,那么为了以后程序中各自的变量和函数不互相干扰,就可以使用static修饰符,这样 在连接到同一个程序的其他代码文件而言就是不可见的。

  二、变量存储类型

  前面我们说了,声明变量时用如下类似的形式:

int num;
float total; 

   它们都没有存储类型修饰符,我们在声明时也可以通过存储类型修饰符来告诉编译器将要处理什么类型的变量。存储类型有以下四种:自动(auto)、静态(static)、外部(extern)、寄存器(regiser)。

      1.自动存储类型

  自动存储类型修饰符指定了一个局部变量为自动的,这意味着,每次执行到定义该变量的语句块时,都将会为该变量在内存中产生一个新的拷贝,并对其进行初始化。实际上,如果不特别指明,局部变量的存储类型就默认为自动的,因此,加不加auto都可以。

  main()   {     auto int num=5;     printf("%dn",num);   }  

  在这个例子中,不论变量num的声明是否包含关键字auto,代码的执行效果都是一样的。函数的形式参数存储类型默认也是自动的。        

      2.静态存储变量

  前面已经使用了static关键字,但是对于局部变量,静态存储类型的意义是不一样的,这时,它是和自动存储类型相对而言的。静态局部变量的作用域仍然近 局限于声明它的语句块中,但是在语句块执行期间,变量将始终保持它的值。而且,初始化值只在语句块第一次执行是起作用。在随后的运行过程中,变量将保持语 句块上一次执行时的值。

  看下面两个对应的程序:

      /*1.C*/        /*2.C*/     int add();        int add();       main()         main()     {          {      int result;       int result;      result=add()       result=add();      printf("%d ",result);     printf("%d ",result);      result=add();       result=add();      printf("%d ",result);     printf("%d ",result);      result=add();       result=add();      printf("%d",result);     printf("%d",result);     }          }       int add()        int add()     {          {      int num=50;       static int num=50;      num++;         num++;      return num;       return num;     }          }    

 

  上面两个源文件,只有函数add()里的变量声明有所不同,一个是自动存储类型,一个是静态存储类型。

  对于1.C文件,输出结果为51 51 51;这很好理解,每次初始值都是50,然后加1上来。

  对于2.C文件,输出结果为51 52 53;这是由于变量是静态的,只在第一次初始化了50,以后都是使用上次的结果值。当第一次调用add()时,初始化为50,然后加1,输出为51;当第 二次调用时,就不初始化了,这时num的值为上次的51,然后加1,输出52;当第三次调用时,num为52,加1就是53了。

  比较就会发现它们的不同之处了。静态变量在下一节要说的递归函数中经常使用到。

  当第一次不指明静态变量的初始值时,默认为0。

  下面举一个例子,把我们说到的静态变量理解一下。

  求1+2+……+100的值的代码如下:

        void add();     int result;       main()     {      int i;      result=0;      for(i=0;i<100;i++) add();      printf("%dn",result);     }       void add()     {      static int num=0;      num++;      result+=num;     }    

 

   add()函数被调用了100次,num的值从1一直变到100,这样就可以求出它们的和了。如果写成int num=0;那就是求1+1+……+1这100个1的值了。

   实际上类似的这类问题我们可以通过递归函数来解决,什么是递归,我们下一节介绍。

      3.外部存储类型

  外部存储类型声明了程序将要用到的、但尚未定义的外部变量。通常,外部存储类型都是用于声明在另一个转换单元中定义的变量。下面举一个例子,这个例子包括两个文件。

       /*1.C*/      void a();        main()      {       extern int num;       a();       printf("%dn",num);      }        /*2.C*/      int num;        void a()      {       num=5;      }    

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/488041.html

(0)
上一篇 2020年11月12日
下一篇 2020年11月12日

精彩推荐