c++和c語言對於變數定義的方式型別,定義的不同方式確定了變數的生存週期、作用範圍以及可以被誰使用的「許可權」問題。
一般來講我們把儲存的持續性簡稱為變數在程式中定義的位置,有以下三個位置:
1.自動儲存持續性:簡稱自動變數,該變數定義在具體的函式塊中,並且不加(static)這種修飾符,該類變數從函式被呼叫時**塊建立開始到函式執行結束時被釋放。
2.靜態儲存持續性:在函式塊外定義的變數(全域性變數)和使用關鍵字static定義的變數的儲存特性都是靜態的,該類變數在程式的整個生命週期都存在。
3.動態儲存持續性:這類記憶體一般是使用malloc或new申請,通過free或delete進行釋放。需要程式設計師自己進行記憶體的管理。
如下面這個例子:
//儲存資料的三種方案
#include
using
namespace
std;
int global_value = 1; //靜態儲存持續性
void func1(void);
void func1(void)
int main(int argc, char **argv)
free(p_value); //p_value所申請的記憶體需要及時釋放
return
0;}
關於作用於只要記住以下幾點即可:
關於鏈結性建議大家可以閱讀一本較為底層的書《程式設計師的自我修養》,其中的部分章節詳細的介紹了靜態鏈結、動態鏈結以及符號相關的知識。
如果是linux或unix作業系統建議大家熟練掌握,objdump和redelf這兩個可以檢視彙編以及底層鏈結屬性的命令,對於暫存器級別的除錯非常有用。
在c++中我們還需要注意儲存說明符和cv限定符。這裡和c語言有著少許差異和擴充。
說明符說明符包含以下幾個:
auto (修飾自動型別變數)
register (用於宣告中盡量把變數放置在暫存器中)
static (表示內部鏈結性,修飾的變數不再是全域性符號)
extern (引用外部的定義變數或者函式)
thread_local(c++11新增)
mutable
其中需要著重解釋下thread_local和mutable
thread_local相當於把修飾的變數當做是執行緒內部的一部分。
//thread_local test
thread_local int
value = 1;
void func1(void);
void func1(void)
int main(int argc, char **argv)
mutable的用來指定即使結構體或者類變數被定義為const,但是被mutable修飾的變數依然可以修改。
// mutable test
struct test
;int main(int argc, char **argv)
; test1.a = 20; //false
test1.b = 30; // true
return
0;}
cv-限定符
const (常性)
volatile (去掉編譯器的優化)
const修飾的變數在定義之後不可以被修改(實際上這句話是有缺陷的)。
//const修飾的變數不能被修改的**
int main(int argc, char **argv)
也就是說被修飾的value當然不能直接更改,但是如果有int *指標指向了他,使用指標去間接修改value,這種漏洞編譯器是很難察覺的,但是作為程式設計師我們不能去欺負編譯器的粗心!!!
volatile的存在是因為在程式中如果發現某個值被多次賦值,則編譯器會進行優化,不再每次都從記憶體取值,而是把該值放在了暫存器中,如果是單執行緒程式當然這是乙個比較好的優化,但是對於多執行緒程式來說,在多次賦值的期間該變數有可能被其他執行緒已經修改,這樣就會造成錯誤賦值的過程。為了避免這種過度的優化,我們使用了volatile關鍵字,這樣就會提示編譯器每次都去記憶體中取值。
學習筆記1 C 總結
溫故而知新,總結過去,展望未來!一 函式過載 c 中允許通過換名機制實現函式過載,函式過載是指在相同的作用域中,允許存在多個函式名相同的函式 存在條件 他們的引數個數 引數型別 引數排列必須不同,返回值型別不做要求 二 異常處理 所謂異常,就是程式執行到某乙個函式或者方法內部時候,出現了與程式涉及流...
Unity學習筆記(1) C 的相關筆記
主要分為兩種型別 1 值型別 直接儲存在記憶體的棧上面 2 引用型別 在記憶體的棧上面衍生出乙個引用,在記憶體的堆上面才會儲存具體的值 3 指標型別 僅在不安全專案中使用 值型別 1 內建型別,如int bool等 2 使用者可自定義的struct型別及列舉enum型別 所有的值型別均繼承於syst...
學習筆記1 c 實現LRU演算法
leetcode oj上有一道題目,要程式設計實現cache的lru演算法,剛看到這道題的時候,我想到了用佇列來做,但是若用單鏈表來做,必須要儲存尾節點的上乙個節點指標,才能實現快速增加一條資料,程式設計起來很不方便,所以我採用了雙端佇列實現,為了處理方便,儲存兩個帶節點指標,乙個節點的next指向...