void的詳解:
void的字面意思是“無類型”或“空類型”,void*則為“無針型指針”,那就意味著void*可以指向任何類型的數據。
眾所周知,如果指針p1和p2的類型相同,那么我們可以直接在p1和p2間互相賦值,不會出現問題;但如果p1和p2指向不同的數據類
型,則必須使用強制類型轉換
運算符把賦值符號兩邊的類型轉換為相同類型或兼容的類型,即就是把賦值運算符右邊的指針類型轉換為左邊指針的類型。
例如:
float *p1;
int *p2;
p1 = p2;
其中p1= p2語句會編譯出現警告
In function ‘main’:
15:7: warning:assignment from incompatible pointer type [enabled by default]
提示我們第十五行的賦值類型不兼容
而改成p1= (float *)p2;才正確;
而void*則不同,任何類型的指針都可以直接賦值給它,無需進行強制類型轉換:
void*p1;
int *p2;
p1 = p2;
但這并不意味著,void*也可以無需強制類型轉換地賦給其它類型的指針。因為“無類型”可以包容“有類型”,而“有類型”則不能包容“無類型”。道理很簡
單,我們可以說“男人和女人都是人”,但不能說“人是男人”或者“人是女人”。
下面的語句編譯出錯或警告:
void *p1;
int *p2;
p2 = p1;
在C語言中,凡不加返回值類型限定的函數,就會被編譯器作為返回整型值處理。但是許多人卻誤以為其為void類型。例如:
add ( int a, int b )
{
return a + b;
}
int main(int argc,char* argv[])
{
printf ( "2 + 3= %d", add ( 2, 3) );
}
程序運行的結果為輸出:
2 + 3 = 5
這說明不加返回值說明的函數的確為int函數。
NULL詳解:
運行:
#include<stdo.h>
int main()
{
int *p=NULL;
printf("%s",p);
}
輸出:(null)
gdb調試可以看出執行int*p=NULL,p的值為0x00000000,可以看出,NULL在實際底層調用中就是0。
而NULL在C語言的stdio.h頭文件里面的定義為:
#if!defined(NULL) && defined(__NEEDS_NULL)
#ifdef__cplusplus
#defineNULL 0
#else
#defineNULL ((void *)0)
#endif
#endif
由此可見,在C語言中,NULL和0的值可以說是一樣的,但是為了不同目的和用途及容易識別的原因,NULL用于指針和對象中,0用
于數值
對于字符串的結尾,使用'\0',它的值也是0,但是讓人一看就知道這是字符串的結尾,不是指針,也不是普通的數值。在不同的系統
中,NULL并非總是和0等
同,NULL僅僅代表空值,也就是指向一個不被使用的地址,在大多數系統中,都將0作為不被使用的地址,所以就有了類似這樣的
定義
#defineNULL 0
但并非總是如此,也有些系統不將0地址作為NULL,而是用其他的地址。
|