2018年11月26日

一种数码管表示方法

#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) 2
X+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!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值