我正在使用此代码将指针移动1个字节,但我感觉不清楚..
int* a = (int*)malloc(sizeof(int));
void* b = ((char*)a)+1;
char
是1个字节,但没有为字节操作目的定义。我相信还有另一种方法可以执行 byte 操作。 字节操作的正确方式是什么?
PS。我将示例代码修改为有效。它现在用Clang编译为C ++。
答案 0 :(得分:4)
在C99中,您有stdint.h
标头,其中包含int8_t
和uint8_t
类型,保证为8位(通常只是char的typedef)。除此之外,C或C ++中的字节没有真正的语言级别支持,实际上标准不用说sizeof
例如以char
为单位(而不是字节) 。还有CHAR_BIT
宏告诉你一个字节中的位数,在某些平台上char
例如是9位。当然我用字节来表示你的意思是八位字节。
答案 1 :(得分:4)
我觉得你很困惑:
char
是1个字节,但没有为字节操作目的定义。我相信还有另一种方法可以执行 byte 操作。 字节操作的正确方式是什么?
您期望byte
到底意味着什么,如果不是char
意味着什么呢?
在C和C ++中,字符是字节。 根据定义。什么是不的情况是 bytes 必然是八位字节。一个字节至少包含8位。 没有保证给定平台甚至可以可能来引用完全 8位的内存块。
答案 2 :(得分:2)
((char*)a)++
这是微软的恶意扩展之一。指针转换表达式是一个rvalue,但根据C ++语言规则,increment运算符仅适用于左值。 g ++拒绝编译它。
答案 3 :(得分:2)
您不应该这样做。许多架构都有数据对齐要求。例如,取消引用未与SPARC机器上的字边界对齐的指针,将使程序崩溃并出现总线错误(SIGBUS
)。
将int
拆分为字节的可移植方法是使用按位运算(假设为8位字节):
uint8_t b3 = 0x12, b2 = 0x34, b1 = 0x56, b0 = 0x78;
uint32_t a;
a = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
printf("%08X\r\n", a);
a = 0x89ABCDEF;
b3 = (a >> 24) & 0xFF;
b2 = (a >> 16) & 0xFF;
b1 = (a >> 8) & 0xFF;
b0 = a & 0xFF;
printf("%02X%02X%02X%02X\r\n", b3, b2, b1, b0);
通过union
的{{3}}技巧可以实现非便携,例如:
typedef union {
uint32_t val;
uint8_t bytes[4];
} DWORD_A;
typedef union {
uint32_t val;
struct {
unsigned b0:8;
unsigned b1:8;
unsigned b2:8;
unsigned b3:8;
};
} DWORD_B;
但是,这种技术导致实现定义的行为,因此不推荐:
答案 4 :(得分:1)
((char*&)a)++;
或者:
a = (int*)((char*)a+1);
我希望你确切知道你在做什么。首先,你的结果是 - 根据定义 - 未对齐的int指针。根据架构和操作系统,这可能会有麻烦。
答案 5 :(得分:0)
plz,使用void *
int g = 10;
int *a = &g;
printf("a : %p\n",a);
printf("a : %p\n", ++a);
printf("a : %p\n", (void*)((char*)a+1));
a:0xbfae35dc a:0xbfae35e0 a:0xbfae35e1