一种数码管表示方法
#include <at89x51.h>
unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char *str=&tab[9];
void delay();
main()
{
while(1)
{
P2=*str--;
delay();
if(*(str+1)==0x3f)
str=str+10;
}
}
void delay()
{
int i,i;
for(i=0;i<1000;i++)
for(j=0;j<115;j++);
}
是不是很有意思?
屏蔽数码管间的干扰
void delay(int k)
{
while(k--);
P2=0;//抗干扰?
}
1.1运算符优先级引发的问题
int func(int n)
{
return n<<1+1;
}
上述代码中的函数func本意是期望计算2n+1,但程序实际运行结果是4n。C/C++语言规定运算符“+”的优先级高于运算符“<<"。因此上述代码等同于return n<<(1+1),所以会先进行加法运算,再进行移位运算,得到结果4n。这里,移位运算一位,等于该数乘以2的该数次方!!!
1.2不加括号的宏定义引起的错误
#define PERIMETER(X,Y) 2X+2Y
#define PERIMETER(X,Y) (2(X)+2*(Y))
1.3污染环境的宏定义
宏定义乱用,维护和拓展后,编译虽能通过,但鬼知道哪里重复了,进而引起极大麻烦。
1.4多语句宏定义
#define EXIT(info) std::cerr<<info<<std::endl;exit(1)
看似没有问题,但当在某些情况下缩进排版后,问题大大的有,例如:
if(data<0)
EXIT(“data is anagative number!”);
正确缩进后变为:
if(data<0)
std::cerr<<info<<std::endl;
exit(1);
显然exit语句不在if分支语句块中,所以,它必被执行!!!
因此最好:
#define EXIT(info) {std::cerr<<info<<std::endl;exit(1)}
拿个大括号框起来!或者采用内联函数的方式
1.5char转换为int时高位符号扩展问题
int main()
{
char a=0x9A;
int util;
util=(int)a;
if(util>0)
printf("positive\n");
else
printf("negative\n");
}
代码中,char变量a的值为0x9A,此值简直坑爹!一般我们设为char a=‘A’;或char a=97;
实际上0x9A的二进制表示为10011010,在强制转换为int时,因为int是有符号的,需要对10011010进行符号拓展,也就是用其最高位1来扩充其他3个高字节,变成11111111 11111111 11111111 100011010(假设int是4个字节),而这个是负数-102的二进制补码表示。所以在判断util是否小于0时就会输出”negative“
正确代码:
int main()
{
char a=0x9A;
int util;
util=(int)(unsigned char)a;
if(util>0)
printf("positive\n");
else
printf("negative");
}
先把a强制转换为unsigned char,这样0x9A才会被解析为154!