C语言中的“陷阱”

有符号数和无符号数

假设我们需要定义一个变量用于存放ADC采样得到的数据,假定门限阈值是100,低于100的数值认为是噪声,那么我们需要如下的代码来做判断:

//满洲里国峰电子科技
#define THRESHOLD 100
char ADCSamples_1=255;
unsigned char ADCSamples_2=255;

if(ADCSamples_1>THRESHOLD)
  printf("ADCSamples_1>THRESHOLD\r\n");
if(ADCSamples_2>THRESHOLD)
  printf("ADCSamples_2>THRESHOLD\r\n");

代码中假设ADC采样到的数值是255,并分别定义了两个变量,看一下有符号和无符号变量的影响。运行结果:

ADCSamples_2>THRESHOLD

原因是:有符号数的首位代表符号,char型数值范围是-128~127,所以255代表-128,是负数,比阈值100小。这样的细节在编程中要注意,否则会引起判断错误,上例中如果用char型存储采样数值,那就会将有用的数值(255)当做噪声处理(门限阈值之下认为是噪声)。

注:为什么255代表-128而不是-127,因为现代计算机采用补码运算,正数的补码是其原码本身,负数的补码是反码+1。

if语句中的判断A<x<B

在日常的数学表达式中,我们通常使用A<x<B这样的表达式,但在C语言中却不是这样的方式:

//错误代码范例
#define MIN 10
#define MAX 100
unsigned char ADCSample;

ADCSample=GetADCValue();//伪代码,读取ADC数值。
if(MIN<ADCSample<MAX)
	SaveADCValidSampleToBuff();//在MIN和MAX之间的数据认为是有效数据,存入缓存
//Copyright (C) 满洲里国峰电子科技 

上述代码是错误的,错在if语句中的判断条件,正确的表达如下:

//错误代码范例
#define MIN 10
#define MAX 100
unsigned char ADCSample;

ADCSample=GetADCValue();//伪代码,读取ADC数值。
if((MIN<ADCSample)&&(ADCSample<MAX))
	SaveADCValidSampleToBuff();//在MIN和MAX之间的数据认为是有效数据,存入缓存
//Copyright (C) 满洲里国峰电子科技 

数组中冗余的元素

有些数组为了满足不同情况的需求会设置的长度比较大,这样在某些情况下,该数组是冗余的。但是如果不小心,会产生Bug。

//将ADC采样的数值ADCSample在液晶屏上显示出来。
char DispBuff[20];//用于存储采样数值的每位数字和小数点。
main()
{   
  while(1)
  {
    TurnOnADC();//开始采样
	if(THRESHOLD<ADCSample)
	{
		sprintf(DispBuff,"%.2f",ADCSample);//将采样数值转换成字符存入数组中。
		for(i=0;i<5;i++)
			DispChar_EN(dispBuff[i]);//将采样数值在屏幕上显示出来。							
	}
  }
}

使用上面的代码会出现Bug,发现程序会停止,不再while中循环采样显示了,原因是在显示的时候,我们显示了5位,而在sprintf中我们保留了2为小数点,若ADCSample为1.23,则第五位的数值是未知的,其对应的字符也未知,而DispChar_EN()函数找不到对应的字符就会产生错误,导致程序异常。

中文输入法

在代码的注释时,常常会使用中文,但是在写代码的时候如果操作不当,会在输入分号的时候采用了中文输入法的分号,这时程序会报错。

这样类似的问题还有很多,今天就先到这里啦,以后慢慢补充~

作者:伏熊(专业:射频芯片设计、雷达系统、嵌入式。欢迎大家项目合作交流。)
微信:GuoFengDianZi

发布了43 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/mzldxf/article/details/104726690
今日推荐