对于void* 的理解

本文详细解析了void*指针的特性和用法,包括其作为无类型指针的意义、如何在函数参数中使用以及实际编程中的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void* 是一个特殊的指针,它的意义为无类型指针,他可以被赋值为任意类型的指针,但是仅限当作一个指针使用。

void* 是不能直接被 * 访问地址的内容,因为还不知道具体要读多少个字节;而且void* 不能参与指针运算,比如

void func(void* array){
    printf("%d\n",array[0]);
}

这段代码通不过编译,会提示void类型不能被当作完整的类型来处理。因为array[i]的访问其实是 array+ i*sizeof(array),但是void类型属于无类型,它的sizeof的值应该是不能被编译器接受,所以编译器拿不到sizeof的值就访问不了。

【事实上输出void的sizeof()值为1】

所以void*的使用必须得先为他分配一个类型。

void* 作为变量使用:

    int b;
    void* num;
    
    b=3;
    num=&b;
    
    printf("%d\n",*(int*)num);
在num=&b 这一步之后,num的值是等于b的地址了,但是num本身并没有被表明为 int* ,所以在后续的printf的访问中,还是需要强制转换才能访问。


在函数形参中的使用:

看一下memCpy的代码:

void *memCpy(void *dest, const void *src, size_t n)
{
	if (NULL == dest || NULL == src || n < 0)
		return NULL;
	char *tempDest = (char *)dest;
	char *tempSrc = (char *)src;

	while (n-- > 0)
		*tempDest++ = *tempSrc++;
	return dest;	
}
这里的的形参是void*, 传进来的是一个一维数组的起始地址。这里并没有直接使用 dest[i]这种方式访问内容,而是先将void* 强制转换为char* 并赋值给 tempDest 才开始正常的数组访问。所以这里的 void* 我觉得更像是一个指针容器,可以接受任何类型的指针,然后进入函数之后再将其转换为需要的特定的类型。


<think>嗯,用户问的是这几个C语言的内存操作函数:memchr、memcmp、memcpy、memmove和memset。我需要逐一解释每个函数的作用、参数以及使用注意事项。首先,得确保自己对这些函数非常熟悉,特别是参数类型和返回值的部分。 先看memchr,它的作用是在内存块中搜索特定字符。参数是const void*,int类型的字符,还有size_t长度。返回的是找到位置的指针,找不到就NULL。需要提醒用户注意字符是以unsigned char形式处理的,这点可能容易忽略。 然后是memcmp,用来比较两块内存的内容。两个const void*指针和长度。返回值是整数,负数、零、正数表示大小关系。要注意比较是按字节进行的,可能受平台字节序影响,这点用户可能需要知道。 接下来是memcpy,用于内存拷贝。参数是目标、源和大小。这里有个__restrict关键字,说明源和目标不能重叠,否则行为未定义。这时候需要对比memmove,后者处理重叠区域更安全。用户可能容易混淆这两个函数,得强调区别。 memmove和memcpy功能类似,但会处理重叠,所以更安全,但可能效率稍低。需要解释为什么它能处理重叠,比如临时拷贝的可能。 最后是memset,用来设置内存块的值。参数是void*,int(会被转成unsigned char),和大小。常用于初始化或清零内存,比如初始化数组为0。但要注意,对于非字符类型,比如int数组用memset设0x01可能不会得到预期的每个int是0x01010101,这可能需要举例说明。 用户可能是C语言初学者,或者在使用这些函数时遇到了问题,比如内存操作错误。需要确保解释清楚每个函数的使用场景和潜在陷阱。例如,memcpy和memmove的区别,memset的使用限制等。同时,可能需要给出简单的例子,帮助理解。 另外,用户提供的函数声明中有一些细节,比如restrict关键字,需要解释其作用,说明memcpy不允许源和目标重叠,而memmove允许。这也是为什么memcpy可能更快的原因。 最后要总结这些函数都属于string.h或memory.h,使用时需要包含头文件。确保用户知道这些基本点,避免常见错误。</think>以下是对C语言内存操作函数的逐条解析(按执行效率和常用程度排序): $$ \text{void* memset(void* dest, int ch, size_t count);} $$ 1. 功能:将内存块前count个字节设置为ch的低字节值 2. 典型应用:缓冲区初始化/清零 3. 示例: ```c char buffer[1024]; memset(buffer, 0, sizeof(buffer)); // 清零缓冲区 ``` $$ \text{void* memcpy(void* restrict dest, const void* restrict src, size_t count);} $$ 1. 功能:从src复制count字节到不重叠的dest区域 2. 特性:使用restrict限定符保证内存不重叠,性能优于memmove 3. 示例: ```c int src[100], dest[100]; memcpy(dest, src, sizeof(src)); // 高效数组拷贝 ``` $$ \text{void* memmove(void* dest, const void* src, size_t count);} $$ 1. 功能:安全复制可能重叠的内存区域 2. 实现原理:采用临时缓冲区或反向拷贝策略 3. 典型场景: ```c char str[] = "memmove can handle overlap"; memmove(str + 4, str, 15); // 处理重叠拷贝 ``` $$ \text{int memcmp(const void* lhs, const void* rhs, size_t count);} $$ 1. 功能:按字典序比较内存内容 2. 返回值: - 负数:lhs < rhs - 零:相等 - 正数:lhs > rhs 3. 注意:比较结果与平台字节序相关 $$ \text{void* memchr(const void* ptr, int ch, size_t count);} $$ 1. 功能:在内存块中查找首个匹配字节 2. 参数:ch被解释为unsigned char 3. 返回值:找到时返回指针,否则返回NULL 共同特性: 1. 头文件:`<string.h>` 2. 参数规范: - size_t类型保证能表示任意对象大小 - void*指针提供通用内存访问能力 3. 时间复杂度:均为$O(n)$线性复杂度 注意事项: 1. memcpy与memmove选择: - 确定不重叠时用memcpy(更快) - 不确定时用memmove(更安全) 2. memset陷阱: ```c int arr[10]; memset(arr, 1, sizeof(arr)); // 每个字节设为0x01,而非设置int为1 ``` 3. 内存边界:必须确保操作范围不超过申请的内存空间 这些函数构成了C语言底层内存操作的基础,熟练掌握可有效提升系统级编程能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值