Void Pointer —( void *)
跟上一章一樣,我們繼續停留在指標的行列。由於我找不到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交換即可。
今天這章結就到這裡,有些複雜還請各位讀者多多指教。若有新的想法也歡迎多多提出。