现在的位置: 首页 > 综合 > 正文

编程时我们忘记注意的那些事(欢迎补充和修正)

2012年06月13日 ⁄ 综合 ⁄ 共 1631字 ⁄ 字号 评论关闭

1. for(; ; ){} 和 while(1){}的区别是什么?

答:从逻辑上看没什么区别,可是从汇编上来看还是有区别的,for明显比while要少几个汇编指令,因为while有一个判断1是否true的逻辑,for就没有了。

00F9138E  mov         eax, 1

00F91393  test        eax, eax

00F91395  je          wmain+30h (0F913A0h)

 

 2. 行和列相同的数组,如a[100][100]在遍历时,是优先选择行遍历还是优先选择列遍历?

答:数组在内存中是以连续的内存单元排列的,一般都是行优先,比如二维数组在内存中的排列顺序是a[0][0],a[0][1],a[0][2],a[1][0],a[1][1]...这就是行优先,有什么意义呢,如果纯粹用数组的下标来访问当然就不必考虑什么行优先,但是如果在某些特殊情况下要求性能比较苛求的情况,通过数组的首地址,在根据偏移量,在根据是行优先,可以直接计算出需要访问的下一个地址,相对于通过数组下标进行操作要快,因为不用重复计算数组的首地址,而是直接进行偏移计算就可以了,而通过数组下标访问每次都要计算一遍首地址。

 

3. 我们在进行自增或是自减时,是用 ++a(--a) 还是用 a++(a--)?哪一种比较好?

答:很多时候编程者都认为这两都没有什么区别。的确, 一般情况下这两者是没什么区别,可是,如果要考虑程序的运算效率的话,那我建议就最好用++a 和 --a。因为 a++ 和 a-- 在计算时不仅对 a 进行自增或自减同时还要对 a 的原始数据进行保存,这样在没有必要保存原始数据的时候就浪费了计算机的资源。

 

4. 为什么我们常常更愿意使用a<<N而去避免像a*(2^N)这样的操作呢?

答:其实更多的编程者前者用的还是比较多的,可能这就是先入为主的结果吧。不过这样不好,得改!为什么前者要优于后者?因为前者是对更底层的操作,只进行了N步的位左移 ;后者看上去只是一步乘法操作,可是要知道乘法的实质是加法操作,也就是说要有(2^N)步的加法操作才能完成。综上所述,前者要优于后者。而 a>>N 和 a/(2^N) 也是同样的道理。

 

5. 有时我们为了让代码更加简短,可能会做这样的一件事,那就是在循环条件里放置一个函数或是表达式的计算, 只是为了省下一条前期的赋值语句。不过要知道的是这样的做法是不明智的。原因就在于我们在循环条件里添加一个函数或是表达式就要在每次循环时都去计算那个函数或是表达式,这样不仅浪费时间还浪费了资源。不划算。例如下面的这两条代码:

SIZE= 1024
program 1:   time:29ms
     p = &a;
     for(int i = 0; i <  SIZE *sizeof(int); i++)
     {
          p = 1;
          p++;
     }
program 2:    time:1ms
    p = &a;
    len =  SIZE *sizeof(int);
    for(int i = 0; i < len; i++)
    {
          p = 1;
          p++;
     }

 

6. i++; 和 i = i + 1;有什么区别没有?

答:有!而且很大。因为我们在计算i++时,cpu只对内存进行了一次取i的访问,可是在计算i = i + 1时,我们的cpu对内存的访问有两次,这样没有必要的访问操作是我们不情愿看到的。所以还是能免则免吧。

 

7. double型的参数很难取到0这个精确值,为什么?要怎么处理?

答:double型的参数或是表达式中,我们很难计算得出0这个答案,因为double型的值不精确的,我们在处理的过程中利用了这样的一种思想:极限。我们可以自行去规定一个精确度来限定当我们的double型参量在我们定义的精确度内就认定这个值是精确的。例如:double t = b*b - 4*a*c;相信大家都很熟悉这个表达式,这就是一元二次方程中根的判别式,当若你这样写if(t==0){两个相等的根;},那可能会吃亏,因为double型有数不精确,我们可以这样来写if (fabs(t) < 1e-8){t = 0.0;两个相等的根;}.我们认为t在小于0.00000001时让它等于零来解决这个问题。

 

 

 

抱歉!评论已关闭.