查看: 2114|回复: 0
打印 上一主题 下一主题

C语言细节问题

[复制链接]
跳转到指定楼层
沙发
发表于 2014-11-29 19:26:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
C语言中的细节
1.1      “零值”比较
1.   写出float x 与“零值”比较的if语句。
首先要知道float是有精度的,不能直接与0相比较或者两数相减与0相比较。float能保留几位小数?
答案是6位。既然如此,那么就应该这么写:
  1. if((x > 0.000001) && (x < -0.000001))
复制代码

1.2      宏定义
1.   定义一个宏,返回X、Y中的较大值。
这个题目其实很简单,但是在很多笔试中都会拿出来考试,并且出错率很高,原因只有一个,
忽略细节(优先级的问题,实在搞不明白就加括号吧,你好理解,别人一看也懂)。终究还是细节决定成败。
  1. #define   MAX( (X) , (Y) )    ((X) >= (Y) ? (X) : (Y))
复制代码

2.   宏定义两个数相加
请问如程序清单5. 1输出什么?
程序清单5. 1  宏定义两数相加
  1. #define   DOUBLE(x) x+x
  2. int main(int argc, char* argv[])
  3. {
  4.     int iNumber = 0 ;
  5.     printf("%d\n" , 10*DOUBLE(10));
  6.     return 0;
  7. }
复制代码

其实这个程序非常简单,学习C语言一周就应该理解是什么意思,但是一般会出错的的地方都在细节。
其实这个程序输出是110。
可能有人会问,不是10先DOUBLE嘛,然后乘以10,不是200嘛。是啊,想法是好的,我想这个程序的“原意”也应该是这样,但是就是由于优先级的问题,打破了我们的愿望。如果要得到200,那么就应该是这样宏定义:
#define   DOUBLE(x) ((x)+(x))。我想,无论我加多少层括号都不算违法吧。

1.3      递归运算
1. 如程序清单5. 2所示,输出什么?
程序清单5. 2  递归运算
  1. #include <stdio.h>
  2. int func(int a)
  3. {
  4.     if (a==0)
  5.     {
  6.        return a;
  7.     }
  8.     printf("%d\n",func(a++/2));
  9.     return a;
  10. }
  11. int main(int argc, char *argv[])
  12. {
  13.     printf("%d",func(7));
  14.     return 0;
  15. }
复制代码

答案:0,2,4,8
这里把7送进去,那么func(a++/2),先执行7/2=3,然后a++ = 8,此时返回3;接着把3送进去,func(a++/2),先执行3/2=1,然后a++ = 4,此时返回1;接着把1送进去,func(a++/2),先执行1/2=0,然后a++ = 2,此时返回0;接着把0送进去,此时直接返回0,递归结束。
递归最容易忽略的细节是,由于递归次数过多,容易导致堆栈溢出。

1.4      让人忽略的贪心法
如程序清单5. 3所示,程序输出什么?
程序清单5. 3  贪心法
  1. int k = 8 ;
  2. int i = 10 ;
  3. int j = 10 ;
  4. k *= i+++j ;
  5. printf("%d \n" , k) ;
复制代码

贪心法,就是一次性能尽可能多得吃运算符,那么这里k *= i+++j ,
加上括号之后就是这样:k = k * ((i++) + j) ;这样的话就很简单可以得出答案为:160。

1.5      性能优化
1.   对如程序清单5. 4所示进行性能优化,使得效率提高。
程序清单5. 4  性能优化
  1. int iValue1;
  2. int iValue2;
  3. iValue1 = 1234/16;
  4. iValue2 = 1234%32;
复制代码
对于嵌入式进行除法是很消耗效率的,能使用移位完成最好使用移位完成。
  1. iValue1 = 1234 >> 4;
  2. iValue2 = 1234 – ((1234 >> 5) << 5);
  3. 1234 / 16 = 77; 1234 % 32 = 18。
复制代码
而十进制:1234转化成二进制:0100 1101 0010。1234 >> 4 = 0000 0100 1101,
转化为十进制即为:77;1234 >> 5 = 0000 0010 0110,((1234 >> 5) << 5)即为0100 1100 0000,
转化为十进制即为:1120,1234 – 1216 = 18。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表