面試題-指標-void*通用指標
問題:
問:函式中的void和指標中的void*有什麼區別?
答:在函式中的void是表示無型別或無返回型別。void指標是通用指標,用來存放任何資料型別的引用。
分析:
void真正發揮的作用在於:
1.對函式返回的限定。
2.對函式引數的限定。
<函式
返回值> <函式名>(引數1,引數2,引數3,.......){內容;}
------------
int sum(int a,int b)
{
int c;
return c;}
其中第一個int是返回值 就是別的函式呼叫此函式時這個函式給他的一個值。
1.如果呼叫時不需要返回值,則函式寫為void sum(int a,int b){....},此時函式沒有返回值。
如果不需要引數,則int sum(void){...}《或者int sum(){...}》,此時void的意義為空,就是沒有引數的意思。
3.如果都不要,則為void sum(void);《或者void sum();》
4.main()
{
return 0;//需要返回值,而且為int型。是因為該函式隱含是返回的是整型型別的。但是在c++上安全檢查嚴格不允許沒有int,但是在vc6.0當中,編譯器是會通過的。
}
void的作用:
1.對函式返回的限定,當函式不需要返回值時,用void限定,如void fun();
2.對函式的引數的限定,當函式不需要接受引數時,用void限定,如int fun(void)
void指標的作用:
1.函式返回值是任意型別的指標,如void *fun();
2.定義函式指標pfun,如void(*pfun)(),如果該函式指標指向這類函式(即void函式),例如:
void fun()//這類函式
{
}
void main()
{
void(*pfun)();
pfun = fun; //指向某個函式
pfun();//呼叫方法1
(*pfun)(); //呼叫方法2
}
3.void指標不能復引用,也就是不能取得它指向的地址的內容。
void *pvoid;
int *pint;
printf("%d",*pint);//正確
printf("%d", *pvoid);//錯誤
由於pint是整型變數指標,解引用取得該指向地址的內容是整型的,知道從第一位元組到第四個位元組的記憶體,而且從低到高儲存整數的32補碼。
而pvoid是指向還不知道資料型別的地址的通用指標,復引用取得的內容不清楚是什麼資料型別,內容佔用的記憶體多大都不清楚。
擴充套件知識:double資料型別復引用是從第一位元組到第八位元組的一塊記憶體,從低到高儲存double數的浮點數符號位、階符、階碼和尾數。
-------------------------------------------------------------------------------------------------------------------------------------
問題:
問:下面程式碼中哪個地方是錯誤的?
#include<iostream>
using namespace std;
void main()
{
void *pvoid=NULL;
int *pint;
int m = 2;
pint = &m;
cout << pint << endl;
cout << pvoid << endl;
pvoid = pint;
pint = pvoid;
cout << pint << endl;
cout << pvoid << endl;
}
答:
#include<iostream>
using namespace std;
void main()
{
void *pvoid=NULL;
int *pint;
int m = 2;
pint = &m;
cout << pint << endl;
cout << pvoid << endl;
pvoid = pint;
pint = (int *)pvoid;//pint=pvoid錯誤,賦值給pint,pvoid需要強制轉換成int型別的。
cout << pint << endl;
cout << pvoid << endl;
}
-------------------------------------------------------------------------------------------------------------------------------------
問題:
問:關於通用指標與解引用的解決問題,以下程式碼哪些語句是錯誤的?
void main()
{
int i=100;
void *p=&i;
*p=0;
//----
int a=100;
void *p2=&a;
*(int*)p2=0;
cout<<a<<endl;
}
答:由於通用指標可以存放任意資料型別的地址,而編譯器無法確定該指標指向記憶體地址中的原始資料型別,因此通用指標無法解引用。
void main()
{
int i=100;
void *p=&i;
*p=0;//錯誤,通用指標不能解引用
//----
int a=100;
void *p2=&a;
*(int*)p2=0;//正確,由於通過強制轉換來指定資料型別,就可以實現解引用
cout<<a<<endl;
}