注册 登录
编程论坛 Linux教室

关于16进制输出的问题

无聊恢恢 发布于 2012-07-21 10:51, 617 次点击
int main{
    int a[5] = {1,2,3,4,5};
   
    printf("&x\n",*(int *)((int)a + 1));
}
输出为2000000 求解释!
6 回复
#2
lonmaor2012-07-21 16:26
不知道你想干嘛
#3
madfrogme2012-07-21 18:26
你是不是把 % 打成了 &?
#4
无聊恢恢2012-07-21 21:27
对啊 打错了 是 printf("%x\n",*(int *)((int)a + 1));
不好意思
#5
pangding2012-07-21 23:35
解释倒是能解释:
看那个数组在内存里的样子(只有前两个有影响)

1 2 的二进制码分别是(括号里的是十六进制表示,逗号分隔字节):
0000 0000  0000 0000  0000 0000  0000 0001 (00,00,00,01)
0000 0000  0000 0000  0000 0000  0000 0010 (00,00,00,02)

intel 的字节序是 little-endian,也就是说存在内存里的是这个样子:
!0000 0001!0000 0000  0000 0000  0000 0000 (!01!00,00,00)
 0000 0010  0000 0000  0000 0000  0000 0000 ( 02,00,00,00)

a 本来指向的 1 的起始,也就是上面红色叹号的位置。加一之后,向后挪了一个字节也就是蓝色叹号那里。再输出 int 就是从那里取四个字节,是 (00,00,00,02) 由 little-endian 便是十六进制的 2000000。

但这种写法是危险的,结果也不具有移植性。
有些机器或者编译器对数据段的数据有严格的对齐限制:a 是 int 类型,所以 a 的齐起始地址在内存里一定是 4(即 sizeof(int))的整数倍。向前进了一字节后,地址被4除余一,在这个地址上进行 int 的读取操作会引发寻址异常。通常程序会表现为段错误。
#6
pangding2012-07-21 23:43
另外楼主的程序:
①:main 后面应该有一对括号。
②:数组后面的那个分号也应该是半角(英文状态)的分号。
③:虽然有人提了,printf 里应该是 %。
④:虽然写不写都可以,不过最好还是在返回 int 的函数最后加上 return 0;

很难想像,这么一个比 hello world 还短的程序能犯这么多错误。
楼主最好先编译编译自己写的程序,这样可以方便其他人直接拷贝运行。

还是就是,如果楼主的基本功不是太好的话,不建议研究这种没什么太大实际意义的代码。一般这类代码涉及的概念比较多。
#7
madfrogme2012-07-22 15:12
回复 5楼 pangding
我等新手好像理解起来有困难
1