最近在整理知識結(jié)構(gòu)塞赂,就隨便分享一下,如果有什么錯誤剂跟,歡迎糾正减途!
博客原文
歡迎點(diǎn)擊
存儲類關(guān)鍵字(用于修飾變量)
auto(自動變量)
- auto即平時的局部變量關(guān)鍵字,可以省略曹洽,故定義局部變量時都沒有寫
- 分配在內(nèi)存中的棧上
register(寄存器變量)
- 這個不是很常用
- 編譯器會將其所修飾的變量盡量分配在寄存器中(使其變量的讀寫效率會變高)
- 由于寄存器數(shù)量有限鳍置,關(guān)鍵字所修飾的變量不一定都放在寄存器內(nèi)
static(靜態(tài)變量)
- 修飾變量
- 修飾全局變量
- 修飾局部變量
- 修飾函數(shù)
修飾類別 | 形成 | 分配位置 | 生命周期 | 鏈接屬性 |
---|---|---|---|---|
局部變量 | 靜態(tài)局部變量 | 數(shù)據(jù)段/BSS段 | 代碼塊作用域 | 無鏈接 |
全局變量 | 靜態(tài)全局變量 | 數(shù)據(jù)段/BSS段 | 文件作用域 | 內(nèi)鏈接 |
函數(shù) | 靜態(tài)函數(shù) | 在其聲明文件 | 文件作用域 | 內(nèi)鏈接 |
extern(外部變量)
- 修飾全局變量,用于文件作用域以外訪問
const(只讀變量)
- 其所修飾的變量存儲在只讀變量區(qū)送淆,在C中仍然是變量(C++中税产,是只讀常量)
- 編譯器通常將const保存在符號表中而非分配存儲空間薇搁,從而節(jié)省了空間欧漱,提高了效率(例子:函數(shù)傳參聲明為const指針--另外一個就是防止該指針在函數(shù)體內(nèi)被意外修改)
就近原則 | 解釋 |
---|---|
const int a; | a是常整型數(shù)蹬叭,a不可變 |
const int *a; | a是指向一個常整型數(shù)的指針核行,a所指內(nèi)容不可變 |
int *const a; | a是指向一個整型數(shù)的常指針稠集,a不可變 |
const int* const a; | a是指向一個常整型數(shù)的常指針名惩,a及其所指內(nèi)容都不可變 |
修改const修飾的變量(在GCC環(huán)境中)
在GCC中续捂,const是通過編譯器在編譯的時候執(zhí)行檢查來確保實現(xiàn)的(即改const類型變量是編譯錯誤眷蜈,而非運(yùn)行時錯誤)
GCC編譯器把const類型的變量放在了數(shù)據(jù)段谒出,只是通過編譯器認(rèn)定這個變量是const的隅俘,運(yùn)行時并沒有標(biāo)記const標(biāo)志,故只要騙過編譯器笤喳,const變量就可以修改了为居。
const int a = 5;
int *p;
p = (int *)&a;
*p = 6;
printf("a = %d. \n", a);
volatile(易變變量)
- 用以修飾一個可以被編譯器之外改變的變量,告訴編譯器不對改變量的訪問進(jìn)行優(yōu)化
編譯器之內(nèi):當(dāng)前程序上下文的控制流(即當(dāng)前代碼)
編譯器之外:中斷ISR中引用的變量杀狡、多線程中共用的變量蒙畴、硬件會更改的變量。(編譯器在編譯時無法預(yù)知的更改)
typedef(自定義數(shù)據(jù)類型變量)
自定義數(shù)據(jù)類型(不要與#define相混淆)
typedef int *Pint; const Pint p;
typedef int *Pint; Pint const p;
- 以上兩個皆相當(dāng)于 int *const p; 即p皆為常指針
很多初學(xué)者都很難去記住上面的兩個關(guān)系呜象,是因為又與#define相混淆了膳凝,還沒有完全理解typedef這個關(guān)鍵字
原理如下: - 編譯器在解析的時候會忽略數(shù)據(jù)類型,直接修飾p恭陡,因此以上兩個式子都可以看為 Pint const p;
- 如果實在想不通鸠项,就想想 const int i; 和int const i; 為什么是相同的
restrict
- 只用于修飾指針;其告知編譯器子姜,所有修改該指針?biāo)赶騼?nèi)容的操作全部是基于該指針的祟绊,即不存在其他進(jìn)行修改操作的途徑
看不懂,是不是哥捕?其實它的作用就是為了幫助編譯器進(jìn)行更好的代碼優(yōu)化牧抽。
該關(guān)鍵字用得少,慎用
注:本文內(nèi)容部分來自互聯(lián)網(wǎng)整理遥赚,部分來自個人經(jīng)驗總結(jié)扬舒;本文將持續(xù)收集更新,歡迎留言補(bǔ)充凫佛!