【【小智雅匯】C|程序塊結構和變量的存儲類(lèi)型】http://toutiao.com/group/6524899958213050884/?iid=15906422033&app=explore_article×tamp=1519315157&tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share
C定義的常用存儲類(lèi)型有4種,即auto、extern、static、register,分別稱(chēng)為自動(dòng)型、外部型、靜態(tài)型和寄存器型。反映變量在內存中存在的空間性和時(shí)間性??臻g性表現為:代碼方面:同一文件內的塊結構,同一程序的其它文件;存儲位置:堆、棧、寄存器。時(shí)間性表現為塊結構的進(jìn)入和退出,程序的開(kāi)始運行和退出。
C語(yǔ)言規定,任何以花括號“{”和“}”括起來(lái)的復合語(yǔ)句都屬于塊結構,在塊內可以對變量進(jìn)行定義,在塊內定義的變量其作用域僅限于塊內。若塊內定義與塊外或外部定義具有相同的變量名,則它們是沒(méi)有關(guān)系的。一個(gè)函數(包括主函數)就是一個(gè)塊結構。
在函數內部定義的變量稱(chēng)為自動(dòng)型,它們的作用域定義在函數內部(主函數也是如此)。不同的函數里若出現相同名字的變量,則它們是毫不相干的。自動(dòng)型變量定義以關(guān)鍵字auto標識,但在函數內部可以省略。
編譯程序為自動(dòng)型變量動(dòng)態(tài)分配存儲空間。具體地說(shuō),這些自動(dòng)型變量使用的??臻g在進(jìn)入函數時(shí)就給予分配,一旦退出該函數,分配給它的空間就立即消失(即這些自動(dòng)型變量消失),所以自動(dòng)型變量既不能被其他函數所引用,也不能保存其值。也就是說(shuō),其存在的時(shí)間較短,空間較小。
外部型變量就是在任何函數(包括主函數)的外部定義的變量,它可以被程序中的所有函數所引用。
外部型變量實(shí)質(zhì)上具有“全局型”定義,它的作用域是整個(gè)程序。在程序的任何地方均可以通過(guò)不同的名字對這種變量進(jìn)行訪(fǎng)問(wèn),但如果有同名變量,則只有內部變量起作用。
引用外部變量主要有以下3個(gè)原因:
I 作為函數之間通信的一種方式。因為外部型變量在整個(gè)程序中都可存取。
II 外部型變量與初始化有關(guān),有時(shí)需要由外部變量提供初始值。
III 外部變量是永久的,在一次函數調用之后到下一次函數調用之前的期間內,能保持它的值不變。
外部型變量必須在任何函數之外定義,在整個(gè)程序(可能有若干個(gè)文件)中都具有相同名字的外部型變量只能在一處定義和初始化,對定義的外部型變量,由編譯程序靜態(tài)地為它們分配適當的存儲空間。
如果要在定義一個(gè)外部型變量之前使用它,或者它被定義在另一個(gè)源文件里,那就必須使用關(guān)鍵字extern進(jìn)行聲明。
#include <stdio.h>
int x=5;
int main()
{
extern y;
printf('x=%d,y=%d\n',x,y);
system('pause');
return 0;
}
int y =6;
//運行結果:x=5,y=6
相對來(lái)說(shuō),外部型變量其存在的時(shí)間較長(cháng),空間較大。
靜態(tài)型變量可以是內部靜態(tài)變量或外部靜態(tài)變量。內部靜態(tài)變量是始終存在并占有有內存單元,其初值也只是在進(jìn)入時(shí)賦值一次。
一般來(lái)說(shuō)函數是外部型的,但同時(shí)也可以將函數定義為靜態(tài)的,被定義為外部靜態(tài)的函數只能被函數所在的文件中的其他函數調用,而不能被其他文件中的函數調用。
通過(guò)將變量或函數定義為外部靜態(tài)型,可以將一個(gè)文件中的一些函數和數據隱藏起來(lái),不允許別的文件存取。這種功能可以使模塊程序設計更方便,特別是當設計一個(gè)大的系統時(shí),一般由若干個(gè)程序員來(lái)設計編寫(xiě)程序,對那些只局限于某些程序使用的全局變量和函數,只要將其定義為外部靜態(tài)型,就可以既防止與其他程序員寫(xiě)的程序產(chǎn)生重名,又使模塊界限清晰。
相對來(lái)說(shuō),靜態(tài)型變量其存在的時(shí)間較長(cháng),空間較相對于上述兩者,處于中間。
(static對函數和外部變量的限定是“空間性”的限定、與對auto變量的限定(時(shí)間性)不同)
是指將auto變量保存到一種特殊的速度更快的存儲單元(寄存器)中。
6.1 mainf.h
#include <stdio.h>
#include <stdlib.h>
extern int ivar1,ivar2;//聲明外部變量
void func1(int ivar1);//聲明函數
6.2 mainf.c
#include 'mainf.h'
int a;//沒(méi)有初始化
static int b; //沒(méi)有初始化
char ch;//沒(méi)有初始化
int c=10;//初始化
char s1[] = 'weareok';//初始化
char c1 = 'w';//初始化
const int i =25;//全局常量
char *p = 'we are here';//全局常量
int main()
{
int num =0;
const int n=25;
volatile int result =15;
static int m=15;
int *p1, *p2;
char *pc = 'she is here';
char st[] = 'we are here';
p2 = (int *)malloc(100);//分配堆
p1 = #
printf('全局沒(méi)初始化變量a,b,ch:\t%p %p %p\n',&a,&b,&ch);
printf('全局初始化變量:c c1 s1:\t%p %p %p\n',&c,&c1,&s1);
printf('全局常量i p:\t%p %p\n',&i,&p);
printf('局部常量n,pc,p2,m:\t%p %p %p %p\n',&n,pc,p2,&m);
printf('局部變量num,result,p1,pc,p1,p2:\t%p %p %p %p %p %p\n',&num,&result,p1,&pc,&p1,&p2);
printf('字符常量指針p,&p,pc,&pc:\t%p %p %p %p\n',p,&p,pc,&pc);
printf('局部字串st,&st,pc,&pc:\t%p %p %p %p\n',st,&st,pc,&pc);
printf('函數地址main,func1:\t%p %p\n',&main,&func1);
printf('主函數內ivar1,ivar2:\t&ivar1=%#p\t&ivar2=#%p\n',&ivar1,&ivar2);
func1(ivar1);
system('pause');
return 0;
}
6.3 func1.c
#include 'mainf.h'
ivar1 = 5;//定義外部變量
ivar2 = 7;//定義外部變量
void func1(int ivar1)//定義函數
{
printf('test函數內:\t&ivar1=%#p\t&ivar2=%#p\n', &ivar1,&ivar2);
printf('test函數內:\t%d*%d=%d\n', ivar1,ivar2,ivar1*ivar2);
}
運行結果:
由上可以看到代碼及數據在內存中的大致存儲規律:
存儲區可以分為代碼區、文字常量區、全局區(靜態(tài)區)、數據區、堆和棧。
代碼區用來(lái)存放程序的二進(jìn)制代碼,由系統負責;
文字常量區存放全局、局部字符串常量(前者可共享),由系統分配在全局區;
全局區(靜態(tài)區)用來(lái)存放全局變量和靜態(tài)變量,分為已初始化和未初始化兩個(gè)區域。
函數的地址存入在數據區,與全局區接近;
棧一般用來(lái)存放文字常量以外的局部變量;
堆一般用來(lái)存放用戶(hù)申請的存儲區,如上面的p2;
-End-
聯(lián)系客服