儲存類別和記憶體管理
概念
作用域:塊作用域,函式作用域,檔案作用域
連結:
外部連結:多檔案中使用
內部連結:只在一個翻譯單元(檔案)內使用
無連結 :具有塊,
函式,函式原型作用域的變數
儲存期:靜態作用域和非靜態作用域
自動變數:
1.自動儲存期,
2.塊作用域,
3.無連結
4.auto關鍵字(顯式)
void doSome(){
int d = 3;
};
int main(int argc, const char * argv[]) {
int a = 0;
for (int i = 0 ; i < 10 ; i++) {
int b = 1;
}
{
auto int c = 2;
}
return 0;
}
// a,b,c,d都是自動變數
靜態內部連結:
1.static顯式宣告,
2.靜態儲存期,
3.內部連結,
4.檔案作用域.
static int statc_a = 2; //只能在main.c中訪問
int main(int argc, const char * argv[]) {
printf("%d",statc_a);
return 0;
}
靜態外部連結:
1.靜態儲存期,
2.外部連結,
3.檔案作用域.
/* sub.h */
#include "sub.h"
int sub_a = 2;
/* main.c */
#include <stdio.h>
int main(int argc, const char * argv[]) {
extern int sub_a;
printf("sub_a : %d\n",sub_a);
return 0;
}
/*
sub_a : 2
Program ended with exit code: 0
*/
//編譯器會找到sub_a這個變數的。
這樣使用靜態外部連結的儲存類別變數是有問題的,如果全域性的變數名有重複的就會報錯,比如在main.c中又定義了一個相同名字的sub_a ,編譯無法通過,顯示連結錯誤。
#include <stdio.h>
int sub_a = 2;
int main(int argc, const char * argv[]) {
extern int sub_a;
printf("sub_a : %d\n",sub_a);
return 0;
}
//clang: error: linker command failed with exit code 1 (use -v to see invocation)
一個比較規範辦法是使用標頭檔案,在標頭檔案中申明需要外部使用的變數extern
/* .h */
#include <stdio.h>
extern int sub_a;
#endif /* sub_h */
/* main.c */
#include <stdio.h>
#include "sub.h"
int main(int argc, const char * argv[]) {
printf("sub_a : %d\n",sub_a);
int sub_a = 3;
printf("sub_a : %d\n",sub_a);
return 0;
}
//但是依然並不能完全解決我們上面產生的問題。
靜態無連結
1.靜態儲存期,
2.無連線,
3.塊作用域
PS:靜態變數只能初始化一次,並且定義時候必須賦值。
static:在宣告區域性變數時,使用關鍵字 static 將區域性變數指定為“靜態區域性變數”,這樣在函式呼叫結束後不消失而保留原值,即佔用的儲存單元不釋放,在下一次函式呼叫時,該變數已有值就是上次函式呼叫結束時的值。
static的作用?
1.在塊作用域內將變數的儲存期變成靜態
void add(){
static int static_a = 1;
int a = 1;
printf("static_a:%d---a:%d\n",static_a,a);
static_a++;
a++;
}
//呼叫三次
static_a:1---a:1
static_a:2---a:1
static_a:3---a:1
2,將檔案作用域內的變數從外部連結變成內部連結
/* sub.c */
#include "sub.h"
static int static_sub_a = 3;
int sub_a = 2;
/* main.c */
int main(int argc, const char * argv[]) {
extern int sub_a;
extern int static_sub_a;
printf("%d\n",static_sub_a);
printf("%d\n",sub_a);
return 0;
}
//報錯 "_static_sub_a", referenced from: 外部無法訪問static_sub_a
相關文章
- C語言細節 儲存類別,連結,記憶體管理C語言記憶體
- InnoDB儲存引擎——記憶體儲存引擎記憶體
- openGauss儲存技術(二)——列儲存引擎和記憶體引擎儲存引擎記憶體
- double型別資料在記憶體中中儲存格式型別記憶體
- 記憶體中的資料儲存記憶體
- Redis 記憶體優化神技,小記憶體儲存大資料Redis記憶體優化大資料
- iOS另類的記憶體管理iOS記憶體
- Redis 記憶體使用優化與儲存Redis記憶體優化
- 記憶體管理 記憶體管理概述記憶體
- SGA和PGA記憶體管理記憶體
- Redis記憶體使用最佳化與儲存Redis記憶體
- Fdmemtable 記憶體表儲存圖片的例子記憶體
- 自動共享記憶體管理 自動記憶體管理 手工記憶體管理記憶體
- 記憶體管理篇——實體記憶體的管理記憶體
- linux記憶體管理(一)實體記憶體的組織和記憶體分配Linux記憶體
- 遊戲記憶體對比普通記憶體區別 遊戲記憶體和普通記憶體相差大嗎?遊戲記憶體
- 【記憶體管理】記憶體佈局記憶體
- 小數在記憶體中是如何儲存的?記憶體
- 【C語言】整型在記憶體中的儲存C語言記憶體
- Color類和測試記憶體的類MemoryMonitor記憶體
- Node - 記憶體管理和垃圾回收記憶體
- JVM記憶體管理和垃圾回收JVM記憶體
- Swift記憶體賦值探索一: 理解物件在記憶體中的儲存狀態Swift記憶體賦值物件
- Linux記憶體洩露案例分析和記憶體管理分享Linux記憶體洩露
- java記憶體溢位和記憶體洩漏的區別Java記憶體溢位
- C和C++的動態記憶體管理的區別C++記憶體
- 你真的懂 Java 的記憶體管理和引用型別嗎?Java記憶體型別
- 記憶體管理記憶體
- 記憶體管理兩部曲之實體記憶體管理記憶體
- Go:記憶體管理與記憶體清理Go記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- Aerospike的bin記憶體管理--即列記憶體管理ROS記憶體
- oracle程式和記憶體轉儲說明Oracle記憶體
- spark 原始碼分析之十六 -- Spark記憶體儲存剖析Spark原始碼記憶體
- 解讀記憶體資料庫的儲存需求RC記憶體資料庫
- memcached全面剖析--2.理解memcached的記憶體儲存記憶體
- MySQL記憶體管理,記憶體分配器和作業系統MySql記憶體作業系統
- 浪潮儲存:以全快閃記憶體儲加速數字轉型記憶體