1.void*概述
void称为无类型,void*称为无类型指针,void不可以单独定义变量,却可以定义无类型的指针,而且所定义的指针称为泛型指针,所谓泛型指针,其含义是void*类型的指针可以接收一切类型变量的地址
struct Test {
int x;
char ch;
};
void fun() {
printf("this is a fun.\n");
}
int main() {
void* pv;
char ch = 'A';
pv = &ch;
int a = 10;
pv = &a;
double d = 12.34;
pv = &d;
struct Test t;
pv = &t;
int ar[10] = { 1,2,3,4,5,6,7,8,9,10 };
pv = &ar;
pv = &fun;
return 0;
}
注:如果需要使用void*指针,需要重新强转为具体类型才可以使用,不可直接针对void*进行使用,如:
void* pv;
char ch = 'A';
pv = &ch;
printf("%c\n", *(char*)pv);
malloc函数原型为:void* malloc(size_t size)
返回值为泛型指针,所以在使用malloc时需要对返回结果进行类型强转
struct Test t = (struct Test*)malloc(sizeof(struct Test));
pv = &t;
2.void*指针应用---通用函数
void* memcpy(void* dest, const void* src, size_t count)
//memcpy简易实现版,不考虑内存重叠问题
void* memcpy(void* dest, const void* src, size_t count) {
assert(dest != NULL && src != NULL);
char* pDest = (char*)dest;
const char* pSrc = (const char*)src;
while (count--)
*pDest++ = *pSrc++;
return dest;
}
内存泄漏检测工具:vld
strcpy和memcpy
char* str = (char*)"Hello String";
//char space[] = ""; //内存空间不足
char space[20] = ""
//strcpy(space, str);
memcpy(space,str,strlen(str)+1);
注:
1.char space[20];
memcpy(space,str,strlen(str))会出现乱码
输出:Hello String烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫?j(?
2.strlen不会将末尾的\0计入长度,而sizeof会将末尾的\0计入长度
memcpy是一个类型无关的函数,接受的参数为泛型,上面实现的memcpy函数当源字符串和目的字符串出现内存重叠时会发生错误
void* my_memcpy(void* dest, const void* src, size_t count) {
assert(dest != NULL && src != NULL);
char* pDest = (char*)dest;
const char* pSrc = (const char*)src;
//判断内存是否重叠
if (pSrc >= pDest || pDest >= (pSrc + count)) {
while (count != 0) {
//没有重叠,正向拷贝
*pDest++ = *pSrc++;
count--;
}
}
else {
//存在内存重叠,反向拷贝
pSrc = pSrc + count - 1;
pDest = pDest + count - 1;
while (count != 0) {
*pDest-- = *pSrc--;
count--;
}
}
return dest;
}
用冒泡排序模拟快排
cmp_函数可根据具体需求编写
int cmp_int(const void* e1, const void* e2) {
return *(int*)e1 - *(int*)e2;
}
int cmp_char(const void* e1, const void* e2) {
return *(char*)e1 - *(char*)e2;
}
int cmp_str(const void* e1, const void* e2) {
return strcmp(*(char**)e1, *(char**)e2);
}
void my_qsort(void* base, size_t num, size_t width,
int (*compare)(const void* elem1, const void* elem2)) {
for (int i = 0; i < num - 1; i++) {
for (int j = 0; j < num - 1 - i; j++) {
//默认升序
if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
测试
int main() {
int ar[] = { 6,3,7,9,8,2,1,4,5 };
int n = sizeof(ar) / sizeof(ar[0]);
my_qsort(ar, n, sizeof(int), cmp_int);
return 0;
}