//static在代码块中具有“累加”的功能,只需初始化一次,普通变量(缺省为自动变量)在函数中为初始化状
//态,即每次都重新初识化。即程序退出时,所占用的内存才会发生变化。
//对于静态的局部变量,编译器对其端的分配与全局变量一样的,解释:因为全局变量我们需要保
//存其值,当下次进入函数体,其值仍然维持在最后一次改变,而如果是放在栈上这是做不到的,
//因为函数所占用的栈空间,当函数返回后就不再属于这个函数了。
#include <iostream>
#include <string>
int sum( int a )
{
auto int c = 0;
static int b = 2;
c += 1;
b += 3;
return ( a + b + c );
//auto的含义是有程序自动控制变量的生存周期,通常指的就是变量进入其作用域的时候被分配,离开其作
//用域时候被释放;static变量在程序初始化时被分配,知道程序退出前才被释放。
}
int main( int argc, char ** argv )
{
int a = 2;
for( int i=0; i < 5; i++ )
std::cout<< sum(a) << ","<<std::endl;
return 0;
}
//输出结果为8,11,14,17,20
auto的作用域为代码块作用域,代码块的作用域为位于一对花括号之间的所有语句称为一个代码块,
任何在代码块的开始位置声明的标识符都具有代码块作用域。
在代码块内部声明的变量的缺省存储类型是自动的,也就说它存储于堆栈指针中,称为自动变量。有一
个关键字auto就是修饰这种类型的,但它极少使用。因为代码块中的变量在缺省的情况下就是自动变量。
在程序执行到声明自动变量的代码块时,自动变量才被创建,当程序的执行流离开该代码块时,这些自动变
量便自行销毁。如果该代码块被数此执行,例如一个函数被反复调用,这些自动变量每次都被重新创建。
所以当代码块再次执行时,他们的值一般不是上次执行时的值。
对于在代码块内部声明的变量,如果给它加上关键字static,可以使它的存储类型从自动变量变为静态。
具有静态存储类型的变量在整个执行过程中一直存在,而不仅仅在它声明的代码块执行时存在。注意,修改
变量的存储类型并不是修改该变量的作用域,它仍然只能在该代码块内部按名字访问。函数的形式参数不能
声明为静态,因为实参总是在堆栈中传递给函数,用于支持递归。寄存器变量关键字register用于自动变量的
声明,提示他们它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。通常寄存器变
量比存储变量访问起来效率更高。但如果太多的变量被声明为register。它只取前几个实际存储于寄存器中,
其余按普通变量自动处理。
不管是非全局、全局的的静态的变量,或者是全局的非静态变量,如果初始化好了,就分配在.data段,如果未初始化好,
则分配在.bss段,而函数一律分配在.text段,即只读的。
而非全局的即局部的非静态变量则分配在栈上或者堆上。
命令 nm -n main.o 查看数据的存放段位置
U ___main
U _time
00000000 b .bss
00000000 d .data
00000000 N .debug_abbrev
00000000 N .debug_aranges
00000000 N .debug_frame
00000000 N .debug_info
00000000 N .debug_line
00000000 N .debug_loc
00000000 N .debug_pubnames
00000000 t .text
00000000 D _at_global2
00000000 t _foo
00000000 b _st_global1
00000004 d _st_global2
00000004 b _st_internal1.1311
00000008 d _st_internal2.1312
00000010 C _at_global1
00000014 t _bar
00000019 T _main
对于const变量分配到.rdata上,只读的,有可能被合并到.text段上。
关于字节对齐,一般是根据长度最大的那个数据类型来分配字节对齐。
比如 const char hello[] = "hello world!" 本来应该是加上‘\0’,总共13个字节,后来因为字节对齐的原因,
则分配了16个字节。