《C陷阱与缺陷》笔记

272 阅读1分钟

P16

分析(*(void(*)())0) ();

  第一步:拆分(*(void(*)())0)()。说明这是一个函数,函数没有传入参数,而函数入口是前者指针所指向的地址。
  第二步:继续拆分可分为两部分,(void(*)())(*0),后者表示,对取地址0的内容,在本式中该地址内容就是函数的入口,而前者就是一个强制类型转换
  第三步:分析(void(*)()),它所修饰的变量表示“一个返回值为空的函数指针”。结合第二步,所以0就是一个“一个返回值为空的函数指针”。
   综上所述,该语句表示执行0地址的函数。 若用typedef可以简化语句。

    typedef void(*A)();
    (*(A)0) ();

P38

有两个字符串s和t,将其连接成单个字符串r?

    char *r;
    r = malloc(strlen(s) + strlen(t) + 1);
    if (!r){
        exit(1);
    }
    strcpy(r, s);
    strcat(r, t
    //用完后);
    free(r);

该程序有三个细节值得注意:

  • 使用malloc函数申请完内存后,需要检查申请是否成功
  • 字符串最后会以/0结尾,所以申请内存的时候需要多申请一个字符空间。
  • 使用完申请的内存空间后,需要释放掉,防止内存泄漏。

P61

判断两个非负整数相加是否溢出

    //错误,当发生溢出时,所有关于结果如何的假设都不再靠谱
    if(a + b < 0)
        complain();
    //正确
    if((unsigned int)a + (unsigned int)b < INT_MAX)
        complain();
    //正确
    if(a < INT_MAX - b)
        complain();