将字符数组视为整数 - 学习C Hard Way Extra信用

时间:2014-04-11 00:43:52

标签: c arrays pointers

在Zed Shaw的“以艰难的方式学习C”中,练习9(http://c.learncodethehardway.org/book/ex9.html)有一个额外的学分问题,我觉得很有趣。他定义了一个4字符数组,并要求读者弄清楚如何将该数组用作4字节整数。

此时我知道这很危险,而且我认为答案是这样的:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char name[4] = {'A'};

    int *name_int;
    name_int = &name;
    printf("%d", *name_int);

    return 0;
}

我的想法是,如果我创建了一个int指针,其值为数组的地址,int类型将使用该地址中的数据字节,然后是可用的下一个3字节数据。在我有限的理解中,我的印象是int和数组都会以相同的方式使用内存:从任意内存地址开始,而不是按顺序使用下一个地址,依此类推。

然而,这个输出并不是我的预期:我得到'A'的ascii值。对我而言似乎表明我的解决方案不正确,我理解如何处理内存是不正确的,或两者兼而有之。

这个小小的黑客怎么可能完成,我在哪里错了?我希望通过更好地理解指针和引用如何工作,以及如何存储和使用内存来远离这一点。

谢谢!

1 个答案:

答案 0 :(得分:8)

你正在遇到小端和大端的数字代表。

让我们看看用于表示4字节整数的4-btyes的值。

+----+----+----+----+
| N1 | N2 | N3 | N4 |
+----+----+----+----+

在big-endian表示中,这4个字节表示:

N1*2^24 + N2*2^16 + N3*2^8 + N4

在小端表示中,这4个字节表示:

N1 + N2*2^8 + N3*2^16 + N4*2^24

在你的情况下。

N1 = 'A' (65 decimal)
N2 = 0
N3 = 0
N4 = 0

由于您获得的整数值为65,因此您有一个小的字节序表示。如果您想将这些数字视为big-endian表示,则可以使用以下内容:

#include <stdio.h>

int main(int argc, char *argv[])
{
   int i;
   char nameString[4] = {'A'};
   int name = 0;

   for ( i = 0; i < 4; ++i )
   {
      name = (name << 8) + nameString[i];
   }

   printf("%d\n", name);
   printf("%X\n", name);

   return 0;
}

我用上面的代码得到的输出:

1090519040
41000000