c語言變數的作用域,連結屬性,儲存型別&&static關鍵字
http://blog.csdn.net/mingzhentanwo/article/details/43524383
一、作用域:
變數在程式的某個部分宣告時,只能在程式的一定區域內才能訪問,這個區域就成為作用域。
作用域分為四種:
①檔案作用域②函式作用域③程式碼塊作用域④原型作用域。
編譯器通過變數宣告的位置來確定作用域
(1)檔案作用域
當變數在所有程式碼塊之外宣告時就在檔案作用域中,檔案作用域的範圍是從變數宣告處一直到檔案的結束。但如果變數的宣告在“.h”檔案中,並且該“.h”檔案被其他檔案用#include 所包含,那該變數的作用域也會相應的擴大到包含檔案的結束。
(2)函式作用域
函式作用域只適用於語句標籤,語句標籤用於goto語句。一個函式作用域內的語句標籤必須唯一。
(3)程式碼塊作用域
宣告位於一對大括號之間,有效範圍從宣告開始至程式碼塊結束。
(4)原型作用域
原型作用域 適用於在函式宣告中的引數名,只適用於函式宣告的括號內;
二、連結屬性
連結屬性決定如何處理在同一個專案位於不同檔案內的識別符號。連結屬性共有三種——①external(外部)、②internal(內部)、③none(無)。
- 連結屬性為none的識別符號不論在那個檔案內都是獨立的個體。
- 連結屬性為internal的識別符號在同一個原檔案內的所有宣告均指向同一個實體,不能在其他檔案中使用extern關鍵字被使用;
連結屬性為external的識別符號不論宣告多少次,位於幾個原檔案內均表示同一實體,可以在其他檔案中使用extern關鍵字宣告使用;
※在檔案作用域內宣告的變數或是函式,在預設的條件下連結屬性為external(相當於前面加了extern),其餘的為none
(1)extern關鍵字
如果使用externa關鍵字宣告某一個變數,說明該變數在別的地方定義的,可能位於別的檔案也可能位於當前檔案。該關鍵字制定識別符號的連結屬性為external,在一個專案中 ,在一個檔案內部可以通過extern關鍵字訪問由別的檔案定義的變數,但此時不能在使用extern修飾變數的同時給該變數賦初值
例1:在test2.c檔案中使用test1.c檔案中的變數a,且變數a屬性為external.
會出錯: 找到一個或多個多重定義的符號
//test1.c
#include<stdio.h>
int a=0;
void fun1()
{
printf("%d\n",a);
}
//test2.c
#include<stdio.h>
int a=1;
void fun2()
{
printf("%d\n",a);
}
//main.c
#include<stdio.h>
void fun1();
void fun2();
int main()
{
fun1();
fun2();
return 0;
}
出錯: 找到一個或多個多重定義的符號
例2:在test2.c檔案中使用關鍵字extern宣告,使用test1.c檔案中的變數a,此時,test2.c中的a值就是test1.c中的a值;且變數a屬性為external;然後在main.c中使用extern宣告a;此時,在三個原始檔中使用的a為一個記憶體中的a,
這時,三個只要改了一個原始檔的a值,三個原始檔當中的a值都會改變;
程式正確
//test1.c
#include<stdio.h>
int a=0;
void fun1()
{
printf("%d\n",a);
}
//test2.c
#include<stdio.h>
extern int a;
a=1;
void fun2()
{
printf("%d\n",a);
}
//main.c
#include<stdio.h>
void fun1();
void fun2();
int main()
{
extern int a;
fun1();
fun2();
a=10;
fun1();
fun2();
return 0;
}
//結果:0 ,0 , 10 , 10
(2)static關鍵字
如果一個識別符號的連結屬性為external,那麼static可以將其連結屬性改為intern,此時static修飾的變數或者函式名,都只能在本檔案中使用,不能使用extren關鍵字在別的檔案中宣告使用;此時別的檔案可以命名和靜態變數或者函式相同的變數名或者函式名;此時,在別的檔案中如果使用extren宣告和靜態變數的變數名或者函式名相同的名字,並對其變數做改變;此時靜態變數或者函式不改變,含有相同名變數的檔案裡面的變數會改變;
例1、test1.c中定義一個全域性靜態變數,此時該變數的連結屬性從external變為internal;在test2.c中定義了一個和變數名相同的變數;可以成功定義;
此時test2.c中的a的連結屬性為external;在main.c中使用extren關鍵字宣告a變數;實際是宣告的test2.c中的a變數;在main.c中對a做修改,只是改變了
test.2中的a;
//test1.c
#include<stdio.h>
static int a=0;
void fun1()
{
printf("%d\n",a);
}
//test2.c
#include<stdio.h>
int a=10;
void fun2()
{
printf("%d\n",a);
}
#include<stdio.h>
void fun1();
void fun2();
int main()
{
extern int a;
fun1();
fun2();
a=100;
fun1();
fun2();
return 0;
}
//結果:0 ,10, 0, 100
三、儲存型別
儲存型別(儲存位置)分為普通記憶體,執行時堆疊和硬體暫存器
變數的預設型別取決於它的儲存型別:
•在程式碼塊之外宣告的變數總是儲存在靜態記憶體中,這種變數稱為靜態變數。無法改變這種變數的儲存型別。靜態變數在程式執行之前建立,在整個程式執行時一直存在直至結束才被銷燬。
•在程式碼塊內宣告的變數預設儲存型別為自動的,儲存在堆疊內。每次函式被呼叫時,這些變數的儲存的位置可能不同。如果用static來修飾一個函式內的變數,就可以將他轉變為靜態的,靜態儲存型別的變數在整個程式執行的過程中一直存在,而不僅僅是在它所在的程式碼塊執行的時候存在,修改變數的儲存型別,不會改變的該變數的作用域,它只能在該變數內部按名字訪問,※只是每次函式被呼叫時,該變數的值仍為上次函式結束時的值。
•用register修飾的變數成為暫存器變數,通常,這種變數的訪問速率比在記憶體中的變數訪問速度快。
四、static關鍵字
(1)當static用於程式碼塊之外時,static用於修改識別符號的連結屬性,從external修改為static
當static用與程式碼塊內部時,static用於修改識別符號的儲存型別,將其從自動變數修改為靜態變數
相關文章
- 作用域、連結屬性和儲存型別型別
- C語言中識別符號的作用域、名稱空間、連結屬性、生命週期、儲存型別C語言符號型別
- c語言static關鍵字的理解C語言
- static關鍵字的作用
- C語言之static關鍵字C語言
- c語言中的變數儲存區域C語言變數
- java中static關鍵字的作用Java
- C語言 關鍵字const的作用 const int* 和int *const 的區別C語言
- java基礎語法--註釋、識別符號、關鍵字、資料型別、型別轉換、變數、常量、作用域、運算子Java符號資料型別變數
- C語言中static關鍵字詳解C語言
- C語言--靜態區域性變數C語言變數
- C語言細節 儲存類別,連結,記憶體管理C語言記憶體
- C語言中volatile關鍵字的作用C語言
- 【粉絲問答10】C語言關鍵字static的使用詳解C語言
- [C語言] 浮點型儲存C語言
- C語言-變數常量資料型別C語言變數資料型別
- C語言include關鍵字和引用.h .c的區別C語言
- c語言中作用域和儲存期的區別C語言
- C:static 關鍵字、靜態變數、跨類訪問資料變數
- Go語言的識別符號、關鍵字、字面量、型別Go符號型別
- C語言的幾個關鍵字C語言
- PLC結構化文字(ST)——變數型別和變數屬性變數型別
- 【轉】C++ static關鍵字C++
- GO語言變數作用域-坑記錄Go變數
- 值得儲存的 synchronized 關鍵字總結synchronized
- GO語言基礎(結構+語法+型別+變數)Go型別變數
- C語言線性連結串列C語言
- 非易失性儲存器NV-SRAM的關鍵屬性
- javascript中的作用域(全域性變數和區域性變數)JavaScript變數
- C# 變數作用域C#變數
- static關鍵字
- static在C語言中的作用C語言
- PHP static 關鍵字和 self 關鍵字例項化的區別PHP
- Go語言中的變數作用域Go變數
- 強型別語言變數和資料型別的理解變數資料型別
- final關鍵字和static關鍵字
- Java 的 static 關鍵字Java
- const關鍵字在C與C++中修飾變數的區別C++變數
- C語言:如何給全域性變數起一個別名?C語言變數