void 的使用方法簡介
void的含義
void 意思就是「無型別」,而void *表示「無型別指標」,可以指向任何型別的資料。主要用途分兩種:
一、對函式返回的限定。
eg:
a) 修飾函式時,表示函式無返回值
void fun(unsigned
char a,unsigned
char b) // 這裡的void就是限定fun無須返回值
b) 修飾指標函式,表示函式返回的是void型的指標。
void *fun(void)
{ void *p = null;
p = malloc(sizeof(int));
if(p!=null)
return p;
}// 引用
int *q = (int*)fun();
int * func(void)
{ int a= 10;
int *p = &a;
return p;
}
二、對函式引數的限定。
我們知道有型別的指標p1和p2,在型別相同情況下,是可以互相賦值的,如果型別不同,則必須強制轉換成一樣的方可以轉換。
eg1:
int *p1 = 「abc」, *p2;
p2 = p1; // 這是可以賦值的。
eg2:
int *p1 = 「abc」 ;
char *p2;
p2 = (char *)p1; // 必須轉換後才可以賦值
但是void *則不同,任何型別的指標都可以直接賦值給它,無需進行強制型別轉換:
void *p1;
int *p2;
p1 = p2;
正是因為這個特點,很多函式在不清楚引數輸入的指標型別的情形下,使用void來修飾引數。
如我們最常用的庫函式:
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
這兩個函式的引數都是void*型,任何型別的指標都可以傳入memcpy和memset中,這也真實地體現了記憶體操作函式的意義,因為它操作的物件僅僅是一片記憶體,而不 論這片記憶體是什麼型別。
特別注意:
1. void型指標沒有經過轉換,不能直接賦給有型別的指標。
eg1:
void *p1;
int *p2;
p2 = p1; // 因為p1為無型別,不能直接這樣賦值。
正確做法:
p2 = (int*)p1;
2.void 型指標必須轉換成有型別的指標後才能進行正常操作。
eg1:
void *p1;
int *p2 = 「abc」;
p1 = p2;
p1++; // 這是錯誤的
正確做法:
char *p3;
p3 = (char *)p1;
p3++;
不能用void直接宣告引數。 如void a; 這是錯誤的做法。
最後我們欣賞一下memcpy的原函式,這是用void比較多的函式:
void* memcpy(void*destaddr,voidconst*srcaddr,size_tlen)
return destaddr;
}
用void *來修飾memcpy,表明是乙個指標函式,返回的函式型別時void指標。
用void*和voidconst* 修飾引數,表示任何型別的指標都可以傳入其中。
char* dest=destaddr; char const* src=srcaddr;表示要對void型別指標指向的位址操作,必須先進行型別轉換。
gdb debug 使用方法簡介
編譯時必須加上引數 g 例 g g temp.cpp o temp.通過gcc編譯生成可執行檔案才能用gdb進行除錯。進入gdb介面 gdb temp.提示符變成 gdb 1 檢視檔案 在gdb中鍵入 l list 就可以檢視所載入的檔案 2 設定斷點 只需在 b 後加入對應的行號即可 這是最常用的...
gdb使用方法簡介
編譯時必須加上引數 g 例 g g temp.cpp o temp.通過gcc編譯生成可執行檔案才能用gdb進行除錯。進入gdb介面 gdb temp.提示符變成 gdb 1 檢視檔案 在gdb中鍵入 l list 就可以檢視所載入的檔案 2 設定斷點 只需在 b 後加入對應的行號即可 這是最常用的...
gdb使用方法簡介
編譯時必須加上引數 g 例 g g temp.cpp o temp.通過gcc編譯生成可執行檔案才能用gdb進行除錯。進入gdb介面 gdb temp.提示符變成 gdb 1 檢視檔案 在gdb中鍵入 l list 就可以檢視所載入的檔案 2 設定斷點 只需在 b 後加入對應的行號即可 這是最常用的...