美文网首页
《C陷阱与缺陷》笔记

《C陷阱与缺陷》笔记

作者: DayDayUpppppp | 来源:发表于2019-01-09 11:54 被阅读0次
第一章 词法陷阱
  1. 整数常量
      int a = 010;      //如果整数常量的第一个字符是0开头的,那么该常量表示的是八进制
      int a = 10;
      //上面两个定义是完全不一样的,第一个是八进制表示的。
    
第二章 语法陷阱
  1. 理解函数声明

    float f;
    float f();
    float *f;
    float *f();
    float (*f)();
    
    float (*f)();   //函数声明,函数的参数是void,返回值是float
    (*f)();    //执行对应的地址的函数
    
    (float (*)())  
    //"指向返回值是float参数是void的函数指针的"的类型转换符
    
    // typedef 简化函数指针类型
    float add(float a,float b)
    {
        cout<<a<<"  "<<b<<endl;
        return a+b;
    }
    
    typedef float(*pfunType)(float, float);
    
    int main()
    {
        pfunType p = add;
        p(3.33, 2.22);
        return 0;
    }
    
  2. 注意作为结束语句的分号
    if之后不小心多写了一个分号

    if(a>b);   //一不小心多写了一个分号
    a = 100;
    

    那么,代码变成

    if(a>b) {  }
    a = 100;
    
第三章 语义陷阱
  1. 指针与数组
  • 声明

    int * p;
    int arr[];
    
  • 定义

    int * p = &val;
    int arr[]=[1,2,3,4,5];
    
  • sizeof

    char * p = "1234567";
    sizeof(p);   // 4 ,指针的大小
    strlen(p);    //
    
    char arr[]="1234567";
    sizeof(arr);   //8,字符串的真实的大小,包含最后的\n
    
  1. 非数组的指针
    char * p = NULL;
    //试图打印内存地址是0的内容
    printf("printf null addr : %s \n",p);     //这个行为是未定义的,取决于不同的编译器的实现方式
    
第四章 连接
  1. 检查外部类型

    • 分析下面的代码:
      file_a.c

      int val = 100;
      

      file_b.c

      extern char val;
      cout<<val<<endl;
      

      文件的定义的类型和外部声明的类型,不一致,会出现什么情况?

      大多数编译器不能检出这样的错误,所以,这是一种很危险的行为。尤其是下面的这个情况

      char  p[] = "1234567";   //定义是数组,却声明为指针
      
      char * p;   //定义是数组,却声明为指针
      cout<<p[1]<<endl;    //妥妥的core掉
      

    原因:

  2. 头文件

    • 头文件的“比较科学”写法:
      头文件只写对应.c文件里面的变量声明
//head.h
extern int config_ip;
extern int config_pwd;
int config_ip;
int config_pwd;

static int val;   //不对外部可见
第六章 预处理

基本用法:

#宏常量
#define num 100

#宏函数
#define max(a,b)  return a>b?a:b
#define swap(a,b) \
  int tmp = a;\
  a = b;\
  b = tmp;

但是,宏的本质是文本替换,但是在很多场景下面会出现问题。用inline和const更加安全一点。

#define max(a,b) a>b?a:b

max(a,b)+1;
//替换之后,a>b?a:b+1       //和原来的有一些歧义,在某些case上面是错误的。
  1. typedef (类型定义)与宏的区别

    • 区别1: 比宏更加安全的定义
    typedef char* PCHAR;
    PCHAR pa,pb;  // = char * pa;char * pb;
    
    如果写成宏的话,可能是这样
    #define PCHAR char
    PCHAR pa,pb;   // = char * pa,pb; //= char * pa; char pb;
    
    • 区别2:用在旧的C代码中,帮助struct。
    // 用在旧的C代码中,帮助struct。以前的代码中,声明 
    // struct新对象时,必须要带上struct,
    // 即形式为: struct   结构名对象名,如:
    struct tagPOINT1
    {
      int x;
      int y; 
    } ;
    struct tagPOINT1 p1;
    
    //而在C++中,则可以直接写:结构名对象名,即:        
    tagPOINT1 p1;
    typedef struct tagPOINT
    {
      int x;
      int y;
    }POINT;
    POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,
    
    • 区别3:
      在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。
    原声明:int *(*a[5])(int, char*);
    变量名为a,直接用一个新别名pFun替换a就可以了:
    typedef int *(*pFun)(int, char*); 
    原声明的最简化版:
    pFun a[5]; 
    
    • 关于typedef


      image.png

相关文章

  • C语言中的词法陷阱

    该文章为笔记,因此许多内容摘抄自《C陷阱与缺陷》。《C陷阱与缺陷》,全书不厚,但是感觉十分有提醒与启迪作用,值得阅...

  • 第03章 语义"陷阱"

    《C陷阱与缺陷》 Andrew Koenig) 阅读笔记 部分资料来自网上(内附链接) 3.1 指针与数组 注意:...

  • 《C陷阱与缺陷》笔记

    第一章 词法陷阱 整数常量 int a = 010; //如果整数常量的第一个字符是0开头的,那么该常...

  • 第02章 语法"陷阱"

    《C陷阱与缺陷》 Andrew Koenig 读书笔记 附录来自网络 2.1 理解函数的声明 2.1.1 如何声...

  • 第01章 词法"陷阱"

    《C陷阱与缺陷》 Andrew Koenig 读书笔记 1.1 =和== 编写时建议:将变量放到==的后方,编译器...

  • 书籍推荐

    1.《C primer plus》----《C程序设计语言》-----《C和指针》、《C专家编程》、《C缺陷与陷阱...

  • 《C陷阱与缺陷》读书笔记

    词法分析中的“贪心法” 每个符号应该包含尽可能多的字符。a---b等同于(a--)-b。a+++++b被编译器视为...

  • 《C缺陷与陷阱》读书笔记

    最近因为工作需要开始重新拾起C语言,虽然说基本语法什么的没有太大问题(不行就网上搜索),但复习巩固下C语言也是不错...

  • 《C陷阱与缺陷》读书笔记

    多字符记号 输入流到给定字符串,识别成记号后,会尽可能包含之后字符构成最长字符串作为记号 组合赋值运算符是两个记号...

  • C陷阱与缺陷--读书笔记

    神奇的函数声明 float *g(), (*h)(); 这里先拆开来看float * g(); 这样就很容易看出来...

网友评论

      本文标题:《C陷阱与缺陷》笔记

      本文链接:https://www.haomeiwen.com/subject/kqcbrqtx.html