一、生存期
C语言的变量有两种生存期
1、静态存储期
具有文件作用域的变量属于静态存储期,函数也属于静态存储期。属于静态存储期的变量在程序执行期间将一直占据存储空间,直到程序关闭才释放。
2、自动存储期
具有代码块作用域的变量一般情况下属于自动存储期。属于自动存储期的变量在代码块结束时将自动释放存储空间。
二、存储类型
存储类型其实是指存储变量值的内存类型,C语言中提供了5种不同的存储类型:
1、auto
2、register
#include<stdio.h>
int main()
{
register int i=520;
printf("addr of i:%p\n",&i);
return 0;
}
运行结果:
lhy@ubuntu:~/xiaojiayu$ gcc p33-1.c
p33-1.c: In function ‘main’:
p33-1.c:5:2: error: address of register variable ‘i’ requested
printf("addr of i:%p\n",&i);
^~~~~~
3、static
#include<stdio.h>
void func()
{
static int count=1;
printf("count = %d\n",count);
count++;
}
int main()
{
int i;
for(i=0;i<5;i++)
{
func();
}
return 0;
}
运行结果:
lhy@ubuntu:~/xiaojiayu$ gcc p33-2.c
lhy@ubuntu:~/xiaojiayu$ ./a.out
count = 1
count = 2
count = 3
count = 4
count = 5
假如我们去掉static会怎么样呢?
#include<stdio.h>
void func()
{
int count=1;
printf("count = %d\n",count);
count++;
}
int main()
{
int i;
for(i=0;i<5;i++)
{
func();
}
return 0;
}
运行结果:
lhy@ubuntu:~/xiaojiayu$ gcc p33-2.c
lhy@ubuntu:~/xiaojiayu$ ./a.out
count = 1
count = 1
count = 1
count = 1
count = 1
static改变的只是count的生存期(时间),而非起作用的位置(空间)如:
#include<stdio.h>
void func()
{
int count=1;
printf("count = %d\n",count);
count++;
}
int main()
{
int i;
printf("count=%d\n",count);
for(i=0;i<5;i++)
{
func();
}
return 0;
}
运行结果:
lhy@ubuntu:~/xiaojiayu$ gcc p33-2.c
p33-2.c: In function ‘main’:
p33-2.c:11:22: error: ‘count’ undeclared (first use in this function)
printf("count=%d\n",count);
^~~~~
p33-2.c:11:22: note: each undeclared identifier is reported only once for each function it appears in
4、extern
5、typedef
关于typedef的理解
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
-----------------------------------------------------------------------------
- 此处由于加了typedef自定义了一个新类型sighandler_t,所以第二行的函数原型看起来顺眼多了,形式跟int func(char c, int i)无异,但是如果看不懂typedef语句,这两句话仍然是噩梦。
- 要理解typedef,只要记住一句话就差不多了,那就是:typedef在语句中所起的作用只不过是把语句原先定义变量的功能变成了定义类型的功能而已。我们只消看几个例子立即明白。
- 例如语句 typedef int *apple; 理解它的正确步骤是这样的:先别看typedef,就剩下int *apple; 这个语句再简单不过,就是声明了一个指向整型变量的指针apple (注意:定义只是一种特殊的声明),加上typedef之后就解释成声明了一种指向整型变量指针的类型apple 。
- 现在,回过来看上面的这个函数原型 typedef void (*sighandler_t)(int),盖住 typedef不看 ,再简单不过,sighandler_t就是一个函数指针,指向的函数接受一个整型参数并返回一个无类型指针 。加上typedef之后sighandler_t就是一种新的类型,就可以像int一样地去用它,不同的是它声明是一种函数指针,这种指针指向的函数接受一个整型参数并返回一个无类型指针 。怎么样?简单吧。
- 再来做一个更酷的练习,请看:typedef char *(* c[10])(int **p);
- 去 掉typedef就变成char *(* c[10])(int **p),先不管这个语句有多难看,它一定是声明了一个拥有10个元素的数组c对不对?okay没什么了不起的,只不过这个数组c的元素有点特别,它们都是函数指针,并且它们所指向的这些函数统统都接受一个二级指针然后返回一直指向字符型的指针。加上typedef之后,c就不是一个数组了,而是一种类型了,什么类型现在你能说出来了吧。
#include <signal.h>
#include <stdio.h>
// typedef void (*sighandler_t)(int);
// sighandler_t signal(int signum, sighandler_t handler);
void handler(int signum)
{
printf("get signum = %d\n",signum);
printf("never quit\n");
}
int main()
{
signal(SIGINT,handler);
while(1);
return 0;
}