博主:鸿渐之翼 个人介绍:一个搞底层的FW,喜欢发一点没用的东西。 
存储类:
作用域: 作用域描述程序中可以访问的一个标识符或多个区域。我们使用的局部变量,包括函数的形式变量,都是代码块作用域。
double A(double b)
{
double j=1;
int i;
for(i=0;i<10;i++)
double k =j+i;
...
j *=k;
}
return j;
函数原型作用域(function prototype scope) 适用于函数原型中使用的变量名称:
int A(int a, double b);
链接: c语言中变量具有以下链接: 外部链接(external linkage),内部链接(internal linkage) 空链接(no linkage)
存储时期: c变量中两种存储时期: 静态存储时期(static storage duration) 自动存储时期(automantic storage duration)
自动变量: 默认情况下,在代码块或函数的头部定义的任意变量都属于自动存储类。
寄存器变量: 寄存器变量可以被存储在CPU寄存器中。 
因为寄存器变量多放在一个寄存器而非内存中,所以无法获得寄存器变量的地址。 以下声明寄存器变量:
int main(void)
{
register int quick;
}
 具有代码块作用域的静态变量 静态变量(static variable)“静态”指的是位置固定不动。 从函数条用到下一次调用,它们并不会消失。 具有外部链接的静态变量 包含了 1.文件作用域2.外部链接3.静态存储时期。 这一类型被称为external storage class
int out;
double a[10];
extern char a;
int main(void){
extern int out;
extern double a[];
}
out的两次申明是链接的例子。它们都指向同一个变量,外部变量具有外部链接。 具有内部链接的静态变量
static int a=1;
int main(void)
{
int a=1;
statci int b=2;
}

存储类总结
自动变量具有代码块作用域、空链接和自动存储时期,一般是一个函数私有。 寄存器变量和自动变量具有相同的属性,编译器能使用更快的内存或存储器来存储它们,但无法获取一个寄存器变量的地址。 具有静态存储时期的变量可能具有外部链接、内部链接或空链接。 当程序执行到包含变量声明的代码块时,给具有自动存储时期的变量分配内存,并在代码块结束时释放这部分内存。如果没有没有初始化,这样的变量具有一个无效值。具有代码块作用的变量局部包含变量声明的代码块。 example:
#include<stdio.h>
void report_count();
void accumulate(int a);
int count=0;
int main(void){
int value;
register int i;
extern int count;
static int total = 0;
void accumulate(int k)
printf("Enter a positive interger:");
while(scanf("%d",&value)==1 && value>0)
{
++count;
for(i==value;i>=0;i--)
accumulate(i);
printf("Enter a positive integer;");
}
report_count();
return 0;
}
void report_count()
{
printf("Loop executed %d times\n",count);
}
void accumulate(int k)
{
static int subtotal =o;
if (k<=0)
{
printf("loop cycle: %d\n",count);
printf("subtotal:%d total:%d\n",subtotal,total);
subtotal=0;
}
else
{
subtotal +=k;
total +=k;
};
}
int count=0;//文件作用域,外部链接 int value;//自动变量 register int i;//寄存器变量 ++count;//使用文件作用域变量 extern int count; //引用声明,外部链接 static int total = 0; //静态定义,内部链接 void accumulate(int k) //函数原型
存储类与函数
double a();
static double b();
extern double c();
double a()默认为外部,函数a()与函数c()可以被程序其他文件中的函数使用,b()不能,因为b被限定在一个文件中。 static存储类就是创建一个特定的模版私有的函数。从而避免可能的名字冲突。

分配内存 malloc()与free()
除了常规的分配内存方式
float a;
char a[] = "aaaaa";
int a[100];
c语言中还有函数malloc(),malloc()分配了内存,但是没有为它制定名字。然而,malloc可以返回内存第一个字节的地址。
double * a;
a = (double *)malloc(20 *sizeof(double));
这段代码请求20个double类型的空间,并且把a指向该空间所在位置。a是作为一个double类型值的指针声明,而不是指向20个double类型值的数据块指针。 例如程序
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char const *argv[])
{
double *pointer;
int max;
int number;
int i=0;
puts("what is maximum number of type double entries?");
scanf("%d",&max);
pointer =(double *)malloc(max *sizeof(double));
if(pointer == NULL)
{
puts("Memory allocation failed.Goodby.");
exit(EXIT_FAILURE);
}
puts(" Enter teh values:");
while(i < max && scanf("%lf",&pointer[i])==1);
++i;
printf("Here are you %d entries:\n",number=i);
for(i = 0; i < number;i++)
{
printf("%7.2f",pointer[i]);
if(i % 7 == 6)
putchar('\n');
}
if(i % 7 !=0)
putchar('\n');
puts("done.");
free(pointer);
return 0;
}
分配对应存放所请求数目足够大的内存空间,并把该内存的地址赋给指针pointer
pointer =(double*)malloc(max *sizeof(double));
malloc()可能无法获得所需数量的内存,在这种情况下,函数返回空指针,程序终止;
if(pointer ==NULL)
{
puts("Memory allocation failed.Goodbye.");
exit(EXIT_FAILURE);
}
如果成功分配内存,程序把pointer当作max个的数组名字 最后使用free()释放内存。
free()的重要性importance of Free()! example:
int main()
{
double a[2000];
int i
}
for (i=0; i<=1000;i++)
gobble(a,2000);
void gobble(double argv[],int n)
{
double * p =(double *)malloc(n *sizeof(double));
}
第一次调用gobble(),它创建了指针p,斌使用了maclloc()分配16000字节内存(设double是8字节)。 当函数终止时,指针p作为一个自动变量消失。但它指向的16000个字节内存依然存在,我们无法访问这些内存,因为地址没了。由于没有调用free(),不可以再使用它了。 第二次调用gobble(),它创建了一个p,再次使用malloc()分配的16000个字节内存。第一次的内存不能使用,因此malloc()不得不再找一个16000字节的块。 当程序完成循环1000次,已经有1600万字节的内存从内存池中移走了。程序已经出现了内存溢出。我们称为memory leak。

本篇完

|