如果我想操作指向一个字节的指针,我应该使用void *或char *,因为我听说过
sizeof(char)
并不总是1个字节,那么void *呢?如果我做
void *p
++p
它会指向一个字节到处吗?
答案 0 :(得分:8)
在C 中,没有为void指针定义指针算法。指针算术本质上与指向类型的大小相关联。对于void *
,指向类型的大小是未知的。
要了解指针算法如何适用于不同的对象,请尝试以下方法:
int obj[5];
int *ip = obj;
char *cp = (char *)obj;
ip++;
cp++;
printf("%p\n%p\n", ip, cp);
但是,如果编译器确实支持它,则void指针上的指针算法与char指针的工作方式相同。
答案 1 :(得分:1)
为此,我认为你应该使用<stdint.h>
。它定义了以下类型(以及其他类型):
uint8_t Always 1 byte (assuming 8-bit bytes, as is nearly ubiquitous)
uint16_t Always 2 bytes
uint32_t Always 4 bytes
uint64_t Always 8 bytes
如果您知道自己在做什么,并希望以内存方式指针算术,那么请使用uint8_t*
指针进行操作。 (是的,我只是把它用作动词,BTW。)
示例:
uint8_t* p = <Some Base Addr>;
while (*p) // p points to non-null byte
{
*p ^= 0xA5; // XOR the byte with A5
p++; // Increment to the next byte.
*(uint32_t*)p = 0xDEADBEEF; // Write a 32-bit (DWORD)
((uint32_t*)p)++; // Increment p by 4 bytes
}
答案 2 :(得分:1)
根据定义,char
只占用一个字节的存储空间,因此如果要根据字节大小进行地址计算,请使用char *
。虽然C标准要求void *
具有与char *
相同的表示,但void *
不包含大小信息,因此不能用于指针算术。
如果您确实想要获取对象表示的位,请使用unsigned char
,因为char
可能已签名,并且未指定为无填充。
现在,评论Jonathon's answer:
虽然来自stdint.h
的固定宽度整数类型也是无填充的,您可以按照特定体系结构的描述使用它们(如果您不需要是可移植的,那么特定于平台的代码没有任何问题)一般来说,你只知道它们的位宽,而不是它们的字节大小,因为CHAR_BIT
可以与8不同(16和32对于嵌入式世界的某些部分是“常见的”)。但是,POSIX系统需要byte == octet。
不需要存在特定大小的固定宽度整数类型:特别是,如果CHAR_BIT
不是2的幂(是的,存在这样的体系结构),则{{1}类型都不是},uint8_t
,uint16_t
,uint32_t
可以存在