【问题标题】:Access c variable as an array将 c 变量作为数组访问
【发布时间】:2017-01-01 07:27:32
【问题描述】:

我有中度卡住,谷歌搜索正确的词不能让我得到正确的答案。更糟糕的是,我已经这样做了,但是我自己的代码示例在源代码的某个地方丢失了。

#include <stdio.h>

int main()
{
    short x = 0xABCD;
    char y[2] = { 0xAB, 0xCD };
    printf("%x %x\n", y[0], y[1]);
    printf("%x %x\n", (char *)&x[0], (char *)&x[1]);
}

基本上我需要通过指针算法通过数组访问各个变量字节,无需任何计算,只需通过类型转换。

【问题讨论】:

  • 你需要((char *)&amp;x)[0]
  • 您可能还需要记住,您正在使用十六进制表示负数(您的编译器应该抱怨类型溢出)给定类型 shortchar(而不是 @987654325 @ 和 unsigned char) 以防引起您的困惑。
  • 代码调用未定义的行为。 printf 期望 unsigned int,你传递 int

标签: c arrays pointers pointer-arithmetic


【解决方案1】:

在你的演员表周围加上括号:

printf("%x %x\n", ((char *)&x)[0], ((char *)&x)[1]);

请注意,字节序可能会改变您的预期结果。

以后,使用-Wall 进行编译以查看警告或错误是什么。

【讨论】:

  • 字节序?这就是你的意思?
  • 这不会改变未定义的行为。 printf 需要 unsigned int,但参数是 int
  • 这可以通过将所有int 值转换为unsigned 来解决。例如(unsigned)(((char *)&amp;x)[0])。使用联合而不是仅仅依靠类型转换可能会更安全(至少对于人类理解而言)。
  • 是的,抱歉,我的意思是字节序,而不是结束符。最谦虚的道歉。错误已修复。
【解决方案2】:

它在 C99 中得到了一定程度的支持。通过一个称为类型双关的过程,通过联合。

union {
  short s;
  char c[2];
} pun;

pun.s = 0xABCD;
pun.c[0] // reinterprets the representation of pun.s as char[2].
         // And accesses the first byte.

指针转换(只要指向char*,以避免严格的别名违规)也可以。

short x = 0xABCD;
char *c = (char*)&x;

【讨论】:

  • 当然,将指针转换为(void *) 也可以(如果您想使用%p 打印指针所保存的值,则必须这样做)。
  • 抱歉打扰了,但它不是像读取最后在联合中写入的成员的值一样调用UB吗?
  • @SouravGhosh - The restriction was removed in C99 and onward。仅包含可能存在陷阱的警告,并说明结果取决于值的表示。
【解决方案3】:

如果您只想获取 ,您可以将源变量的地址存储在 char * 中,然后递增和取消引用 char 指针以打印每个变量的值字节。

引用C11,第 6.3.2.3 章

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

类似的东西(考虑伪代码,未测试

#include  <stdio.h>

int main(void)
{
    int src = 0x12345678;
    char * t = &src;

    for (int i = 0; i < sizeof(src); i++)
        printf("%x\t", t[i]);

    return 0;
}

应该这样做。


也就是说,为了详细说明接受的答案,为什么部分:

根据operator precedence table,数组索引运算符的优先级高于类型转换,因此除非明确强制,否则在表达式中

  (char *)&x[0]

x 的类型未按预期更改。因此,为了强制类型转换的有意义使用,我们需要将其括在额外的括号中。

【讨论】:

    猜你喜欢
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2012-11-26
    • 2013-06-29
    • 1970-01-01
    相关资源
    最近更新 更多