本帖最后由 刘前辈 于 2011-3-5 19:28 编辑
比如位域pin.b_1只有一位,但为什么按位取反后会得到0xFE呢??在ARM7上得到的又是0xFFFFFFFE呢??
看来前辈的联想能力一流,有些话一直没说,说多了反而让人质疑。
第一,ANSI C 规定:位段结构是把16位的整型变量按位段定义成结构。举例:
struct
{
uchar b_1: 1;
uchar b_2: 1;
……
uchar ……
uint m: 8;
}pin=(1,0,……120};
C51上按LZ的写法定义了8位uchar 当然可以,( 8位机上可以移植)ANSI C 写法标准应该是16位,新的C标准有没有规定32位位段结构前辈还不知道。
ARM一个int 如果32位,那么一个位段结构32位(不严格按照ANSI C)也能理解。看编译器自己怎么做方便了。
现在的问题: ~pin.b_1=0xFFFFFFFE ;
太好理解了,我前面说一个单个pin.b_1 连“运算对象”都不算,它提升个啥?(仔细看整提升定义:什么叫运算对象:只有运算对象才需要整类型 int 提升!)
而现在你是 ~ pin.b_1 , ~ 是运算符,运算符后面的当然是运算对象,它可能提升(新的概念叫类型转换),也可能不需要提升,取决于它当前的类型是不是整类型 int 。你定义的是uchar, 所以ARM编译器规则需要转换为 int ,成为0x00000001;按位取反等于0xFFFFFFFE。
所以这里好几个需要理解的问题:
1、没有运算符的表达式pin.b_1 , 不是运算对象。
2、~ 是运算符。它后面的pin.b_1,是运算分量。
3、提升(转换)是较小的类型对象在“该用 int 类型的地方。”的扩展应用。
4、这种转换并不影响 运算对象的值。
5、写成更标准的形式,应该是:
struct
{
int b_1: 1;
int b_2: 1;
……
……
}
、 |