C语言存储类
C中的存储类用于确定变量的生存期,可见性,内存位置和初始值。 C中有四种类型的存储类
auto
extern
static
register
存储类型 |
堆栈 |
默认值 |
范围 |
生命周期 |
auto |
RAM |
垃圾值 |
Local |
函数内 |
extern |
RAM |
Zero |
Global |
直到主程序结束可能在程序中的任何地方声明了 |
static |
RAM |
Zero |
Local |
直到主程序结束,在多个函数调用之间保留值 |
register |
Register |
垃圾值 |
Local |
函数内 |
auto
auto变量在运行时auto分配内存。
auto变量的可见性仅限于定义它们的块。
auto变量的范围限于定义它们的块。
默认情况下,auto变量会初始化为垃圾内容。
分配给auto变量的内存在从块中退出时会释放。
用于定义auto变量的关键字是auto。
默认情况下,每个局部变量在C中都是auto的。 示例1
#include <stdio.h>
int main()
{
int a; //auto
char b;
float c;
printf("%d %c %f",a,b,c); // printing initial default value of automatic variables a, b, and c.
return 0;
}
输出:
示例2
#include <stdio.h>
int main()
{
int a = 10,i;
printf("%d ",++a);
{
int a = 20;
for (i=0;i<3;i++)
{
printf("%d ",a); // 20 will be printed 3 times since it is the local value of a
}
}
printf("%d ",a); // 11 will be printed since the scope of a = 20 is ended.
}
输出:
static
定义为static说明符的变量可以在多个函数调用之间保留其值。
static局部变量仅对定义它们的功能或块可见。
同一static变量可以声明多次,但只能一次分配。
static整数变量的默认初始值为0,否则为null。
static全局变量的可见性仅限于声明它的文件。
用于定义static变量的关键字是static。
示例1
#include<stdio.h>
static char c;
static int i;
static float f;
static char s[100];
void main ()
{
printf("%d %d %f %s",c,i,f); // the initial default value of c, i, and f will be printed.
}
输出:
示例2
#include<stdio.h>
void sum()
{
static int a = 10;
static int b = 24;
printf("%d %d \n",a,b);
a++;
b++;
}
void main()
{
int i;
for(i = 0; i< 3; i++)
{
sum(); // The static variables holds their value between multiple function calls.
}
}
输出:
register
定义为寄存器的变量将根据CPU中剩余的内存大小分配给CPU寄存器。
我们不能取消引用寄存器变量,即不能使用&operator作为寄存器变量。
寄存器变量的访问时间比auto变量快。
寄存器局部变量的初始默认值为0。
register关键字用于应存储在CPU寄存器中的变量。但是,是否由编译器选择?变量可以存储在寄存器中。
我们可以将指针存储到寄存器中,即寄存器可以存储变量的地址。
static变量不能存储到寄存器中,因为我们不能对同一变量使用多个存储说明符。
示例1
#include <stdio.h>
int main()
{
register int a; // variable a is allocated memory in the CPU register. The initial default value of a is 0.
printf("%d",a);
}
输出:
示例2
#include <stdio.h>
int main()
{
register int a = 0;
printf("%u",&a); // this will give a compile time error since we can not access the address of a register variable.
}
输出:
main.c:5:5: error: address of register variable ?a? requested
printf("%u",&a);
^~~~~~
extern
extern存储类用于告诉编译器,定义为extern的变量是通过程序中其他位置的extern链接声明的。
声明为extern的变量未分配任何内存。它只是声明,旨在指定在程序的其他位置声明该变量。
extern整数类型的默认初始值为0,否则为null。
我们只能全局初始化extern变量,即我们不能在任何块或方法中初始化extern变量。
extern变量可以声明多次,但只能一次初始化。
如果将变量声明为extern变量,则编译器将在程序的某个位置(可能是extern或static)搜索要初始化的变量。如果不是,则编译器将显示错误。
示例1
#include <stdio.h>
int main()
{
extern int a;
printf("%d",a);
}
输出
main.c:(.text+0x6): undefined reference to `a'
collect2: error: ld returned 1 exit status
示例2
#include <stdio.h>
int a;
int main()
{
extern int a; // variable a is defined globally, the memory will not be allocated to a
printf("%d",a);
}
输出
示例3
#include <stdio.h>
int a;
int main()
{
extern int a = 0; // this will show a compiler error since we can not use extern and initializer at same time
printf("%d",a);
}
输出
compile time error
main.c: In function ?main?:
main.c:5:16: error: ?a? has both ?extern? and initializer
extern int a = 0;
示例4
#include <stdio.h>
int main()
{
extern int a; // Compiler will search here for a variable a defined and initialized somewhere in the pogram or not.
printf("%d",a);
}
int a = 20;
输出
示例5
extern int a;
int a = 10;
#include <stdio.h>
int main()
{
printf("%d",a);
}
int a = 20; // compiler will show an error at this line
输出