[C] C Traps and Pitfalls 读书记录

使用errno.h检测错误

当库文件调失败的时候,比如fopen没有相应文件,malloc没有内存等等时,就会设置errno。引用errno.h(cerrno)的时候就会有一个全局变量errno。 还可以perror,strerror使用。我们可以先判断错误之后,在检查errno找出原因。

#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
int main(void)
{
    /*调用errno之前必须先将其清零*/
    errno=0;
    FILE *fp = fopen("test.txt","r");
    if(fp==NULL)
    {
  perror("Error");
        printf("errno值: %d\n",errno);
        printf("错误信息: %s\n",strerror(errno));
    }
}

使用Signal检查

信号是某种意义上的异步,可以在程序执行期间的任何一个时刻发生。有SIGABRT,SIGINT等等,可以去查询,也可以自定义信号。下面程序可以检测在程序被Ctrl+C中断。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <csignal>
#include <unistd.h>

void sighandler(int signum)
{
   printf("Caught signal %d, coming out...\n", signum);
   exit(1);
}

int main()
{
   signal(SIGINT, sighandler);
   while(1) 
   {
      printf("Going to sleep for a second...\n");
      sleep(1);
   }
   return 0;
}

 

getchar()实际上是#define getchar() getc(stdin)的宏定义。当然很多编译器也写了getchar()的函数。当然putchar也有宏定义。

宏定义在类型定义时出现问题

#define ElemType struct foo
ElemType a,b;

但是当为指针时,会变成一个指针和一个变量。

#define ElemType struct foo *
ElemType a,b;
struct foo *a,b;

词法分析中的贪心法

在C中有/,*,=等单字符符号,也有/*,==等多字符符号,词法会选择当前情况下能够组合的最长的组合情况,因此a—b与表达式 a– -b的含义相同。