求救为什么*b的值是0xfffffff7!

wangyangkobe 2011-03-31 11:15:28

#include <iostream>
using namespace std;

int main()
{
unsigned int a = 0xFFFFFFF7;
unsigned char i = (unsigned char)a;
char* b = (char*)&a;;
printf("%08x, %08x\n", i, *b);
}
...全文
431 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
luciferisnotsatan 2011-04-12
  • 打赏
  • 举报
回复
你要是按10进制输出,就是负数。16进值就是补码。扩展成int,就是0xfffffff7

[Quote=引用 17 楼 luciferisnotsatan 的回复:]

引用 6 楼 pengzhixi 的回复:

你看你的输出格式就知道了%x

正解
x
Hexadecimal integer.


你按16进制输出,内存里就是0xfffffff7
[/Quote]
luciferisnotsatan 2011-04-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 pengzhixi 的回复:]

你看你的输出格式就知道了%x
[/Quote]
正解
x
Hexadecimal integer.


你按16进制输出,内存里就是0xfffffff7
xmu_才盛 2011-04-12
  • 打赏
  • 举报
回复
因为你告诉编译器要这么做, 你的代码说的, 所以为什么啊?????
Jupiter_cuso4 2011-04-12
  • 打赏
  • 举报
回复
printf和cout原理是不一样的
printf没有类型检查,它不知到你传的是char,只是根据你第一个变量猜测数据的长度。
cout是有C++的类型检查的,所以它知道是个char变量,因而是乱码。
huer0625 2011-04-12
  • 打赏
  • 举报
回复
lz, 对于你的疑问,我解释几点。
第一:函数的局部变量的空间都是在用户栈分配的,对于指针类型,char类型还有unsigned char类型和int还有unsigned int类型在32位的机子上分配都是4个字节存储空间。
第二: %x默认是打印的是unsigned int *指向的数据即打印unsigned int类型的数据,而unsigned int在32位机子上分配的是4个字节的空间。
unsigned char i = (unsigned  char)a; 

这条语句进行了强制类型转换,所以在i所在的临时空间里,其实保存的是0x000000f7。
char* b = (char*)&a;

这条语句只是对a所在空间的地址指针进行了强制类型转化,让&a成为指向char *类型的地址,但是&a地址所在的空间存储的值还是0xfffffff7。
printf("%08x, %08x\n", i, *b);

这条语句已经默认把i指向的指针&i默认转化成unsigned int *类型了,b 指向的内存默认也被转换成unsigned int 类型。所以它打印的结果是:
supertool@supertool-desktop:~/test$ ./unsigned 
000000f7, fffffff7

下面我是用gdb调试,验证前面的解释:
supertool@supertool-desktop:~/test$ gdb ./unsigned 
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/supertool/test/unsigned...done.
(gdb) l
1 #include <iostream>
2 #include <cstdio>
3 using namespace std;
4
5 int main()
6 {
7 unsigned int a = 0xFFFFFFF7;
8 unsigned char i = (unsigned char)a;
9 char* b = (char*)&a;;
10 printf("%08x, %08x\n", i, *b);
(gdb) b 10
Breakpoint 1 at 0x400751: file unsigned.cpp, line 10.
(gdb) r
Starting program: /home/supertool/test/unsigned

Breakpoint 1, main () at unsigned.cpp:10
10 printf("%08x, %08x\n", i, *b);
(gdb) x /x &a
0x7fffffffe248: 0xfffffff7
(gdb) x /x &i
0x7fffffffe24f: 0x000000f7
(gdb) x /x &b //通过这条命令我们可以看到b保存是&a,而&a保存是0xfffffff7
0x7fffffffe240: 0xffffe248
(gdb) x /x b
0x7fffffffe248: 0xfffffff7
(gdb) n
000000f7, fffffff7
11 }
(gdb)
yk2252365 2011-04-11
  • 打赏
  • 举报
回复
printf()中参数是*b的一个副本,值f7,因为对齐到4个字节再压栈,char是有符号的,用ff补完其他的3字节。printf("%x")中取整数格式,就是fffffff7了。
希望对你有帮助。
wangyangkobe 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qq120848369 的回复:]

另外,任何小于int的类型在使用时都会先进行扩宽,这里是printf时扩宽的.
[/Quote

楼上这是什么意思?
wangyangkobe 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qq120848369 的回复:]

C/C++ code
000000f7, 000000f7
请按任意键继续. . .



作为一个提问者,希望你能仔细的阅读回答.
[/Quote]

我的输出结果是

000000f7, fffffff7
请按任意键继续. . .
qq120848369 2011-03-31
  • 打赏
  • 举报
回复
000000f7, 000000f7
请按任意键继续. . .


作为一个提问者,希望你能仔细的阅读回答.
wangyangkobe 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qq120848369 的回复:]

另外,任何小于int的类型在使用时都会先进行扩宽,这里是printf时扩宽的.
[/Quote]


我觉得只会把a的第一个字节内容输出来啊。
pengzhixi 2011-03-31
  • 打赏
  • 举报
回复
你看你的输出格式就知道了%x
qq120848369 2011-03-31
  • 打赏
  • 举报
回复
另外,任何小于int的类型在使用时都会先进行扩宽,这里是printf时扩宽的.
qq120848369 2011-03-31
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;

int main()
{
unsigned int a = 0xFFFFFFF7;
unsigned char i = (unsigned char)a;
unsigned char* b = (unsigned char*)&a;;
printf("%08x, %08x\n", i, *b);
}

再试试,因为有符号数扩宽会用符号位填充.
wangyangkobe 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hhh_hao 的回复:]

char* b = (char*)&a; //b 指向了a的地址, *b等于a,

unsigned char i = (unsigned char)a; //这句没作用
[/Quote]

*b等于a?我怎么觉得不对啊,

int d = 10000;
char *f = (char*)(&d);
cout<<*f<<endl;


这个和上面一样的原理吧,但是得到的是乱啊啊
hhh_hao 2011-03-31
  • 打赏
  • 举报
回复
char* b = (char*)&a; //b 指向了a的地址, *b等于a,

unsigned char i = (unsigned char)a; //这句没作用
c_losed 2011-03-31
  • 打赏
  • 举报
回复

b = &a; //传a地址
*b 是地址的值


所以没有为什么。。
赵4老师 2011-03-31
  • 打赏
  • 举报
回复
严格来说
b的类型是char *
*b的类型是char
赵4老师 2011-03-31
  • 打赏
  • 举报
回复
因为b是有符号char呀
printf("0x%02x\n",'\x80');
还输出0xffffff80呢
dada12da1d2ad 2011-03-31
  • 打赏
  • 举报
回复
char* b = (char*)&a;//只是保存了a的地址
如果你换为double* b = (double*)&a;这种形式,得到结果还是一样。
因为无论是char *b还是double *b都只是一个指针,占4个字节(32位中),保存a的地址。a中的内容没有改变。

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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