这个问题是关于C语言中指针的。

4

我见过很多这样的类型,但我不知道它的含义是什么。

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

有人能解释一下吗?

这段代码是无效的C语言代码,不会按照作者的预期执行。请勿复制。 - R.. GitHub STOP HELPING ICE
2
类型为 char * 的任意指针不一定满足 int 的对齐要求,可能无法被准确地存储在 int * 中(int * 可能比 char * 少一些位)。即使 int * 可以存储该值,如果未满足对齐要求,则在尝试取消引用指针时行为是未定义的。最后,还有别名考虑因素,这些因素大多可以通过其中一个涉及到 char 类型来缓解。 - R.. GitHub STOP HELPING ICE
不,它们并不一样。在C++中,代码同样是无效的。使其有效将把单操作码的解引用转换为在许多archs上每个指针解引用的15+行汇编语句。C ++可能因膨胀和缓慢而声名狼藉,但它并不那么糟糕。 - R.. GitHub STOP HELPING ICE
@R.. 这在C++中是有效的,因为:1)char、unsigned char或signed char数组保证对于任何类型都能正确对齐(否则向量分配器将很难实现:))。2)int可能不会比char少位。我不知道什么是别名。 - Armen Tsirunyan
2
@Armen:只有使用new char[]动态分配的数组才能保证这样。栈或成员变量没有任何此类保证。这就是为什么C++0x中有一个std::aligned_storage<T>的原因。 - Puppy
显示剩余4条评论
6个回答

3

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

b0 b1 b2 b3 b4 b5 b6 b7 

现在,ptr将指向b0,但将其视为int。也就是说,

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

希望对你有所帮助。

1

仅仅是somevar会通过ptr指针被解释为一个int序列(或只有一个)。将ptr增加一次就可以将指针移动sizeof(int)个字节。

在执行这样的转换时要注意字节序。从somevar中提取的字节可能需要重新排序才能正确地被解释为整数。

还要确保somevar的长度是sizeof(int)的倍数,否则当尝试访问最后一个int时,由于它只部分可用,您将会得到未定义的行为。


在程序的后续代码中,有一个bswap32函数来交换字节序。 - dikidera

0
在 C 语言中,数组的标识符是指向数组第一个元素的指针。因此,在您的示例中,somevar 是一个指向片段第一行声明的数组的第一个元素的 unsigned char*。
因此,很明显 ptr 也是一个指向数组第一个元素的指针,但由于类型转换,它将其视为有符号整数。
这不一定是一个好的类型转换,因为 int 和 char 很可能具有完全不同的大小,这可能导致一些未定义的行为。

1
数组的名称不是指针。它可以隐式转换为指针,但它不是指针。 - Armen Tsirunyan

0

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


0

右边是一个指向int的指针。

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

在这种情况下,您正在将字符打包到int中。根据系统的不同,您可能会得到一个内部位表示与[char0,char1,char2,char3]匹配的int,后跟另一个内部位表示与字符四到七匹配的int。

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

如果您深入研究代码,很有可能会发现另一个地方将指向您“构造”的int的指针转换回char*。


0

它是指向数组第一个值的指针。由于它是无符号字符,需要将其强制转换为int类型(虽然不需要,但这是良好的实践)。就大小而言,int类型的大小大多数情况下都比无符号字符小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接