[Expert C Programming] Notes (一)

第一条:.如果你是位有经验的程序员,在比较式中你应该这样写if(3==i)(有经验的写法),而不是if(i = 3)(错误写法)或者if(i == 3)(正确写法),因为如果你误用了赋值符号,编译器会发出"attempted assighment to literal(试图向常熟赋值)"的错误信息。

...............................................................................


第二条:关于计算机日期

#include <stdio.h>   
    #include <time.h>   
    int main(void)   
    {   
        time_t biggest = 0x7FFFFFFF;   
        printf("biggest = %s/n",ctime(&biggest));   
        return 0;   
    }

下面我来解释下这段程序(书上没有!)
关于time_t(From Wiki): The time7 _t datatype is a data type in the ISO C library defined for storing system time values. Such values are returned from the standard time() library function. This type is a typedef defined in the standard <time.h> header. ISO C defines time_t as an arithmetic type, but does not specify any particular type, range, resolution, or encoding for it. Also unspecified are the meanings of arithmetic operations applied to time values.

time_t是long的typedef形式,当然你可以使用下面的代码来测试下它在你机器中所占的字节数:

#include <stdio.h>   
    int main(void)   
    {   
        printf("%d",sizeof(time_t));//输出为4,所以占用4字节   
        return 0;   
    }

现在咱们再回过头来看上面的上面那段程序,它的输出结果为 Tue Jan 19  11:14:07 2038

ctime把参数转换成当地时间,但是它和格林尼治的时间并不一致,取决于你所在的时区,所以上面的程序是错误的,应该用gmtime()函数来取得最大的UTC时间值,由于这个函数并不返回参数,所以再用asctime()函数来获取一个这样的字符串。

修改过的程序如下:

#include <stdio.h>   
    #include <time.h>   
    int main(void)   
    {   
        time_t biggest = 0x7FFFFFFF;   
        printf("biggest = %s/n",asctime(gmtime(&biggest)));   
        return 0;   
    }

现在的结果为Tue Jan 19  03:14:07 2038

................................................................................

第三条:编译器设计者的金科玉律:效率(几乎)就是一切。

    编译器的效率包括两个方面:运行效率(代码的运行速度)和编译效率(产生可执行代码的速度) ...运行效率起决定性作用。

    优化措施:清除无用代码,忽略运行时检查,这些既能缩短编译时间,又能减少运行结果,不利之处在于可能无法发现程序中无效的运行结果。

  ................................................................................

第四条:关键字const并不能把变量变成常量!在一个符号前加上const限定符只是表示这个符号不能被赋值,也就是它的值对于这个符号来说是只读的,但它并不能防止通过程序内部(甚至外部)的方法来修改这个值。const最有用指出就是用它来限定函数的形参,这样该函数将不会修改实参指针所指的数据,但其他的函数却可能会修改它。

看段代码:

#include <stdio.h>  
    int main(void)  
    {  
        const int limit = 10;  
        limit = 6;     //wrong  
        printf("%d/n",limit);  
    }


上面的代码明显错误的,但是你继续看下面的代码:

#include <stdio.h>  
    int main(void)  
    {  
        int limit = 10;  
        const int *limitp = &limit;  
        int m = 27;  
        limitp = &m;  
        printf("%d",*limitp);  
        return 0;  
      
    }

上面的代码可以通过,且值被修改,这说明limitp是一个指向常量整形的指针,这个指针不能用于修改这个整形数,但是任何时候,这个指针本身的值却可以改变。这样,它就指向了不同的地址,对它进行解除引用操作时会得到一个不同的值!

  ................................................................................

第五条:先看下面一段代码,你认为它会编译通过吗?先不用用编译器运行!

#include <stdio.h>  
    int main(void)  
    {  
      int array[] = {23,14,12,17,204,99,16};  
      #define TOTAL (sizeof(array)/sizeof(array[0]))  
      int d = -1,x;  
      if(d<=TOTAL-2)  
      {  
          x = array[d+1];  
      }  
      return 0;  
    }

运行结果为:/hello/main.cpp|7|warning: comparison between signed and unsigned integer expressions|

其实这段代码有个bug,因为TOTAL所定义的值是unsigned int类型(因为sizeof()返回类型是无符号数)。if语句在signed int和unsigned int之间测试相等性,所以d被升级为unsigned int类型,-1转换成unsigned int的结果将是一个非常大的正整数!致使表达式的值为假!

解决这个问题,其实只要对TOTAL进行强制转换即可:

看下面的这段修改后的代码:

Code:
  1. #include <stdio.h>  
  2. int main(void)  
  3. {  
  4.   int array[] = {23,14,12,17,204,99,16};  
  5.   #define TOTAL (sizeof(array)/sizeof(array[0]))  
  6.   int d = -1,x;  
  7.   if(d<=(int)TOTAL-2);  
  8.   {  
  9.       x = array[d+1];  
  10.   }  
  11.   return 0;  
  12.   
  13. }  

上面的代码就可以通过了!

我们再看下这条代码:

#define TOTAL (sizeof(array)/sizeof(array[0])) 

而不推荐使用 #define TOTAL (sizeof(array)/sizeof(int)) 

因为前者可以在不修改#define语句的情况下改变数组的基本类型(比如把int变成char)。

  ...............................................................................

第六条:对无符号类型的建议

尽量不要使用无符号类型,以免增加不必要的复杂性。尤其是,不要仅仅因为无符号数不存在负值(如年龄和国债)而用它来表示数量、


[Expert C Programming] Notes (二)



原文链接: http://blog.csdn.net/crazyjixiang/article/details/6465995

转载于:https://my.oschina.net/chen106106/blog/51158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值