(一)基本概念
void 類型:空類型,用於特殊目的的沒有操作,也沒有值的類型。不能被顯式或隱式的轉換為任意非空類型,可以通過強制類型轉換為void類型。
void指針:指向任何對象的指針都可以轉換為void*類型指針,且不會丟失信息。在ANSI C使用類型void*代替char*作為通用指針的類型。
(二)使用方法
1. void的使用
第一種是:對函數返回的限定
在不加返回值類型限定的情況之下,編譯器會將其處理為整型的類型。例如以下的情況:
#include <stdio.h>
// 參考了別人寫void的例子,但是這個例子十分形象
// 的表明了不加返回類型值限定時,編譯器的處理規則。
add (int a, int b)
{
return a + b;
}
int main(int argc, char* argv[])
{
printf("2 + 3 = %d", add (2, 3));
return 0;
}
對於每個函數,我們都要明確的指定其返回值的類型。該void的時候,就void。不要省略不寫,這回帶來大麻煩
。
第二種:對函數參數的限定
當函數不允許接受參數時,必須使用void限定。例如以下兩種情況:
在C語言下:
#include <stdio.h>
// 以下兩個函數都可以進行正常的編譯,不會報錯。
// C的容忍度還是很大的。。。
int func()
{
return 1;
}
int func1(void)
{
return 1;
}
int main(int argc, char* argv[])
{
printf("%d\n", func(2));
printf("%d\n", func1(2));
return 0;
}
運行結果:
在C++語言下:
#include <iostream>
int func()
{
return 1;
}
int func1(void)
{
return 1;
}
int main(int argc, char* argv[])
{
std::cout << func(1) << std::endl;
std::cout << func1(1) << std::endl;
return 0;
}
運行結果:
在C語言中,可以給無參數的函數傳送任意類型的參數,但是在C++編譯器中編譯同樣的代碼則會出錯。
在C++中,不能向無參數的函數傳送任何參數。
2. void指針的使用
在《C++ primer》中,對void指針的作用做了闡述:與另一指針比較;向函數傳遞void指針或從函數返回void指針;給void指針賦值。
由於void指針可以指向任意類型的數據,亦即可用任意數據類型的指針對void指針賦值,因此還可以用void指針來作為函數形參,這樣函數就可以接受任意數據類型的指針作為參數。
以下摘至sgi stl中的代碼片段:
/* __n must be > 0 */
static void* allocate(size_t __n)
{
void* __ret = 0;
if (__n > (size_t) _MAX_BYTES) {
__ret = malloc_alloc::allocate(__n);
}
else {
_Obj* __STL_VOLATILE* __my_free_list
= _S_free_list + _S_freelist_index(__n);
// Acquire the lock here with a constructor call.
// This ensures that it is released in exit or during stack
// unwinding.
ifndef _NOTHREADS
/*REFERENCED*/
_Lock __lock_instance;
endif
_Obj* __RESTRICT __result = *__my_free_list;
if (__result == 0)
__ret = _S_refill(_S_round_up(__n));
else {
*__my_free_list = __result -> _M_free_list_link;
__ret = __result;
}
}
return __ret;
}
/* __p may not be 0 */
static void deallocate(void* __p, size_t __n)
{
if (__n > (size_t) _MAX_BYTES)
malloc_alloc::deallocate(__p, __n);
else {
_Obj* __STL_VOLATILE* __my_free_list
= _S_free_list + _S_freelist_index(__n);
_Obj* __q = (_Obj*)__p;
// acquire lock
ifndef _NOTHREADS
/*REFERENCED*/
_Lock __lock_instance;
endif /* _NOTHREADS */
__q -> _M_free_list_link = *__my_free_list;
*__my_free_list = __q;
// lock is released here
}
}
對於指針的自增行為,要迎合ANSI C 的規范。在ANSI C中void指針不能自增的,這種行為是一種非法行為,因為未知void的大小。
#include <iostream>
int main(int argc, char* argv[])
{
int i = 0;
void *p;
int *pint;
int *pint1;
pint = &i;
p = pint;
std::cout << pint << std::endl;
pint++;
std::cout << pint << std::endl;
std::cout << p << std::endl;
pint1 = (int *)p;
std::cout << pint1 << std::endl;
return 0;
}
運行的結果:
文獻參考:
1. 《C++ primer》和《C語言程序設計》
2.http://wenku.baidu.com/view/22c4b8d86f1aff00bed51edc.html這篇文章很出名啊,很多void的文章都是轉載這一篇文章的。