C語言全面總結-3
C語言基本知識點複習-3
typedef & define
typedef 是一個C語言中的關鍵字 用來為一個資料型別取別名 以增加程式碼的可讀性 用typedef定義陣列、指標、結構等型別會帶來很大的方便 不僅使程式書寫簡單 也使意義明確 增強可讀性。
define 是一個C語言中的指令 不緊可以為型別取別名 還可以用於常量 變數 和開關編譯等
typedef和define的區別
- typedef是關鍵字 在編譯的時候起作用 會檢查資料型別
define是一個預處理指令 在預處理階段對程式碼進行替換 所以巨集定義不佔用編譯時間 - define沒有作用域 而 type有自己的作用域
- 在對指標使用時有區別
比如:
先定義
#define int * INT1
typedef int * INT2
INT1 a,b;=====>int *a,b; 表示建立了一個int型指標a和一個int 型變數b
INT2 a,b; =====>int *a,*b; 表示建立了兩個int指標a和b
用INT1和INT2定義的a,b結果會不一樣 由此可見define僅僅是做一個文字上的簡單替換 而typedef不僅替換文字 同時還兼顧了替換的型別的功能
當用typedef 為結構體取別名時
正常我們定義結構體一般都是 struct + structName {…}; 這樣既沒有很好的可讀性 而且每次建立新的結構體變數時都要寫 struct +structName + structA 就很麻煩
所以用typedef為結構體取別名就很方便 例如:
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
這樣就可以直接用book來代表struct Books 這一串 既簡便又增加了可讀性
當然還有進階版本 直接定義結構體+結構體指標升級套餐
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book,*bookPtr;
這個程式碼的意思就是為struct Books取別名為book 為struct Books *取別名為bookPtr
程式記憶體分佈和記憶體管理
一般我們講的程式記憶體 比如說計算機當前執行了三個程式 則對於每一個程式都會將physical memory實體記憶體的一部分對映成一塊完整的虛擬記憶體 讓每個程式都以為自己擁有了完整的記憶體空間 這樣子可以極大的方便了資料和程式碼的組織
一個程式所對映的虛擬地址如下(virtual memory 虛擬記憶體)
上邊的圖中 大致把VM分成了六個大塊 核心 、棧、堆、資料段、程式碼段、不可訪問的空間 但其中核心和不可訪問段是使用者無法訪問的
一般我們無法直接檢視一個exe可執行檔案的內容 但是在linux下可以使用" readelf 檔名 -s " 指令來檢視一個可執行檔案的section段資訊
這裡的一些 像11.13 .15等都對應著上圖VM中不同的段位置
棧
棧的全稱為(run-time stack)執行時棧 意味著在執行時棧的大小是變化的 一般棧中儲存的是區域性變數 一旦一個函式被呼叫 則會建立一幀新的棧用來存放該程式的區域性變數和形參 當然在實現函式的巢狀呼叫時 還要儲存當下的程式碼地址和相關暫存器的值 以便於保護現場和恢復現場 但是棧的空間很小 一般只有8M
如果超出了這個界限則會產生 “棧溢位” 導致程式崩潰 所以一邊程式用不宜呼叫太深的巢狀函式 和太多的區域性變數
堆
堆的全稱為(run-time heap)執行時棧 所以堆也是大小變化的 主要用來儲存使用者自定的資料空間 一般有以下幾個函式建立和釋放
malloc() //建立一個連續的自定義空間
calloc(n,m)//建立n個每個m大小的自定義空間
realloc()//為已有的自定義空間更改大小
free()//釋放自定義空間
!!! 建立動態記憶體空間後記得要用free釋放
資料段
用來存放全域性變數 靜態變數 其中又分三段
.bss 用來存放未初始化靜態資料 比如a[100] 這個陣列沒初始化 因為系統會對為初始化的靜態資料自動初始化為0 但是如果直接存100個0在a[100]裡有點浪費空間 所以在.bss這一段中就可以標記一下 說這個陣列是未初始化的 就不用記100個0
.data 用來存放已初始化的靜態變數
.rodata 顧名思義就是隻讀(read only data)用來存放常量
程式碼段
用來存放使用者程式碼和系統程式碼
使用者程式碼好理解
系統程式碼就是系統給可執行檔案自動新增的一個“初始化程式碼”包括環境變數的準備 命令列引數的組織和傳遞 這部分資料在棧底 緊挨著核心的那裡
一些細節點
- 棧底的那部分環境變數開始執行後就不會更改 執行過程中更改的環境變數會儲存在堆中
- 棧和堆都是動態變化的 執行過程中 棧從上往下增長 堆從下往上增長(上邊的圖也可以看出來)
- 靜態資料包括:全域性變數和static修飾的區域性變數
- 應儘量避免濫用靜態變數 first 因為靜態變數在整個程式執行期間都生存的 會佔空間 second 例如全域性變數屬於共享資源 在多執行緒中容易產生競爭 需要小心的互斥以保護
檔案I/O
I/O可以使用系統IO和標準IO
系統IO是作業系統訪問檔案的API 介面 例如Linux裡面的open()close()
標準IO是C語言標準庫中提供的結構 例如fopen()fclose()
當使用fopen時系統會返回檔案指標int *File
open()會返回一個檔案描述符 int file
一遍檔案描述符會從3開始 因為0.1.2已經分別被標準輸入(鍵盤)標準輸出(顯示器 )和標準出錯所佔據
使用檔案指標或檔案描述符就可以對檔案進行操作了
小結
C語言基礎就告一段落了 其實還有好多深入的知識點還沒有複習到 比如連結串列結構 指標的詳細 等等… 後面會繼續學習計組計網 資料結構演算法 和作業系統 到時候再對進階的一些C語言知識點做進一步專門的總結歸納吧
嗜好太多 能力太小~
相關文章
- C 語言程式碼總結
- c語言踩坑總結C語言
- C 語言程式設計習慣總結程式設計
- ES6語言特性的總結(3)
- 鵬哥C語言初識課程總結C語言
- 關於c語言輸入字串的總結C語言字串
- c語言常用小知識點總結1C語言
- C語言指標總結大學霸IT達人C語言指標
- C語言教程——03 C語言結構C語言
- C語言知識彙總 | 00-C語言知識彙總目錄C語言
- c語言指標彙總C語言指標
- C語言小白記錄自己的錯題和總結C語言
- 全面總結: Golang 呼叫 C/C++,例子式教程GolangC++
- C語言-選擇結構C語言
- Go語言基礎語法總結Go
- C語言位運算子知識總結和例項分析C語言
- c語言基礎知識3C語言
- C語言結構體大小分析C語言結構體
- 結對程式設計(c語言)程式設計C語言
- C語言線性連結串列C語言
- C語言結構體專題C語言結構體
- C語言宣告知識體系總結大學霸IT達人C語言
- 、【C語言基礎】 第十天 | 知識點總結C語言
- C語言第7題:指標總結(兩張表格重點***)C語言指標
- yield全面總結
- 使用 Sublime Text 3 編譯 C 語言編譯
- 3- C語言編譯過程C語言編譯
- c語言字面值知識體系總結大學霸IT達人C語言
- C語言知識彙總 | 51-C語言字串指標(指向字串的指標)C語言字串指標
- C語言知識彙總 | 56-C語言NULL空指標以及void指標C語言Null指標
- C語言C語言
- 聊聊C語言/C++—程式和程式語言C語言C++
- 資料結構 順序棧(c語言)資料結構C語言
- C語言結構體作為形參C語言結構體
- C語言-->(十四)結構體、巨集、編譯C語言結構體編譯
- 資料結構雜湊表(c語言)資料結構C語言
- C語言結構聯合位欄位知識體系總結大學霸IT達人C語言
- C語言 typedefC語言