【发布时间】:2022-01-23 21:36:40
【问题描述】:
问题:
我可以让两个不同类型的指针(uint32_t * 和char *)指向同一个地址吗?
这就是我想要这个的原因:
可以说,我有一个 uint32_t 类型的变量,其中包含一个 UTF-32 编码的 unicode 字符。而且我已经知道以 UTF-8 编码时它需要 4 个字节。它的二进制表示是这样的:
00000000000aaabbbbbbccccccdddddd
a、b、c 和 d 是 4 个不同的范围,其中每个位可以是 0 或 1。
通过巧妙的按位 &、| 和 << 操作,我可以重新排列这些位,以便最后有这个新的分布:
00000aaa00bbbbbb00cccccc00dddddd
然后我可以翻转一些位(再次使用|)来得到这个
11110aaa10bbbbbb10cccccc10dddddd
当我将其拆分为数组中的 4 个后续 char 变量时,我有这个:
11110aaa 10bbbbbb 10cccccc 10dddddd
这正是同一个 unicode 字符的 UTF-8 编码。
因此,内存中相同的 4 个字节应该是一个 uint32_t 变量,同时是一个由 4 个 char 变量组成的数组:
所以,我想要这个:
uint32_t *utf32;
char utf8[4];
-
*utf32是一个指向单个 4 字节长的uint32_t变量的指针。 -
utf8是一个指向由 4 个char元素组成的数组的指针,每个元素长 1 个字节。
我希望两个指针都指向同一个地址。所以我可以将一个 utf32 编码的字符写入变量utf32,将其转换到位,然后从数组utf32 中读取结果。这可能吗?如果是这样:我该怎么做?
(我在上个千年用 COBOL 编码时经常使用这种技术,因为在 COBOL 中很容易用许多不同的定义重载内存中的同一区域。但我不知道如何在C.)
我发现很多问题涉及指向相同地址的 2 个指针,但在这些问题中,指针始终具有相同的类型。还有一些其他问题是,如果用某种类型定义的指针指向用另一种类型定义的地址,为什么会出现错误。但是我没有发现任何关于共享同一地址的两个不同类型的指针。
【问题讨论】:
-
"因此,内存中相同的 4 个字节应该是一个
uint32_t变量,同时是一个由 4 个char变量组成的数组" - 而那当然可能(如您所问,通过使用union或2 个指向同一内存的类型指针),我不建议这样做。uint32_t具有字节顺序,其字节顺序可能与您需要的char[]顺序不匹配。我将使用单独的char[]并根据需要将位从uint32_t移到char[],而不管字节序如何。此外,由于 UTF-8 无论如何都是可变长度的,并非所有uint32_t值都会填充char[4]。 -
你可以这样做——但你的两个指针之一将是
char *,这很有帮助。如果你有两个不是char *的指针——比如int *和float *——你就不得不担心strict aliasing。但是通过char类型访问是该规则的明确例外。