使用指针访问long long变量中的字节

Den*_*nis 3 c pointers strict-aliasing pointer-arithmetic

我应该创建一个变量

long long hex = 0x1a1b2a2b3a3b4a4bULL;
Run Code Online (Sandbox Code Playgroud)

然后定义指向1a1b,2a2b,3a3b和4a4b的4个指针.然后我打印那些双字节的地址和值.

我的方法是创建一个指针

long long *ptr1 = &hex;
Run Code Online (Sandbox Code Playgroud)

然后使用指针算法来获取下一个值.我意识到增加这个指针会增加长字节,而不是像我需要的那样增加2个字节.创建一个短指针

short *ptr1 = &hex;
Run Code Online (Sandbox Code Playgroud)

是我需要的,但我的编译器不会让我,因为数据类型不兼容.我该如何解决这个问题?有没有办法创建一个递增2个字节的指针并将其分配给更大数据类型的变量?

Sou*_*osh 8

您只能通过兼容类型访问任何变量.

但是,char指针可用于访问任何类型的变量.

请不要将投射short* 请参阅下面的注意,它们不是兼容的类型.您只能使用char*符合规范的代码.

引用C11,章节§6.3.2.3

[...]当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节.结果的连续增量(直到对象的大小)产生指向对象的剩余字节的指针.

因此,出路是,使用a char *并使用指针算法来获取所需的地址.


注意:由于所有其他答案都提示一个明显错误的方法(将指针强制转换为short *显式违反严格别名),让我对我的答案和支持引号进行扩展.

引用C11,章节§6.5/ P7

对象的存储值只能由具有以下类型之一的左值表达式访问:88)

- 与对象的有效类型兼容的类型,

- 与对象的有效类型兼容的类型的限定版本,

- 对应于对象的有效类型的有符号或无符号类型,

- 对应于对象有效类型的限定版本的有符号或无符号类型,

- 聚合或联合类型,其成员中包含上述类型之一(包括递归地,子聚合或包含联合的成员),或者

- 角色类型.

在这种情况下,a short和a long long不是兼容类型.所以唯一的出路是使用pointer tochar`类型.


来自问题正文的剪切 - 粘贴

这被OP添加为更新

编辑:这是正确的解决方案,不会导致未定义的行为.编辑2:添加了内存地址.

#include <stdio.h>
int main() {
    long long hex = 0x1a1b2a2b3a3b4a4bULL;
    char *ptr = (char*)&hex;
    int i; int j;
    for (i = 1, j = 0; i < 8, j < 7; i += 2, j += 2) {
        printf("0x%hx%hx at address %p \n", ptr[i], ptr[j], (void *) ptr+i);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)