概述
基本上每种语言都要讨论这个话题,C语言也不例外,因为只有你完全了解每个变量或函数存储方式、作用范围和销毁时间才可能正确的使用这门语言。今天将着重介绍C语言中变量作用范围、存储方式、生命周期、作用域和可访问性。
变量作用范围 存储方式 可访问性变量作用范围
在C语言中变量从作用范围包括全局变量和局部变量。全局变量在定义之后所有的函数中均可以使用,只要前面的代码修改了,那么后面的代码中再使用就是修改后的值;局部变量的作用范围一般在一个函数内部(通常在一对大括号{}内),外面的程序无法访问它,它却可以访问外面的变量。
//
// main.c
// ScopeAndLifeCycle
//
// Created by Kenshin Cui on 14-7-12.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#include <stdio.h>
int a=1;
void changeValue(){
a=2;
printf("a=%dn",a);
}
int main(int argc, const char * argv[]) {
int b=1;
changeValue(); //结果:a=2
printf("a=%d,b=%dn",a,b); //结果:a=2,b=1 ,因为changeValue修改了这个全局变量
return 0;
}
变量存储方式
C语言的强大之处在于它能直接操作内存(指针),但是要完全熟悉它的操作方式我们必须要弄清它的存储方式。存储变量的位置分为:普通内存(静态存储区)、运行时堆栈(动态存储区)、硬件寄存器(动态存储区),当然这几种存储的效率是从低到高的。而根据存储位置的不同在C语言中又可以将变量依次分为:静态变量、自动变量、寄存器变量。
静态变量
首先说一下存储在普通内存中的静态变量,全局变量和使用static声明的局部变量都是静态变量,在系统运行过程中只初始化一次(在下面的例子中虽然变量b是局部变量,在外部无法访问,但是他的生命周期一直延续到程序结束,而变量c则在第一次执行完就释放,第二次执行时重新创建)。
//
// 2.1.c
// ScopeAndLifeCycle
//
// Created by Kenshin Cui on 14-7-12.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#include <stdio.h>
int a=1; //全局变量存储在静态内存中,只初始化一次
void showMessage(){
static int b=1; //静态变量存储在静态内存中,第二次调用不会再进行初始化
int c=1;
++b;
a+=2;
printf("a=%d,b=%d,c=%dn",a,b,c);
}
int main(int argc, const char * argv[]) {
showMessage(); //结果:a=3,b=2,c=1
showMessage(); //结果:a=5,b=3,c=1
return 0;
}
自动变量
被关键字auto修饰的局部变量是自动变量,但是auto关键字可以省略,因此可以得出结论:所有没有被static修饰的局部变量都是自动变量。
//
// 1.3.c
// ScopeAndLifeCycle
//
// Created by Kenshin Cui on 14-7-12.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
int a=1;
auto int b=2;
printf("a=%d,b=%dn",a,b); //结果:a=1,b=2 ,a和b都是自动变量,auto可以省略
//需要注意的是,上面的自动变量是存储在栈中,其实还可以存储到堆中
char c[]="hello,world!";
long len=strlen(c)*sizeof(char)+1;//之所以加1是因为字符串后面默认有一个 空操作符不计算在长度内
char *p=NULL;//可以直接写成:char *p;
p=(char *)malloc(len);//分配指定的字节存放c中字符串,注意由于malloc默认返回“void *”需要转化
memset(p,0,len);//清空指向内存中的存储内容,因为分配的内存是随机的,如果不清空可能会因为垃圾数据产生不必要的麻烦
strcpy(p,c);
printf("p=%sn",p);//结果:p=hello,world!
free(p);//释放分配的空间
p=NULL;//注意让p指向空,否则p将会是一个存储一个无用地址的野指针
return 0;
}










