unsigned int a=0x12345678;char *c=(char*)&a;不理解。。。

xiaowai0219 2010-07-21 10:13:59
#include <stdio.h>

int main()
{
unsigned int a=0x12345678;
unsigned char b=(unsigned int)a;
char *c=(char*)&a;
printf("%04x %04x\n",b,*c );
return 0;
}

/*
*编译器:vc++6.0
*case1:unsigned int a=0x12345678;
*output:0078 0078
*
*case2:unsigned int a=0x123456a8;
*output:0078 ffffffa8;
*
*问题:为什么结果这样?谁能帮忙把详细过程说下
*/
...全文
1964 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaowai0219 2010-07-22
  • 打赏
  • 举报
回复
搞清楚了,结贴给分。
此题来自程序员面试宝典2,马上就进入大四,要找工作了。多做点准备
凡是预则立,不预则废嘛。。。
xiaowai0219 2010-07-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 phpjspasp 的回复:]
// b先提升成int,因为b是无符号的,所以做无符号扩展,高位补0
// *c是有符号的,做有符号扩展,高位补符号位,符号位为1,所以补1.补成了0xffffffa8。然后输出 。[/Quote]
应该是这样的,改unsigned char *c之后,结果是00a8,是按你说的那样,无符号,做无符号扩展,高位补0
fancanqin 2010-07-21
  • 打赏
  • 举报
回复
学习学习
yanghope 2010-07-21
  • 打赏
  • 举报
回复
对不起,我说成操作系统啦,呵呵,抱歉啊!
phpjspasp 2010-07-21
  • 打赏
  • 举报
回复 1
xiaowai0219
[Quote=引用楼主 xiaowai0219 的回复:]
C/C++ code
#include <stdio.h>

int main()
{
unsigned int a=0x12345678;// 我知道你的机器是小端的,所以0x78放在了a所占空间的最低地址字节。
//不妨假设a所占的空间的地址是1000, 1001, 1002, 1003
//在地址为1000的字节里,存放0x78
// 1001 0x56
// 1002 0x34
// 1003 0x12

unsigned char b=(unsigned int)a; // 这样,a被截断,把0x78赋给了b, b是无符号的。

char *c=(char*)&a; // &a是1000,对吧,接着上面我说的。所以*c的内容是0x78,是有符号的
printf("%04x %04x\n",b,*c ); // b先提升成int,因为b是无符号的,所以做无符号扩展,高位补0
// 第一个输出0078
// *c是有符号的,做有符号扩展,高位补符号位,符号位为1,所以补1.补成了0xffffff78。然后输出 。
return 0;
}

/*
*编译器……
[/Quote]
xiaowai0219 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lokii 的回复:]
实际上就这样:

C/C++ code
#include <stdio.h>

int main()
{
char c=0xa8;
printf("%04x\n", c);
return 0;
}

c的符号位为1,为负数,%04x打印时强制转化成为32位的无符号整型来打印。
[/Quote]
好像这样解释得过来。。。
phpjspasp 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xiaowai0219 的回复:]

引用 7 楼 yanghope 的回复:
这和大端法和小端法没有关系,主流的操作系统如windows和Linux都是采用的是小端法进行数据在内存的存储,这个问题涉及到C的底层工作机制,大家知道,C的底层就是汇编,这个程序出现了多次的位的缩放,而编译器在将这段代码转换成对应的汇编程序时(可以反汇编查看汇编代码),会用到CBW,CWD等位的缩放的指令,例如CBW(将byte转化成word)指令,规……
[/Quote]
小端大端是处理器决定的。不是操作系统决定的。
intel的处理器是小端,sun sparc是大端,moto的可以小端也可以大端
xiaowai0219 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 yanghope 的回复:]
这和大端法和小端法没有关系,主流的操作系统如windows和Linux都是采用的是小端法进行数据在内存的存储,这个问题涉及到C的底层工作机制,大家知道,C的底层就是汇编,这个程序出现了多次的位的缩放,而编译器在将这段代码转换成对应的汇编程序时(可以反汇编查看汇编代码),会用到CBW,CWD等位的缩放的指令,例如CBW(将byte转化成word)指令,规则:当最高位是1时,补全的位将全是1,这就是为……
[/Quote]
这个看着靠谱点,不过有一点我有异议:
主流的操作系统如windows和Linux都是采用的是小端法进行数据在内存的存储。
好像字节序跟操作系统没关系额
xiaowai0219 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 xiaowai0219 的回复:]
引用 1 楼 phpjspasp 的回复:
自己去查吧。
google 小端,大端,整形提升。
或者
google little-endian, big-endian, integer promotion

高地址存高位,大端字节序。b的值是截断,大于等于3为的丢掉。
char *c=(char*)&a;相当于:
unsigned int *p=&a;
char ……
[/Quote]
好混乱啊,应该这样
char *c=(char*)&a;相当于:
unsigned int *p=&a;
char *c=(char*)p;
我不明白的是为什么case1里面c输出0078,而case2里面为ffffffa8;
我觉得都应该是a的值
xiaowai0219 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 phpjspasp 的回复:]
自己去查吧。
google 小端,大端,整形提升。
或者
google little-endian, big-endian, integer promotion
[/Quote]
高地址存高位,大端字节序。b的值是截断,大于等于3为的丢掉。
char *c=(char*)&a;相当于:
unsigned int *p=&a;
char *b=(char*)p;
我不明白的是为什么case1里面b输出0078,而case2里面为ffffffa8;
我觉得都应该是a的值
yanghope 2010-07-21
  • 打赏
  • 举报
回复
这和大端法和小端法没有关系,主流的操作系统如windows和Linux都是采用的是小端法进行数据在内存的存储,这个问题涉及到C的底层工作机制,大家知道,C的底层就是汇编,这个程序出现了多次的位的缩放,而编译器在将这段代码转换成对应的汇编程序时(可以反汇编查看汇编代码),会用到CBW,CWD等位的缩放的指令,例如CBW(将byte转化成word)指令,规则:当最高位是1时,补全的位将全是1,这就是为什么前几位都是ffff的原因,当最高位是0时,补全的位将都是0,这就是为什么会出现00的原因。所以写程序不要想当然,理解底层机制会让你写更复杂的程序时少走很多弯路。
xiaowai0219 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 pan18 的回复:]
0x12345678十进制数是多少?是不是int和usigned有溢出呀?
[/Quote]
没溢出。。。
lokii 2010-07-21
  • 打赏
  • 举报
回复
实际上就这样:
#include <stdio.h>

int main()
{
char c=0xa8;
printf("%04x\n", c);
return 0;
}

c的符号位为1,为负数,%04x打印时强制转化成为32位的无符号整型来打印。
pan18 2010-07-21
  • 打赏
  • 举报
回复
0x12345678十进制数是多少?是不是int和usigned有溢出呀?
fancanqin 2010-07-21
  • 打赏
  • 举报
回复
上面错了,是16进制
fancanqin 2010-07-21
  • 打赏
  • 举报
回复
菜鸟路过学习。。
%04x 貌似输出字段宽度为4的10进制数。 前面的等大虾。
phpjspasp 2010-07-21
  • 打赏
  • 举报
回复
自己去查吧。
google 小端,大端,整形提升。
或者
google little-endian, big-endian, integer promotion

69,375

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧