我正在使用CodeVisionAVR Evaluation V2.05.0,它使用C编译器参考。我在尝试此代码时遇到了问题:
unsigned int n;
long int data;
data|=(1<<n);
问题是当n大于15时,数据值不会改变。虽然当我尝试:
data|=(1<<16);
结果是正确的。 任何帮助请求。
答案 0 :(得分:0)
在您的代码中,1
的类型(一如既往)int
。因此,如果sizeof (int)
小于sizeof (long)
,则表明您无法将int
移到long
的所有位上。
解决方案当然是使用(无符号)长常量:
data |= 1UL << n;
我使它无符号,因为无符号整数更适合按位运算符。文字1UL
的类型是unsigned long
。我发现使用后缀比使用更好的后缀,因为它更短,是文字本身的一部分,而不是有一个错误类型的字面值并投射它。
很多人似乎都希望用这样的表达方式:
unsigned long long veryBig = 1 << 35; /* BAD CODE */
右侧应该以某种方式神奇地适应左侧的“需要”,因此变成类型unsigned long long
(我假设它至少有35位,这当然不是便携但很简洁)。这不会发生,C不会那样工作。表达式被计算,然后它被转换(如果需要)到左边的类型,以使赋值工作。
答案 1 :(得分:0)
如果sizeof(int)==2
,则1<<n
的类型为int
。并1<<16 == 0
。因此data
不会改变。
答案 2 :(得分:0)
可能是因为int
是16位。当您使用整数文字时,编译器可以计算出结果大于int
中的拟合,并且会优化整个移位操作,但是当您使用变量时,编译器无法做到因为它不知道n
的价值。
答案 3 :(得分:0)
我要感谢大家,通过你的回答,我真的理解了这个问题
(1<<n)
中的1是整数,大小为2个字节。
我通过让1为无符号长(1UL<<n)
来解决问题。
这是我的第一个问题,你是很棒的家伙。
谢谢你,我很抱歉我的英语不好。