在C語言中我們可以給變量指定屬性,因此在我們的C語言關鍵字中有一種關鍵字叫屬性關鍵字,是用來指定變量特有的屬性。
一、AUTO即就是C語言中局部變量的默認屬性
編譯器默認所有的局部變量都是AUTO的。AUTO還有另外的一種含義,就是在內存的棧上面分配空間。堆棧是一個動態分配內存空間的地方。
二、static 關鍵字指明變量的靜態屬性。
1.static 關鍵字同時具有作用於限定符的意義,即文件作用域標識符。文件作用域的意思就是定義的這個變量就限於當前文件時全局的其他文件是不可以訪問的。
-static 修飾的全局變量作用域只限於聲明的文件中
-static 修飾的函數作用域只限於聲明的文件中
2.static 修飾的局部變量存儲在程序靜態區
例如:
1.其他文件可以訪問的情況:
test1.c
int myInt = 0; //在test1.c中定義一個全局變量沒有使用static修飾的情況下。test2.c可以調用
int MyFunction() //在test1.c中定義一個全局函數沒有使用static修飾的情況下。test2.c可以調用
{
return myInt;
}
test2.c
#include<stdio.h>
extern myInt; //extern關鍵字是引用其他文件中定義的變量或函數。
extern MyFunction();
int main(viod)
{
int j = 0;
for (j = 0 ;j<5;j++)
{
printf("%d\n",MyFunction());
printf("%d\n",myInt);
}
return 0;
}
2.其他文件不能訪問的情況:
test1.c
static myInt = 0; //由於使用了static修飾因此其他文件時不可以訪問的
static int MyFunction() //由於使用了static修飾因此其他文件時不可以訪問的
{
return 0;
}
test2.c
#include<stdio.h>
extern myInt; //extern關鍵字是引用其他文件中定義的變量或函數。
extern MyFunction();
int main(viod)
{
int j = 0;
for (j = 0 ;j<5;j++)
{
printf("%d\n",MyFunction());
printf("%d\n",myInt);
}
return 0;
}
這種情況進行編譯時會報錯。
三、register
1.register 關鍵字指明將變量存儲於寄存器中也就是說cpu中,register 只是請求存儲器變量,但不一定請求成功。必須達到一定的條件才能成功,如要達到寄存器可以接受的字節長度。在一般的情況下,cpu寄存器只是儘量的把這個變量當做cpu寄存器的變量進行存儲,但不一定成功的。
2.不能使用取地址符(&)來獲取register變量的地址。因爲存放在cpu寄存器中,使用取地址符是取不到的,&是取內存中的地址。
3.我們知道棧中的變量是經常變換的,因此如果我們定義一個全局變量使用auto進行修飾時會報錯(例1-1)。如果使用register進行修飾的時候同樣
會出現錯誤的(例1-1),因此如果我們允許變量長期的存放到寄存器中,如果寄寄存器沒有可以使用的空間的時候就會造成cpu無法工作。因此在C語言中是不可
以存放全局變量到寄存器中。
例如1-1:
#include<stdio.h>
static int l;
register int s;
auto int m;
int main(viod)
{
static int i;
register int j;
return 0;
}
4.register修飾的變量發在cpu寄存器中,在cpu寄存器中變量取得速度遠高於內存中的變量,因此在實時性的系統中或者要求性能很高
的系統中往往會把變量存放在cpu寄存器中。
對比使用了register 和不使用register的區別:
--使用register
---------------------------------------------------------------
#include<stdio.h>
#include<sys/time.h>
int main(int arg ,char * argv[])
{
struct timeval start,end;
gettimeofday(&start,NULL);//start time
double timeuse;
register double sum;
register int j,k;
for(j=0;j<1000000000;j++){
for(k=0;k<10;k++)
{
sum = sum+1.0;
}
}
gettimeofday(&end,NULL);
timeuse = 1000000 * (end.tv_sec - start.tv_sec)+end.tv_usec-start.tv_usec;
timeuse/=1000000;
printf("running time :%f\n",timeuse);
return 0;
}
消耗的時間爲:running time :8.547920
---------------------------------------------------------------
--不是用register
--------------------------------------------------------------
#include<stdio.h>
#include<sys/time.h>
int main(int arg ,char * argv[])
{
struct timeval start,end;
gettimeofday(&start,NULL);//start time
double timeuse;
double sum;
int j,k;
for(j=0;j<1000000000;j++){
for(k=0;k<10;k++)
{
sum = sum+1.0;
}
}
gettimeofday(&end,NULL); //end time
timeuse = 1000000 * (end.tv_sec - start.tv_sec)+end.tv_usec-start.tv_usec;
timeuse/=1000000;
printf("running time :%f\n",timeuse);
return 0;
}
消耗的時間爲:running time:34.287267
---------------------------------------------------------------
在這裏我們使用到了struct timeval 結構體和gettimeofday()函數。
結構體的定義爲:
---------------------------------------------------------------
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
---------------------------------------------------------------
函數:
---------------------------------------------------------------
/* Get the current time of day and timezone information,
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
Returns 0 on success, -1 on errors.
NOTE: This form of timezone information is obsolete.
Use the functions and variables declared in <time.h> instead. */
extern int gettimeofday (struct timeval *__restrict __tv,
__timezone_ptr_t __tz) __THROW __nonnull ((1));
---------------------------------------------------------------
gettimeofday()功能是得到當前時間和時區,分別寫到tv和tz中,如果tz爲NULL則不向tz寫入。