C++ 什么';这是在C/C+中向指针添加1字节的正确方法+;?

C++ 什么';这是在C/C+中向指针添加1字节的正确方法+;?,c++,c,pointers,C++,C,Pointers,我现在用这段代码将指针移动1个字节,但我感觉有些不清楚 int* a = (int*)malloc(sizeof(int)); void* b = ((char*)a)+1; char是1个字节,但不是为字节操作而定义的。我相信还有另一种方法可以完成这个字节操作。正确的字节操作方法是什么 PS.I修改了样本代码以使其有效。现在它被编译成C++与Clang。< /P> ((char*&)a)++; 或: 我希望你知道你在做什么。首先,根据定义,您将得到未对齐的int指针。根据体系

我现在用这段代码将指针移动1个字节,但我感觉有些不清楚

int* a = (int*)malloc(sizeof(int));
void* b = ((char*)a)+1;   
char
是1个字节,但不是为字节操作而定义的。我相信还有另一种方法可以完成这个字节操作。正确的字节操作方法是什么

PS.I修改了样本代码以使其有效。现在它被编译成C++与Clang。< /P>
((char*&)a)++;
或:


我希望你知道你在做什么。首先,根据定义,您将得到未对齐的int指针。根据体系结构和操作系统的不同,这可能会带来麻烦。

在C99中,您有
stdint.h
头,它包含
int8_t
uint8_t
类型,这些类型保证为8位(通常只是字符的typedef)。除此之外,C语言或C++语言中没有对字节的实际语言支持,事实上标准是说“<代码> sieOfs<代码>是以<代码> char < /C> >(而不是字节)为单位。还有一个
CHAR\u BIT
宏,它告诉您一个字节中的位数,例如在某些平台上
CHAR
是9位。当然我假设字节是指八位字节

((char*)a)+


这是一个邪恶的微软扩展。一个指针转换表达式是一个rValk,但是根据C++语言规则,增量操作符只对LValk工作。g++拒绝编译此文件。

我认为您感到困惑:

char
是1个字节,但不是为字节操作而定义的。我相信还有另一种方法可以完成这个字节操作。正确的字节操作方法是什么

如果不是与
char
的意思完全相同,那么您希望
byte
到底是什么意思


<>在C和C++中,字符<强>是字节。strong>根据定义。不是情况是字节必然是八位字节。一个字节至少包含8位。没有可以保证给定的平台甚至可以引用正好是8位的内存块。

您不应该这样做。许多体系结构都有数据对齐要求。例如,取消对SPARC计算机上未对齐字边界的指针的引用,将导致程序因总线错误而崩溃(
SIGBUS


int
拆分为字节的可移植方法是使用逐位操作(假设为8位字节):

但是,这种技术会导致实现定义的行为,因此不推荐使用:

  • 字节顺序取决于主机系统的端序
  • 位字段的打包不可移植
  • 由于编译器生成代码以防止错误访问,增加了复杂性/开销
  • 在没有阻止它们的实现上出现对齐问题
    • 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));
      

      < P> >:0xBFAE35DC A:0xBFAE35E0A:0xBFAE35E1

      你使用C还是C++?您显示的代码对这两个版本都无效。你所说的“
      char
      不是为字节操作定义的”是什么意思?没有正确的方法可以做到这一点;您所做的会导致未定义的行为。@Alexandre:因为只有一个有效的
      int*
      指针指向长度
      sizeof(int)
      的缓冲区。现在,这个问题正在创建一个
      void*
      。这里有很多标准在摇摆!OP没有说明他为什么要这么做,所以,恕我直言,他和所有写C的人都处于同样的境地——你需要解析一些网络数据,或者一些复杂的文件,或者其他什么,你需要索引到一个字节数组中。我有点惊讶于人们如此大声地宣称这在概念上是不可能的,应该不惜一切代价避免。在C语言中,这可能在概念上是不可靠的,但老实说,OP建议的代码在大多数常见平台上都能完美运行,并且很可能完成任务;它没有“字节”类型。它有一个字符。标准uint8_t仅在c99中引入(带有stdint.h),因此许多编译器(如turbo c)都没有附带它。为了让人恼火,许多C++编译器将char、签字符作为不同类型,自己尝试——创建2个函数fo(char *)和fo(签名char),C++不会抱怨模糊性,但是稍后你可以很容易地调用错误函数。假设C预定义了u8、u16、u32、u64(相对于16位体系结构);我们今天不会有一百万个同义词!不仅是一个未对齐的指针,而且是一个无效的指针,因为它超出了分配的缓冲区的边界。谢谢。在C/C++中,
      byte
      的概念似乎是完全抽象的。对吗?如果是这样,
      char
      应该是数据类型的最小单位。是吗?除了位字段之外,char是数据类型的最小单位。但是,由于您不能命名位字段的类型(因此不能有指向它的指针,也不能获取它的地址)或以小于char的单位执行指针算术,因此对于指针而言,char是最小值,是的。它是
      char\u bit
      ,而不是
      char\u bit
      。哇!谢谢你帮了我很多!这就是我想要的!谢谢我不知道有关对齐的详细信息。如果是这样,就不可能使字节操作代码可移植。它似乎需要任何类型的抽象。如果有一块数据需要逐字节访问,那么首先可以将其声明为
      char
      数组。另外,我展示的位移位方法是可移植的。有关更多信息,请参阅。
      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);
      
      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;
      
      int g = 10;
      int *a = &g;
      printf("a : %p\n",a);
      printf("a : %p\n", ++a);
      printf("a : %p\n", (void*)((char*)a+1));