void 指標的使用

2021-10-11 02:02:18 字數 3094 閱讀 5829

指標有兩個屬性:1)指向變數;2)物件的位址和長度,但是指標只儲存位址,長度則取決於指標的型別;編譯器根據指標的型別從指標指向的位址向後定址,指標型別不同則定址範圍也不同,比如:

int*從指定位址向後尋找4位元組作為變數的儲存單元

double*從指定位址向後尋找8位元組作為變數的儲存單元

void即「無型別」,void *則為「無型別指標」,可以指向任何資料型別。

1)       對函式返回的限定

a)  當函式不需要返回值時,必須使用void限定。例如: void func(int, int);

2)       對函式引數的限定

a)  當函式不允許接受引數時,必須使用void限定。例如: int func(void)。

2.1   void指標可以指向任意型別的資料,即可用任意資料型別的指針對void指標賦值。例如

int *pint;

void *pvoid; //它沒有型別,或者說這個型別不能判斷出指向物件的長度

pvoid = pint; //只獲得變數/物件位址而不獲得大小,但是不能 pint =pvoid;

2.2   如果要將pvoid賦給其他型別指標,則需要強制型別轉換如:

pint = (int *)pvoid;  //轉換型別也就是獲得指向變數/物件大小

**

2.3   void指標不能復引用(即取內容的意思)

*pvoid         //錯誤

要想複引用乙個指標,或者使用「->」運算子復引用一部分,都要有對於指標指向的記憶體的解釋規則。

例如,int *p;

那麼,當你後面影印用p的時候,編譯器就會把從p指向的位址開始的四個位元組看作乙個整數的補碼。

因為void指標只知道指向變數/物件的起始位址,而不知道指向變數/物件的大小(佔幾個位元組)所以無法正確引用

2.4   void指標型別運算

按照ansi(americannationalstandardsinstitute)標準,不能對void指標進行演算法操作,即下列操作都是不合法的:

void* pvoid;

pvoid++;             //ansi:錯誤

pvoid+=1;           //ansi:錯誤

ansi標準之所以這樣認定,是因為它堅持:進行演算法操作的指標必須是確定知道其指向資料型別大小的。

//例如:

int*pint;

pint++;                //ansi:正確

pint++的結果是使其增大sizeof(int)。

但是大名鼎鼎的gnu(gnu'snotunix的縮寫)則不這麼認定,它指定void*的演算法操作與char*一致。

因此下列語句在gnu編譯器中皆正確:

pvoid++;             //gnu:正確

pvoid+=1;           //gnu:正確

pvoid++的執行結果是其增大了1。

在實際的程式設計中,為迎合ansi標準,並提高程式的可移植性,我們可以這樣編寫實現同樣功能的**:

void*pvoid;

(char*)pvoid++;               //ansi:正確;gnu:正確

(char*)pvoid+=1;             //ansi:錯誤;gnu:正確

gnu和ansi還有一些區別,總體而言,gnu較ansi更「開放」,提供了對更多語法的支援。但是我們在真實設計時,還是應該盡可能地迎合ansi標準。

2.5   如果函式的引數可以是任意型別指標,那麼應宣告其引數為void*。

典型的如記憶體操作函式memcpy和memset的函式原型分別為:

void*memcpy(void*dest,constvoid*src,size_tlen);

void*memset(void*buffer,intc,size_tnum);

這樣,任何型別的指標都可以傳入memcpy和memset中,這也真實地體現了記憶體操作函式的意義,因為它操作的物件僅僅是一片記憶體,而不論這片記憶體是什麼型別。如果 memcpy和memset的引數型別不是void*,而是char*,那才叫真的奇怪了!這樣的memcpy和memset明顯不是乙個「純粹的,脫離低階趣味的」函式!

下面的**執行正確:

//示例:memset接受任意型別指標

int  intarray[100];

memset(intarray,0,100*sizeof(int));             //將intarray清0

//示例:memcpy接受任意型別指標

int  intarray1[100],  intarray2[100];

memcpy(intarray1,intarray2,100*sizeof(int));//將intarray2拷貝給intarray1

有趣的是,memcpy和memset函式返回的也是void*型別,標準庫函式的編寫者是多麼地富有學問啊!

2.6   void不能代表乙個真實的變數

下面**都企圖讓void代表乙個真實的變數,因此都是錯誤的**:

void a;                              //錯誤

function(void a);                     //錯誤

void指標的使用

整理網路資源 在 c語言中在任何時候都可以用 void 型別的指標來代替其他型別的指標,void 指標可以指向任何資料型別的變數 如果要通過 void 指標去獲取它所指向的變數值時候,需要先將 void 指標強制型別轉換成和變數名型別想匹配的資料型別指標後再進行操作 指標的強類型別轉化 void p...

void指標 void 的用法

指標有兩個屬性 指向變數 物件的位址和長度 但是指標只儲存位址,長度則取決於指標的型別 編譯器根據指標的型別從指標指向的位址向後定址 指標型別不同則定址範圍也不同,比如 int 從指定位址向後尋找4位元組作為變數的儲存單元 double 從指定位址向後尋找8位元組作為變數的儲存單元 1.void指標...

void指標 void 的用法

指標有兩個屬性 指向變數 物件的位址和長度 但是指標只儲存位址,長度則取決於指標的型別 編譯器根據指標的型別從指標指向的位址向後定址 指標型別不同則定址範圍也不同,比如 int 從指定位址向後尋找4位元組作為變數的儲存單元 double 從指定位址向後尋找8位元組作為變數的儲存單元 1.void指標...