【问题标题】:What is this pointer in C?C语言中的这个指针是什么?
【发布时间】:2011-10-04 13:03:22
【问题描述】:

我见过很多这样的类型,但我不知道这是什么意思

unsigned char somevar[MAXLEN];
int *ptr = (int *) somevar;

谁能解释一下?

【问题讨论】:

  • 这段代码是无效的C,不会做作者期望它做的事情。不要抄袭。
  • @R..:嗯?这是有效的并且具有明确定义的行为。为什么不呢?
  • char * 类型的任意指针不一定满足 int 的对齐要求,并且可能无法忠实地存储在 int * 中(它的位数可能少于char *)。即使int * 可以存储该值,如果不满足对齐要求,当您尝试取消引用指针时行为未定义。最后,还有别名注意事项,其中一种类型是char,这一事实主要缓解了这种情况。
  • @R.. 我不能 100% 确定 C,因为我没有读过标准,不幸的是,但是在 C++ 中,你所有的论点都得到了照顾......
  • @Armen:只有使用new char[] 动态分配的数组才能保证这种方式。堆栈或成员变量没有任何此类保证。 C++0x 中有std::aligned_storage<T> 是有原因的。

标签: c arrays pointers char


【解决方案1】:

本质上,您将一个字符数组解释为指向 int 的指针。假设sizeof (int) 为 4,char 数组包含这些字节:

b0 b1 b2 b3 b4 b5 b6 b7 

现在ptr 将指向b0,但威胁它为int。也就是说,

ptr[0]是由字节b0, b1, b2, and b3组成的整数
ptr[1]是由字节b4, b5, b6, and b7组成的整数

HTH

【讨论】:

    【解决方案2】:

    只是somevar 将通过ptr 指针被解释为int 的(或只是一个)序列。增加一次ptr 将指针sizeof(int) 向前移动一次。

    在进行此类转换时请注意字节顺序。来自somevar 的字节可能需要重新排序才能正确解释为整数。

    还要确保somevar 的长度是sizeof(int) 的倍数,否则在尝试访问最后一个int 时会出现未定义的行为,因为它将部分可用。

    【讨论】:

    • 在这段代码所在的程序中,还有一个交换字节序的 bswap32 函数。 Mersi mnogo。
    【解决方案3】:

    C 中数组的标识符是指向数组第一个元素的指针。因此,在您的示例中, somevar 是一个 unsigned char * 指向在 sn-p 的第一行中声明的数组的第一个元素。

    因此很明显 ptr 也是指向数组第一个元素的指针,但由于类型转换,它会将其视为有符号整数。

    这不一定是一个好的类型转换,很有可能 int 和 chars 的大小完全不同,这可能会导致一些未定义的行为。

    【讨论】:

    • 数组名不是指针。它可以隐式转换为指针,但它不是指针。
    【解决方案4】:

    当您从二进制文件或网络套接字读取一些原始字节时,通常会这样做,并且您(从数据格式或协议)知道这些字节序列表示一个整数。这将为您提供一个指针,您可以取消引用并获取这些字节表示的整数值。

    【讨论】:

      【解决方案5】:

      在右手边,它是一个指向 int 的指针。

      在左侧,它是一个未知类型的变量 (somevar),它被转换为一个指向 int 的指针。建议以批判的眼光看待 somevar。有时需要在 C 中进行强制转换;但是,更常见的是在 C 中进行强制转换,表明选择了错误的 somevar 类型,或者您正在做一些不太可能移植的事情。

      在这种情况下,您将字符打包成整数。根据系统的不同,您可能会得到一个内部位表示匹配 [char0, char1, char2, char3] 的 int,然后是另一个内部位表示匹配字符 4 到 7 的 int。

      但是,在某些其他系统上,您可能会得到一个内部位表示为 [char3, char2, char1, char0] 的 int。最后,还有其他系统处理位顺序的方式更加不同。

      如果你深入研究代码,你会发现在另一个地方,指向“已构建”int 的指针会被转换回 char*。

      【讨论】:

        【解决方案6】:

        它是指向数组第一个值的指针。由于它是一个无符号字符,因此需要将其类型转换为 int(它不需要,但这是一种很好的做法)。根据有人担心大小,大小 int 在大多数情况下总是小于无符号字符。

        【讨论】:

          猜你喜欢
          • 2013-06-27
          • 2014-09-29
          • 1970-01-01
          • 2019-03-19
          • 1970-01-01
          • 1970-01-01
          • 2022-06-14
          • 2022-01-12
          • 1970-01-01
          相关资源
          最近更新 更多