一、register變數
關鍵字regiter請求編譯器儘可能的將變數存在CPU的寄存器中。有以下幾點注意的地方。
1、register變數必須是能被CPU寄存器所接受的類型,這通常意味著register變數必須是一個單個的值,並且其長度應小於或等於整型的長度。
但是,有些機器的寄存器也能存放浮點數。
2、register變數可能不存放在記憶體中,所以不能用取址符運算子“ & ”。
3、只有局部變數和形參可以作為register變數,全域變數不行。
4、靜態變數不能定義為register。
register修飾符暗示編譯器相應的變數將被頻繁地使用,如果可能的話,應將其儲存在CPU的寄存器中,以加快其儲存速度。例如下面的記憶體塊拷貝代碼,
/* Procedure for the assignment of structures, */
/* if the C compiler doesn't support this feature */
#ifdef NOSTRUCTASSIGN
memcpy (d, s, l)
{
register char *d;
register char *s;
register int i;
while (i--)
*d++ = *s++;
}
#endif
二、static
1、修飾變數(局部和全域變數)
①靜態全域變數:
在全域資料區分配記憶體;未經初始化的靜態全域變數會被程式自動初始化為0(自動變數的值是隨機的,除非它被顯式初始化);
範圍僅限於變數被定義的檔案中。
全域變數和全域靜態變數的區別:
1)全域變數是不顯式用static修飾的全域變數,但全域變數 預設是靜態,範圍是整個工程,在一個檔案內定義的全域變數,在另一個檔案中,
通過extern 全域變數名的聲明,就可以使用全域變數。
2)全域靜態變數是顯式用static修飾的全域變數,範圍是所在的檔案,其他的檔案即使用extern聲明也不能使用。
② 靜態局部變數
#include<cstdio>增加這條語句
char a = ‘A‘; // global variable
void msg()
{
printf("Hellon");
}
你可能會問:為什麼在a.c中定義的全域變數a和函數msg能在main.c中使用?前面說過,所有未加static首碼的全域變數和函數都具有全域可見度,其它的源檔案也能訪問。此例中,a是全域變數,msg是函數,並且都沒有加static首碼,因此對於另外的源檔案main.c是可見的。
如果加了static,就會對其它源檔案隱藏。例如在a和msg的定義前加上static,main.c就看不到它們了。利用這一特性可以在不同的檔案中定義同名函數和同名變數,而不必擔心命名衝突。Static可以用作函數和變數的首碼,對於函數來講,static的作用僅限於隱藏,而對於變數,static還有下面兩個作用。
(2)static的第二個作用是保持變數內容的持久。儲存在待用資料區的變數會在程式剛開始運行時就完成初始化,也是唯一的一次初始化。共有兩種變數儲存在靜態儲存區:全域變數和static變數,只不過和全域變數比起來,static可以控制變數的可見範圍,說到底static還是用來隱藏的。
(3)static的第三個作用是預設初始化為0。其實全域變數也具備這一屬性,因為全域變數也儲存在待用資料區。在待用資料區,記憶體中所有的位元組預設值都是0x00,某些時候這一特點可以減少程式員的工作量。
最後對static的三條作用做一句話總結。首先static的最主要功能是隱藏,其次因為static變數存放在靜態儲存區,所以它具備持久性和預設值0。
下面是main.c的內容
除了標頭檔,需要聲明函數:void msg();
int main(void)
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
2、靜態函數
在函數的傳回型別前加上static關鍵字,函數即被定義為靜態函數。靜態函數與普通函數不同,它只能在聲明它的檔案當中可見,
不能被其它檔案使用。其它檔案中可以定義相同名字的函數,不會發生衝突。
static 函數…..
內建函式和外部函數
當一個來源程式由多個源檔案組成時,C語言根據函數能否被其它源檔案中的函數調用,將函數分為內建函式和外部函數。
1 內建函式(又稱靜態函數)
如果在一個源檔案中定義的函數,只能被本檔案中的函數調用,而不能被同一程式其它檔案中的函數調用,這種函數稱為內建函式。
定義一個內建函式,只需在函數類型前再加一個“static”關鍵字即可,如下所示:
static 函數類型 函數名(函數參數表)
{……}
關鍵字“static”,譯成中文就是“靜態”,所以內建函式又稱靜態函數。但此處“static”的含義不是指儲存方式,而是指對函數的範圍僅局限於本檔案。
使用內建函式的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它檔案中的函數同名,因為同名也沒有關係。
2 外部函數
外部函數的定義:在定義函數時,如果沒有加關鍵字“static”,或冠以關鍵字“extern”,表示此函數是外部函數:
[extern] 函數類型 函數名(函數參數表)
{……}
調用外部函數時,需要對其進行說明:
[extern] 函數類型 函數名(參數類型表)[,函數名2(參數類型表2)……];
案例]外部函數應用。
(1)檔案mainf.c
main()
{ extern void input(…),process(…),output(…);
input(…); process(…); output(…);
}
(2)檔案subf1.c
……
extern void input(……) /*定義外部函數*/
{……}
(3)檔案subf2.c
……
extern void process(……) /*定義外部 函數*/
{……}
(4)檔案subf3.c
……
extern void output(……) /*定義外部函數*/
{……}