读书笔记--C陷阱与缺陷(七)

第七章

      1.null指针并不指向任何对象,所以只用于赋值和比较运算,其他使用目的都是非法的。

      误用null指针的后果是未定义的,根据编译器各异。

      有的编译器对内存位置0只读,有的可读写。

      书中给出了一种判断编译器如何处理内存0的代码:

 1 #include <stdio.h>
 2     int main()
 3 {
 4 
 5     char *p;
 6     p=NULL;
 7     printf("location 0 contains: %d
", *p);
 8 
 9     return 0;
10 }

在禁止读内存0的机器上,程序会执行失败。有的机器上,却可以10进制打印内存0存储的字符内容。

      笔者试了下codeblocks,程序执行失败,即禁止读内存0.

  2.移位运算符

      在向右移位时,会考虑空出的位是0填充,还是符号位填充?

      如果移位对象是无符号数,毫无疑问是0填充;若是有符号数,可以是0填充也可以是符号位。

      具体负数的移位操作下次专门写一篇。

      移位操作的位数限制在被移位对象的长度内。

      即若int型是32位,n是int型,那么[0-31]的移位时合法的:n<<31, n<<0

  3.大小写转换

      库函数 toupper  tolower起初被定义为:

      #define toupper(c) ((c)+'A'-'a')

      #define tolower(c) ((c)+'a'-'A')

      但是这个宏定义没考虑输入的大小写是否正确。

      如下程序将不能工作:

      int c;

      while ((c)= getchar() != EOF)

           putchar(tolower(c));

      应该改为:

      int c;

      while ((c)= getchar() != EOF)

           putchar(isupper(c) ? tolower(c) : c);

      或者重写函数,如 toupper:

int toupper (int c)
    {
        if (c >= 'a' && c <= 'z')
            return c + 'A'-'a';
        return c;
    }

      这样的程序更加健壮,就是函数调用相比宏定义更加浪费开销。

  至此 C陷阱与缺陷 的读书笔记就结束了,感觉该书知识有点旧但讲的很有深度,对于大型C项目和多平台项目有启发!

原文地址:https://www.cnblogs.com/chenzhefan/p/7518233.html