1. 函數指針(function pointer):html
函數指針是指向函數的指針變量。編程
一般咱們說的指針變量是指向一個整型、字符型或數組等變量,而函數指針是指向函數。數組
函數指針能夠像通常函數同樣,用於調用函數、傳遞參數。數據結構
函數指針變量的聲明:ide
typedef int (*fun_ptr)(int,int);函數
例子:https://www.runoob.com/cprogramming/c-fun-pointer-callback.htmlspa
sub:指針函數是返回指針的函數,詳見我上一篇文章。指針
2.回調函數(Callback function):code
函數指針變量能夠做爲某個函數的參數來使用的,回調函數就是一個經過函數指針調用的函數。htm
"
如下是來自知乎做者常溪玲的解說:
你到一個商店買東西,恰好你要的東西沒有貨,因而你在店員那裏留下了你的電話,過了幾天店裏有貨了,店員就打了你的電話,而後你接到電話後就到店裏去取了貨。在這個例子裏,你的電話號碼就叫回調函數,你把電話留給店員就叫登記回調函數,店裏後來有貨了叫作觸發了回調關聯的事件,店員給你打電話叫作調用回調函數,你到店裏去取貨叫作響應回調事件。
"
意思簡單來講就是:你如今定義的A函數的參數包含了一個你如今還不知道的B函數,因此你在參數中作了一個B函數指針以便引用這個B函數。 一旦引用的這個B函數被定義了,你就能夠在runtime使用你的A函數。
例子:https://www.runoob.com/cprogramming/c-fun-pointer-callback.html
sub:size_t 是一種數據類型,近似於無符號整型,但容量範圍通常大於 int 和 unsigned。這裏使用 size_t 是爲了保證 arraysize 變量可以有足夠大的容量來儲存可能大的數組.
3.字符串(string):
在 C 語言中,字符串其實是使用 null 字符 '\0' 終止的一維字符數組。所以,一個以 null 結尾的字符串,包含了組成字符串的字符。
下面的聲明和初始化建立了一個 "Hello" 字符串。因爲在數組的末尾存儲了空字符,因此字符數組的大小比單詞 "Hello" 的字符數多一個。
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; (通常正常人不會用這種)(不須要把 null 字符放在字符串常量的末尾。C 編譯器會在初始化數組時,自動把 '\0' 放在字符串的末尾。)
char greeting[] = "Hello"; (比較通用,和其餘語言很像,注意「[ ]」,由於C裏面string是char的array。)
常見操做:
strcpy(s1, s2); 複製字符串 s2 到字符串 s1。
strcat(s1, s2); 鏈接字符串 s2。
strlen(s1); 返回字符串 s1 的長度。
strcmp(s1, s2); 若是 s1 和 s2 是相同的,則返回 0;若是 s1<s2 則返回小於 0;若是 s1>s2 則返回大於 0。
strchr(s1, ch); 返回一個指針,指向字符串 s1 中字符 ch 的第一次出現的位置。
strstr(s1, s2); 返回一個指針,指向字符串 s1 中字符串 s2 的第一次出現的位置。
sub:
strlen 與 sizeof的區別:
strlen 是函數,sizeof 是運算操做符,兩者獲得的結果類型爲 size_t,即 unsigned int 類型。
sizeof 計算的是變量的大小,不受字符 \0 影響;
而 strlen 計算的是字符串的長度,以 \0 做爲長度斷定依據。
4.結構體(struct):
a.定義:
C 數組容許定義可存儲相同類型數據項的變量,結構是 C 編程中另外一種用戶自定義的可用的數據類型,它容許您存儲不一樣類型的數據項。
假設咱們有一個電子圖書館,咱們能夠用結構體來定義一本書及其屬性: 1.標題 2.做者。。。之類。
爲了定義結構,您必須使用 struct 語句。struct 語句定義了一個包含多個成員的新的數據類型,struct 語句的格式以下:
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
}book;
在通常狀況下,tag 、member-list、variable-list 這 3 部分(對應代碼裏面的Books, char title[50]; , book)至少要出現 2 個。
sub :
1.不一樣的定義方式產生的結構體能夠被視爲不一樣的類型,沒法相等(無論成員是否是同樣).
2.結構體的成員能夠包含其餘結構體,也能夠包含指向本身結構體類型的指針,而一般這種指針的應用是爲了實現一些更高級的數據結構如鏈表和樹等。
3.能夠在定義的時候初始化,跟變量同樣。
詳見:https://www.runoob.com/cprogramming/c-structures.html
b. 結構訪問還有使用:
爲了訪問結構的成員,咱們使用成員訪問運算符(.)。成員訪問運算符是結構變量名稱和咱們要訪問的結構成員之間的一個句號。您可使用 struct 關鍵字來定義結構類型的變量。
好比 你要訪問 Book1 的title --- Book1.title (若是學過面對對象編程的朋友估計感受很眼熟)
c.結構做爲函數參數:
您能夠把結構做爲函數參數,傳參方式與其餘類型的變量或指針相似。您可使用上面實例中的方式來訪問結構變量:
void printBook( struct Books book ){
。。。
。。。
。。。
}
d.指向結構的指針:
struct Books *struct_pointer; 定義
struct_pointer = &Book1; 結構變量的地址
struct_pointer->title; 指向該結構的指針訪問結構的成員
e.位域:
有些信息在存儲時,並不須要佔用一個完整的字節,而只需佔幾個或一個二進制位。例如在存放一個開關量時,只有 0 和 1 兩種狀態,用 1 位二進位便可。爲了節省存儲空間,並使處理簡便,C 語言又提供了一種數據結構,稱爲"位域"或"位段"。
所謂"位域"是把一個字節中的二進位劃分爲幾個不一樣的區域,並說明每一個區域的位數。每一個域有一個域名,容許在程序中按域名進行操做。這樣就能夠把幾個不一樣的對象用一個字節的二進制位域來表示。
位域和結構體的定義基本上差很少,只不過須要多加 位域長度 。
struct bs{
int a:8;
int b:2;
int c:6;
}data;
說明 data 爲 bs 變量,共佔兩個字節。其中位域 a 佔 8 位,位域 b 佔 2 位,位域 c 佔 6 位。
使用時這兩種均可以:1. data.a 2. data->a
sub:
1.一個位域存儲在同一個字節中,如一個字節所剩空間不夠存放另外一位域時,則會從下一單元起存放該位域。也能夠有意使某位域從下一單元開始。
2.因爲位域不容許跨兩個字節,所以位域的長度不能大於一個字節的長度,也就是說不能超過8位二進位。若是最大長度大於計算機的整數字長,一些編譯器可能會容許域的內存重疊,另一些編譯器可能會把大於一個域的部分存儲在下一個字中。
3.位域能夠是無名位域,這時它只用來做填充或調整位置。無名的位域是不能使用的.
4.位域在本質上就是一種結構類型,不過其成員是按二進位分配的。
5.結構體變量的首地址可以被其最寬基本類型成員的大小所整除。
6.結構體每一個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,若有須要編譯器會在成員之間加上填充字節(internal adding)。即結構體成員的末地址減去結構體首地址(第一個結構體成員的首地址)獲得的偏移量都要是對應成員大小的整數倍。