1.函數編程
有時程序中要屢次實現某一功能,就須要屢次重複編寫實現此功能的代碼,這使程序不精練。所以須要模塊化程序設計的思想。數組
函數的返回值要匹配,若函數有返回值能夠不接受,可是函數沒有返回值不能接受。模塊化
傳參時實參要與形參匹配。函數
函數必須先定義才能使用。設計
若函數申明瞭以後沒有實現,編譯過程當中不會出現錯誤,但連接運行時會出錯。指針
形參與實參地址不一樣當值傳遞時,函數形參發生改變,但實參沒有改變。內存
2.數組字符串
三值合一:io
ar訪問的是數組名的值,而這個值剛好是首元素的地址。編譯
&ar[0]對數組首元素求地址
&ar是求整個數組空間的地址(剛好是首元素的地址)
多維數組均可以轉化爲一維數組。
二維數組初始化時行能夠缺省,但列不能夠缺省。
訪問地址獲得值只對字符數組成立,對其餘數組的訪問都只能獲得地址
注意\0和字符數組越界的問題。
數組的大小用sizeof,數組的實際大小用strlen
雙引號存的是字符串(系統默認加\0),單引號存單個字符
數組訪問的底層是指針形式的訪問
數組名做爲形參退化爲指針(只針對一維數組)
3.字符串
字符指針存放的是地址,字符串常量保存在靜態常量區值不能改變,字符數組存放的是若干個元素,字符是變量,能夠進行賦值改變
指針能夠對指針賦值,但數組名不能夠對數組名賦值。
4.數組指針與指針數組 函數指針和指針函數
(*ar)[10] //數組指針,指向數組的指針,強調的是指針
*ar[10] //指針數組,存儲指針的數組,強調的是數組
(*ar)() //函數指針,指向函數的指針,強調的是指針
*ar() //指針函數,返回指針的函數,強調的是函數
5.C之動態內存分配與釋放
全局變量是分配在內存中的靜態存儲區的,非靜態的局部變量是分配在內存中的動態存儲區稱爲棧。
動態內存分配區域稱爲堆區,存放臨時數據,這些數據沒必要在程序的聲明部分定義,也沒必要等到函數結束後才釋放,而是根據須要隨時開闢隨時釋放。因爲未在聲明部分定義他們的變量或數組,所以不能經過變量名或者數組名去引用這些數據,只能經過指針來引用。
在編程時,大概把內存分爲三個區域:
棧區:局部變量,在程序裏面定義的
堆區:malloc calloc realloc函數開闢的,必須手動釋放,不然會形成內存泄漏
靜態常量區:靜態變量,全局變量 只要主程序結束,生成在其中的變量就撤銷
不能夠定義void類型的變量,但能夠定義void 類型的指針,void類型的指針能夠接收一切類型的指針,想要把void型指針向真實類型轉換,則必須進行強制類型轉換
6.自定義類型
C之自定義類型:struct結構體,union聯合體,enum枚舉
7。指針
指針的本質就是相應類型的地址
區分:const int* p,int const* p,int *const p和const int* const p
const int* p和int const* p代表了p所指向的值不能改變。int *const p表示p的值不能改變。而const int* const p 表示p和p所指向的值都不能改變。
指針兩值的四個方面:
指針的類型:只要把指針聲明語句裏面指針名字去掉,剩下的部分就是這個指針的名字
指針所指向的類型:把*去掉,再把名字去掉,剩下的內容就是這個指針所指向的類型
指針的值(指針所指向的內存區):
指針自己所具備的內存區:32位系統佔四個字節
當函數用數組作參數的時候數組就會退化爲指針。
8.C之字節對齊
字節對齊是用空間換時間。
字節對齊的四個概念:
1.基本數據類型的自身對齊值
2.程序指定的對齊值(#pragma pack(value)時的對齊值value)
3.自定義類型的自身對齊值(即結構體或類的成員自身對齊的最大值)
4.自定義類型的有效對齊值
自定義類型的自身對齊值和指定對其中較小的值
空結構體佔一個字節的空間
當結構體數據類型相同時,則所佔空間爲元素自身類型空間之和
當結構體數據類型不一樣時的處理方法:
1.先列出其自身大小
2.往下看,下面數據的大小是上面數據的整數倍
3.自定義類型的對齊值
即結構體或類的成員自身對齊的最大值(按照成員的由小到大能節省空間)
用#pragma pack(value)指定對齊值
自定義類型的自身對齊值和指定對其中較小的值
結構體裏套上結構體的狀況
要是按一字節對齊,則只需將全部類型的大小加在一塊兒。
當結構體中有數組時,跟數組無關,只跟數組的類型值有關
先看內存嵌套的結構體,按照上面的規則進行對齊
若強制字節對齊,則裏外都按照value值對齊
當結構體有名字時,就升級爲一個類型,類型不佔空間;若產生一個結構體變量,空間存在。
結構體的位域:
從比特位的角度出發
位域是不能跨字節存儲的,也不能誇類型存儲的
位域的大小不能超過自身類型的大小