void 类型指针
void => 空类型
void* => 空类型指针,只存储地址的值,丢失类型,无法访问,要访问其值,我们必须对这个指 针做出正确的类型转换,然后再间接引用指针。
所有其它类型的指针都可以隐式自动转换成 void 类型指针,反之需要强制转换
#include <stdio.h>
#include <stdlib.h>
int main() {
int arr[] = {1 , 2, 3, 4, 5};
char ch = 'a';
//定义了一个void 类型的指针
void *p = arr;
//p++; 不可以, void* 指针不允许进行算术运算
//其他类型可以自动转换成void* 指针
p = &ch;
//printf("数组第一个元素: %d\n", *p); //不可以进行访问
printf("p: 0x%p ch: 0x%p\n", p, &ch);
//强制类型转化
char * p1 = (char *)p;
printf("p1 The character is: %c\n", *p1);
return 0;
}
运行结果:
函数指针
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare_int(const void *a, const void *b){
//printf("调用compare_int 啦,你好骚气哦! \n");
int *a1 = (int *) a;
int *b1 = (int *) b;
//printf("a 的地址: 0x%p b的地址: 0x%p\n", &a, &b);
return *b1 - *a1;
}
int compare_char(const void *a, const void *b){
//printf("调用compare_char 啦,你好骚气哦! \n");
char c1 = *((char *) a);
char c2 = *((char *) b);
if(c1>='A' && c1<='Z') c1+=32;
if(c2>='A' && c2<='Z') c1+=32;
return c1 - c2;
}
int main(void){
int x = 10;
int y = 20;
//函数有没有地址?
//printf("compare_int 的地址: 0x%p \n", &compare_int);
//compare_int(&x, &y);
//函数指针的定义 把函数声明移过来,把函数名改成 (* 函数指针名)
int (*fp)(const void *, const void *);
/*贝尔实验室的C和UNIX的开发者采用第1种形式,而伯克利的UNIX推广者却采用第2
种形式ANSI C 兼容了两种方式*/
fp = &compare_int; //
(*fp)(&x, &y); //第1种,按普通指针解引的放式进行调用,(*fp) 等同于compare_int
fp(&x, &y); //第2种 直接调用
//qsort 对整形数组排序
int arr[]={2, 10, 30, 1, 11, 8, 7, 111, 520};
qsort(arr, sizeof(arr)/sizeof(int), sizeof(int), &compare_int);
for(int i=0; i<sizeof(arr)/sizeof(int); i++){
printf(" %d", arr[i]);
}
//qsort 可以对任何类型的数组进行排序
char arr1[]={"abcdefghiABCDEFGHI"};
qsort(arr1, sizeof(arr1)/sizeof(char)-1, sizeof(char), &compare_char);
for(int i=0; i<sizeof(arr1)/sizeof(char)-1; i++){
printf(" %c", arr1[i]);
}
printf("\n");
return 0;
}
运行结果: