C语言总结

c语言仅为开发unix而生 为高效而生
c++为面向对象语言而生 兼容已有的代码
系统一般由多种语言写成的

数据类型和变量:
    数据类型是一个模子,操作变量就是操作空间
    char short int
    typedef用法:
        typedef int INT32
        typedef unsigned char BYTE
        typedef struct _demo
        {
            short s;
            BYTE  b1;
            BYTE  b2;
            INT32 i;
        }DEMO;
        
        
属性关键词:
    变量定义前可以加属性关键词
    auto:
        变量存储在程序的栈里 变量的值是变的
        局部变量默认auto类型
    static:
        局部变量存储于程序的静态区
        文件作用域标识符
            修饰的全局变量作用域只在声明的文件当中
            修饰的函数作用域只在声明的文件当中
    register:
        指明变量存储于寄存器里
        只是请求寄存器变量 但不一定请求成功
        
        register变量必须是CPU寄存器可以接受的值
        不能用&获取register变量的地址
        
        用在实时性能要求比较高的系统里
        
        只会被初始化一次
        
        
语句用法:
    if - else:(两路分支)
        if的条件是逻辑上的值
        
        bool型变量不能直接在条件里面进行比较
        普通变量和0比较 0值应该出现在比较符号左边(避免BUG 防止写成赋值符号)
        float不能直接进行0值比较 需要定义精度
        
    switch:(多路分支)
        case语句分支必须有break 否则会导致分支重叠
        default语句有必要加上 以处理特殊情况
        
        case 语句中的值只能是整型或字符型
        顺序分析:
            按照字母或者数字排列各条语句
            正常情况放前边 异常情况放后面
            default 语句只能用于处理真正的默认情况
            
        if用于范围判断比较适合
        
    循环语句:
        do while for
            do - while 至少执行一次
            用do - while(0)在只执行一次的场合(申请内存 释放内存 避免内存泄漏)
            
            使用while时一定要注意条件是什么
        
        
    break 表示终止循环的执行 跳出块
    continue 表示中值本次循环体 进入下次循环执行
    

关键字分析:
    goto:
        禁用goto 打入冷宫
        
    void:
        修饰函数的返回值和入口参数
        不能定义变量类型
        
        只有相同类型的指针才能相互赋值 void指针可以作为左值用于接收任意类型的指针
        
        用void* 作为函数的入口类型可以接收任意类型的指针参数
        
    extern:
        声明外部定义的变量和函数
        用于告诉编译器c方式编译 extern"C"
        
    sizeof正名:
        编译器内置的指示符 不是函数
        计算相应的实体所占的内存大小
        其值在编译期就已经知道结果了
        
        sizeof int;     是不允许的
        sizeof (int);     是允许的
        所以统一写成了sizeof(); 被冤枉成为一个函数了
        
    const:
        const只对编译器有用 运行时无用
        变量会占用内存空间 用指针操作地址还是可以改变值的  const类型的数组的值也会被改变
        const修饰的变量是只读的 本质还是变量
        
        const修饰指针:
            const int* p;
            int const* p;
            int* const p;
            const int* const p;
            
            左数右指 不变
            当const出现在*号左边时指针指向的数据为常量
            当const出现在*号后右边时指针本身为常量
            
            const修饰函数参数表示在函数体内不希望改变参数的值
            const修饰函数返回值表示返回值不可变 多用于返回指针的情形
            
    volatile:
        编译器警告指示字
        告诉编译器必须每次去内存中取变量值 不做优化
        修饰可能被多个线程访问的变量
        修饰可能被未知因数更改的变量
        
        
    enum:
        enum是一种自定义类型
        enum默认常量在前一个值的基础上依次加1 第一个值默认为零
        enum类型的变量只能取定义时的离散值
        
        define宏只是简单的替换 无法被调试 是一种特定类型的常量
        
    typedef:
        给一个已经存在的数据类型重命名
        没有产生新的类型
        不能进行signed unsigned进行拓展
        
        define只是字符串的替换 无别名的概念
        
        
符号的技巧:
    注释:
        编译器在编译的时候 会将注释删除同时用空格替代
        编译器认为双引号括起来的内容都是字符串 双斜杠也不例外
        /*......*/ 型的注释不能被嵌套
        
        /*作为一段注释的开始 直到遇见*/
        
        准确易懂简洁 提示准确 阐述原因
        
    接续符和转义符:
        接续符 \:
            指示编译器行为的利器 继续下一行的内容
            注意加空格
            接续单词的时候注意不能加空格
            
            define必须在一行内结束 用接续符实现定义代码块
        
        转义字符 \:
            表示无回显字符
            \n 换行
            \t tab
            
            出现在字符或者字符串当中
        
    单引号&双引号:
        单引号 表示字符常量   代表整数
            'a' 一字节
            'a' + 1 = 'b'
        双引号 表示字符串常量 表示一个指针
            "a" 二字节
            "a" + 1 = '\0' (指针操作)
        不能将字符 和 字符串 赋值 和 比较
        
    逻辑运算符:
        短路规则:
            ||从左到右计算 为真停止
            &&从左到右计算 为假停止
        
        ! :
            "!" 只认得0 见到0 返回1
                值不为0时 返回0
        
        三目运算符:
            逻辑判断之后 返回一个值 不是变量
            
    位运算符:
        避免位运算符 逻辑运算符 数学运算符同时出现在一个表达式里
        尽量用()表达次序
        左移n位 相当于乘于 2^n
        右移n位 相当于除于 2^n
        
        a ^ a = a;
        
    操作符分析:
        ++:
            i = 3; (++i) + (++i) + (++i) = 16 / 18;
            i = 3; k = (++i, i++, i+10) = 15    //逗号表达式 从左到右计算 最后一个表达式的值
                
            i +++ 1
                编译器从左到右尽可能多的包含字符
        
    优先级和类型转换:
        ----------------------------------------------------------
        常见问题                            |    表达式
        ----------------------------------------------------------    
        .的优先级高于* ->可以消除这个问题      |    *p.f
        []的优先级高于*                     |    int *app[]
        函数()高于*                            |    int *fp()
        == != 优先级高于 位操作                |    (val & mask != 0)
        == != 优先级高于 赋值符                |    c = getchar() != EOF
        算术运算符高于位移运算符            |     mab << 4 + lsb
        逗号运算符在所有运算符优先级最低    |      i = 1, 2;
        ----------------------------------------------------------    
        
        C语言的隐式类型转换:
            低类型向高类型转换
            实参向形参转换
            赋值右边向赋值左边转换
            return 表达式转换为返回值类型
        
            char  ->        int -> unsigned int -> long -> unsigned long -> double
                                                                              |
                    short ->                                                float编译预处理    
        
编译预处理:
    编译过程:
        预处理器 - 编译器 - 汇编器 - 链接器
        gcc -E test.c -o test.i
        
        gcc -S test.i -o test.s
        
        gcc -C test.s -o test.o
        
        单步编译技术 排除错误
        
        链接器的工作就是把各个独立的模块链接为可执行程序
        静态链接在编译器完成 动态连接在运行时完成
        
    宏定义使用分析:
        #define 从本行开始之后的代码可以使用这个宏常量
        宏表达式像函数 却不是函数 比函数强大 容易出错
        宏表达式只是简单的文本替换 有副作用
        不要在宏参数里面写表达式
        可以只充当一个语句 扩展C语言的用法
        编译器不知道宏表达式的存在
        用实参代替形参不进行任何计算 实参可以是只是数据类型
        宏表达式没有调用开销
        宏表达式不能出现递归的定义
        
        #undef结束#define定义域
        
        功能强大的内置宏
            __FILE__ :打印文件名
            __LINE__ : 不能放在函数里面来调用 可以使用宏代码块
            日志宏   : 打印时间 包含<time.h>
            
        宏代码块 多条语句 多行:  do{} while(0)  +   续行符
        
    条件编译使用分析:
        #if
        #else
        #endif :
            对编译器起作用 执行时不起作用
            
        gcc -DC=1 -E test.c -0 test.i //命令行时 预编译时指明C=1
        
        #include:
            将已经存在的文件内容嵌入到当前文件夹
            间接包含同样会产生嵌入文件内容的动作
            
            所以用到
                #ifndef
                #define
                #endif
            条件编译技术 只包含一次 防止多次展开 产生重定义的情况
        
        应用:
            不同的产品线用同一份代码
            区分编译产品的调试版和发布版
            
    #error 和 #line:
        #error 编译指示字:
            生成一个编译错误信息 停止编译
            #error message 无需双引号
            #warning message 生 成编译警告 不会停止编译
        #line 编译指示字:
            用于强制指定新的行号和编译文件名 并对源程序的代码重新编号
            #line number filename filename可以省略
    #pragma:
        编译器指示字 用于指示编译器完成一些特定的动作
        指示字是编译器和操作系统特有的
        在不同的编译器之间是不可移植的
            编译器将忽略不认识的指令
            不同的编译器将以两种不同的方式解释同一条pragma指令
            
        #pragma message
            message 参数在大多数的编译器中有相似的功能
            message 参数在编译时输出信息到编译输出窗口中
            message 可用于代码的版本控制
            
            知道编译的代码是不是自己想要的
            
        #pragma pack         
            内存对齐 不同类型的数据在内存当中并不是一个一个顺序排放的
            CPU对内存的读取并不是连续的 按块读取
             
            只能读写偶地址
            
            pragma(4) 告诉编译器的默认对齐方式
            结构体成员的对齐参数为其所有成员使用的对齐参数的整数倍
            
    #和##运算符使用解析:
        预处理器的开始符
        #用于在预编译期将宏参数转换为字符串
        #存在于宏里面使用 打印调用的函数名
        
        ##用于在编译的时候粘连两个字符
        
        ##定义结构体类型
        #define STRUCT(type) typedef struct _tag_##type type; struct _tag_##type
        
        
        
        
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值