Void Pointer —( void *)

Sharon Peng
4 min readAug 28, 2019

--

跟上一章一樣,我們繼續停留在指標的行列。由於我找不到void pointer的中文,所以就用英文來代替了。

void pointer是什麼呢?

就是可以回傳任何型態的值,也就是說,我們在一開始宣告指標時,還不需要知道這個指標的特定型態(可以是int, float, double….),我覺得他比較像是回傳值的不同而不是另一種新型態的指標。

#include <stdio.h>int main()
{
int x = 33;
float y = 12.4;
char c = 'a';
void *ptr; // 宣告void pointer(沒有特定型態)

ptr = &x; //可以變成int
printf("void ptr points to %d\n", *((int *)ptr));
ptr = &y; //可以變成float
printf("void ptr points to %f\n", *((float *)ptr));
ptr = &c; //可以變成char
printf("void ptr points to %c", *((char *)ptr));
return 0;
}

當我們要間接取得指標內的值時,我們需要先資料型態轉換成相對應的型態,再使用*符號。

*(*int)ptr:現把void pointer轉換成int指標,再用*取記憶體 ptr中的值。

函式與void pointer的應用:

宣告:

void * 名稱(const void *);

因為我們知道void pointer,可以回傳任何型態的值,同樣的,裡面的參數也可以是void *型態,如果想要變數型態不變的話,可以加上const。

#include <stdio.h>

void* square (const void* num); //宣告平方函式

int main()
{
int x, sq_int;
x = 6;
sq_int = square(&x); //回傳值是int型態
printf("%d squared is %d\n", x, sq_int);

return 0;
}

void* square (const void *num)
{
int result;
result = (*(int *)num) * (*(int *)num);
return result;
}

指標函式成為參數:

以qsort來舉例(在stdlib.h函式庫中)

void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *) )

拆解參數

void * base : void pointer的陣列

size_t num : 陣列內的元素數量

size_t width: 陣列元素的型態大小(int:4 char: 4…)

int (*compare)(const void *, const void *): 比較兩個參數,

elem1 = elem2 回傳 0

elem1 > elem2 回傳 1

elem1 < elem2 回傳 -1

範例程式:

#include <stdio.h>
#include <stdlib.h>

int compare (const void *, const void *);

int main()
{
int arr[5] = {52, 23, 56, 19, 4};
int num, width, i;

num = sizeof(arr)/sizeof(arr[0]);
width = sizeof(arr[0]); //int 的大小
qsort((void *)arr, num, width, compare);
for (i = 0; i < 5; i++)
printf("%d ", arr[ i ]);

return 0;
}

int compare (const void *elem1, const void *elem2)
{
if ((*(int *)elem1) == (*(int *)elem2))
return 0;
else if ((*(int *)elem1) < (*(int *)elem2))
return -1;
else
return 1;
}

sizeof(arr) / sizeof(arr[0]):(這邊的大小代表資料型態佔記憶體位址的大小)

整個陣列的大小(5*4(20))/第一個數列的大小(4) = 5(總共五個元素)

上方程式碼排序方式由小到大,想要大到小的話,把其中的-1, 1交換即可。

今天這章結就到這裡,有些複雜還請各位讀者多多指教。若有新的想法也歡迎多多提出。

--

--