在理解 void* 前,複習一下C的數據類型、void的用法、指針的用法。
數據類型
void 類型
在C語言中, void也是數據類型:不確定的類型。
void雖然是數據類型,但不能用來定義一個void變量, 如:void test=10; // 編譯時會報錯,
void類型,有3個作用 ;
- 限定函數返回值, 如: void GetTime(shot t); // 這裏的void表示:函數不能返回值
- 限定函數參數, 如:shot GetValue(void); // 這裏的void表示:函數不接受參數傳入
- 聲明無類型指針, 如:void* pStrint; // void *可以接受任何類型的賦值
指針 類型
每一次看到指針這個簡稱,必須想起它的大名:指針類型,這樣更容易理解。
- 指針類型,它和數組、結構體等是數據類型中的其中一個派生成員, ;
- 指針類型與其它數據類型的區別, 指針定義後在內存中佔4個字節, 這4個字節存儲的是某數據段的地址值, 而如int類型也佔的4字節, 但存儲的是直接的數據值;
- 指針的大小是4個字節,因爲STM32的內存地址是32位4字節. 在win的64位系統中, 指針是佔8個字節.
-
char* strTemp = “星期天有空嗎,一起去玩吧?"; // strTemp 的大小是4個字節,不管所指向的數據是什麼,有多大, 反正它只是負責某數據的地址。
- 指針用法
-
// 定義一個數組,在內存開闢一段空間,然後用指針指向它,方便做數據處理 char A[4096]; char* p=A; p++; // 等同於&A[1] *p++; // 等同於 A[1]+1 int Time = (int*)p; // 等同於 Time= A[4]<<24 | A[3]<<16 | A[2]<<8 | A[1] while(*p!=0) // 等同於 A[1]!=0 { ... } // 其實, 不用指針也可以完成上面的各種操作, 但用指針更簡潔
void* 作爲參數類型
void* 是一種無類型指針,任何類型指針都可以轉爲void*
,它無條件接受各種類型.
void* pTest; // 定義一個void指針
pTest++; // 錯誤; 因爲指針還不確定知道其指向數據類型大小,對它++無法確定要加多少個字節
if(*pTest==0); // 錯誤;
(char*)pTest++; // 正確
if(*((int*)pTest)==0); // 正確
void*基本用於函數、接口。
典型的,如內存操作函數 memcpy和 memset,函數原型分別爲:
void * memcpy(void *dest, const void *src,size_tlen);
void * memset ( void * buffer, int c, size_t num );
int TestINT[100]; // 傳入int類型數據
memset ( TestINT, 0, 100*sizeof(int) ); // 將TestINT清0,
char TestChar[50]; // 傳入char類型數據
memset(TestChar, 0, 50); // 將TestChar清0
void* 作爲返回類型
- void 作爲返回類型裏,作用是限定函數不能返回任何值。
- void* 作爲返回類型時, 作用是函數可以返回任何類型的值,可以是int,char, 也可以是struct;
void* SUM(char a, char b)
{
return a+b;
}
int main(void)
{
int V1 = SUM(1,2);
char V2 = SUM(1,2);
float V3 = SUM(1,2);
int* V4 = SUM(1,2);
}
特別注意
void* SUM(char A, char B); // 這裏是指函數可以返回任何類型的值
void (*SUM)(char A, char B); // 這個是函數指針,和void* 是完全沒一丁點關係聯繫的。