24小时热门版块排行榜    

CyRhmU.jpeg
查看: 1260  |  回复: 7
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

我爱小虫子

新虫 (正式写手)

[求助] C++一道题目,疑惑已有2人参与

题目如下图,另外附上书上的解释,没有明白,为什么unsigned char 明明是1个字节,为什么要给他分配16的空间啊,
另外,附上一个连接,我从网上找的,但是也没有明白,这个连接的帖子里是分配了32位。不要小看 b=~a>>4 - ybdesire的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/ybdesire/article/details/6583724
我再VC6上也试了题目上的问题,结果是250,和在VS上结果一样的,(因为b只能存放低8位)
再说一下我的疑惑哈,
(1)unsigned char 为什么不是分配了一个字节,
(2)如果不是一个,那应该是16还是32啊(还是视编译器而定啊)
.感谢!!!!

C++一道题目,疑惑
QQ图片20140323170345.jpg


C++一道题目,疑惑-1
QQ图片20140323170430.jpg
回复此楼

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

我爱小虫子

新虫 (正式写手)

送红花一朵
引用回帖:
4楼: Originally posted by adf2007 at 2014-03-24 23:58:29
我可以确定你有几点理解错了。
一、“不要小看 b=~a>>4 - ybdesire的专栏 - 博客频道 - CSDN.NET”这篇文章你没有仔细看。那篇文章有3个例子,第一个例子的反汇编没有写全,但是第一个例子确实提到了32这个数 ...

今天好好看了好几遍你的回复,实在觉得应该感谢。。。。。,再送一朵小红花吧
6楼2014-03-25 22:34:00
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 8 个回答

rbs

木虫 (小有名气)

【答案】应助回帖

★ ★ ★ ★ ★ ★ ★ ★ ★ ★
感谢参与,应助指数 +1
我爱小虫子: 金币+10, ★★★★★最佳答案, 非常感谢,你说的这些确实是我的疑惑,是我对一些概念的模糊,这次一定搞清楚。。 2014-03-25 08:06:26
C标准里面有明确的说明:
Each of the operands shall have integer type.The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.
移位运算的操作数必须是整型(关于整型还有些说头,但可以确定的是绝对不再是char)。如果操作数不是整型,则会做integer promotion操作,基本上就是转型操作。
另外,对于按位非操作,操作数一样要首先做integer promotion操作。
If an int can represent all values of the original type, the value is converted to an int;
otherwise, it is converted to an unsigned int. These are called the integer promotions。
在这种情况下,a必然会被转为int,然后再按位非。然后再右移5位。在此例中也就是一个负数右移5位。实际上这个答案是不确定的。因为C标准说:
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type
or if E1 has a signed type and a nonnegative value, the value of the result is the integral
part of the quotient of E1 / 2^E2 . If E1 has a signed type and a negative value, the
resulting value is implementation-defined.
最后一句说明负数的右移是由实现平台自定的,C标准不管。不过一般而言,大家都是会补符号位也就是-1,基本没有补0的。但C标准允许这种可能性。
所以a的值首先是个unsigned char,位非操作前转为int,位非变为负数,右移5位时右边一直补1,最后赋值给b的时候,再进行一个强制转型操作。
2楼2014-03-24 23:43:00
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

rbs

木虫 (小有名气)

【答案】应助回帖

引用回帖:
2楼: Originally posted by rbs at 2014-03-24 23:43:00
C标准里面有明确的说明:
Each of the operands shall have integer type.The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.
移位运 ...

上述的英文来源于
International Standard Programming languages C, ISO/IEC 9899, second edition
也就是C99标准。
3楼2014-03-24 23:45:23
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

adf2007

铁虫 (初入文坛)

【答案】应助回帖

感谢参与,应助指数 +1
我可以确定你有几点理解错了。
一、“不要小看 b=~a>>4 - ybdesire的专栏 - 博客频道 - CSDN.NET”这篇文章你没有仔细看。那篇文章有3个例子,第一个例子的反汇编没有写全,但是第一个例子确实提到了32这个数,应该是“申请了一个32位的临时变量x,将a扩展后,存入x”这句话让你误解了。通过看第二和第三个例子的反汇编,你就会发现,真正给unsigned char a分配内存空间的是第一句mov  byte ptr [ebp-4], 0A5h 。这一句分配了一个byte 的内存空间来存储0xa5,也就是1个字节8位。
二、你之所以迷惑是16位还是32位,是因为反汇编的后面几行代码,也就是把0xa5的值赋给通用寄存器的那句。你的QQ截图是赋值给了eax,你的书上说eax是16位;而"博客频道 - CSDN.NET"那篇文章赋值给了ecx或eax,那篇文章说它们是32位的。你要弄明白的有三点:1、通用寄存器存在于CPU中,它们具体是多少位是由硬件决定的。不同的CPU位数不一样的话,寄存器位数也不一样。2、针对这个题目,把0xa5放到通用寄存器里面,仅仅是为了后续的计算,或者说为了存储一些计算的中间变量。eax就是存储中间变量的,真正存0xa5的是byte ptr [ebp-4]这段内存。3、通用寄存器在CPU中,真正存放0xa5的是在内存中,这是两个完全不同的地方。你回想一下CPU和内存条就知道,完全是两个不同的硬件。平时所说的unsigned char 占一个字节,就是指在内存中存储时的大小。
三、稍微总结一下:程序运行的时候,数据、代码都在内存中放着;内存可以很大,可以存放很多东西。CPU中也有存放数据的地方,它们叫寄存器,寄存器数量很少,能存的数据也很少。寄存器只能帮助CPU完成简单的加减乘除等计算什么的,它们并不真的存什么。就好像考试的时候,内存相当于考试卷,寄存器相当于演草纸。题目都在考试卷上,但是每道题都得先写到演草纸上写写算算才能得出结果,然后再把结果写到考试卷上。

» 本帖已获得的红花(最新10朵)

4楼2014-03-24 23:58:29
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
信息提示
请填处理意见