C 的那点事儿

一、预处理
    定义:在编译之前所做的处理,主要包括:
                        头文件(预处理会展开)、宏定义(预处理会替换掉)、条件编译
    
二、头文件
    作用:将一些公用代码,如函数原型声明,类型声明,全局变量声明,宏定义等,放到一个文件中,以提供跨工程代码复用,减少代码重复书写。
    处理方式:内容展开(若头文件中有递归包含逐级展开)
    能否重复包含:不能,容易出现重复定义
    可以使用条件编译,如下方式加以解决
    #ifndef  宏
    #define 宏
    
    #endif
    
    #include  <>:编译器去系统默认指定目录查找
    #include“”:编译器先在当前目录查找,找不到再去系统默认目录

三、宏定义
    定义:用一个简单易记的字符集合代替复杂的内容
    格式:#define  字符集合   内容
    处理方式:简单的完全的字符替换
    优点:增强代码可读性,提高可移植性
    注意:以下两行是不等价的【见3.c】

#define IP int *     //预处理前替换掉    IP a,b 指:int*a;int b不等价
typedef int *  ip;   //编译时  ip   a,b  指:int*a; int* b;
             
    带参宏:
    1、整体的返回值要添加括号
    2、使用参数时也要添加括号

四、关键字
   【typedef】
         作用:给类型起别名,可以提高代码的可移植性
        1、typedef int ** ipp;
        2、typedef int (*a2p)[5];
        3、typedef int (*fp)(int, int);
  【static】
        1、static修饰局部变量
        延长局部变量的生命周期至整个程序
        2、static修饰全局变量
        限定了全局变量的作用域为当前定义的源文件
        3、static修饰函数
        限定了函数的使用范围为当前定义的源文件

        总结:static虽然限定了全局变量和函数的作用域,
                        但是其它源文件可以定义同名变量或函数。
  【const】
        1、const int *a 和 int const *a
        a的指向可以改变,a指向的内容不可改变
    
        2、int *const a
        a的指向不可改变,a指向的内容可以改变

        3、const int *const a
        a的指向不可改变,a指向的内容也不可改变

    1、const int *a; int b; a = &b; *a = 100;  错
    2、int *const a; int b; a = &b; *a = 100;  错
    3、int b; int *const a = &b; *a = 100;   对
    
    如果有const int *a;int *b;那么语句a=b;是否可行?
    反过来b=a;又是否可行?为什么呢?
    
    结论:const指针不可以通过地址改变数据,而非const指            针可以通过地址修改数据,所以在指针变量赋值时只能            是非const指针赋值给const指针,反过来则有风险。

    总结:const修饰谁,谁就不可改变

五、条件编译
    定义:给某段代码指定编译条件
    处理方式:条件成立参与编译,条件不成立相当于删除
    格式一:注释成块代码
    #if 表达式

    #endif

    格式二:测试代码
    #if 表达式

    #else

    #endif

    格式三:
    #ifdef 宏

    #endif

    格式四:
    #ifndef 宏

    #endif

六、复杂的指针声明
    1、二级指针(多级指针)
            int a = 250;
            int *p = &a;
            int **q = &p;
            p <===>  &a
            *p <==>  *(&a) <==> a
    
            q <===> &p
            *q <==> *(&p) <==> p <==> &a
            **q <==> *p <==> a
            总结:&使数据埋藏的更深,*使数据重见天日
    2、指向二维数组的指针
            int a[5];
            int *p = a<==> &a[0]
            
            int a[2][5];
            int [5]  *p =>  int (*p)[5] = p=a=&a[0]
            a+1 <==> p+1 <==> &a[1]
            *(p + i) <==> &a[i][0]
            &a[i][j] <==> *(p+i)+j
            a[i][j] <==> *(*(p+i)+j)
    3、函数指针
            void test(int a, char *b);
            void (*p)(int, char *) = test;
            p(250, NULL);

    总结:作为函数参数的时候使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值