• C语言总结



    C语言总结
    C语言的概述(自己总结)
        起源,发展,现状,特点,优缺点
    数据类型
        内建:C语言自带的数据类型
            整型
                stdint.h    对数据类型进行了封装
                limits.h     各种数据类型的最大值是小值
                unsigned   
                    uint8_t,uint16_t,uint32_t,uint64_t
                    char,short,int,long,long long
                    char 0~255  256个值
                    short 0~65535 65536个值
                signed
                    int8_t,int16_t,int32_t,int64_t
                    char,short,int,long,long long
                    char -128~127 256个值
                    short    -32768~32767 65536个值               
                   
            浮点型(小数点浮动)
                数据格式:符号位 指数位 尾数位
                默认小数点后六位有效,精度有限,运算效率低
                有专门针对浮点运算的CPU
                float 4
                double 8
                如何判断float类型的数据是“零值”?
                if(val<0.000001 && val>-0.000001)
                {
                    //不等于0,但无效,相当于零值
                }
                如何提高浮点类型数据的准确率?
                    先放大,在还原。
            布尔型
                由于C语言出现于1970年左右,布尔类型流行于1980以后,所以c语言中是没有真正的布尔类型。
                bool  stdbool.h
                true 非零值 NULL 绝大多情况小为假 ''
                false 零值
                NULL == ((void*)0)||((void*)1);
                _bool C99标准中补充的
                如何判断int,bool,int*类型的值是否为假?
                int num;           
                if(0 == num)
                if(flag)
                if(NULL==p)
            字符型
                底层采用整数存储的,整数与ASCII表的字符对应
                '' 0
                '0'    48
                'A' 65
                'a' 97

                转义字符
                a
                
               
                v
                f
               
               
                %%
                "
                \
     
            枚举
                功能受限制的int类型,防君子不防小人
                使用枚举是一直锦上添花,使用枚举可以提高程序的安全性和可读性
                有名枚举
                typedef enum CMD    {ADD,DEL,FIND};
                可以定义枚举变量
                匿名枚举
                ENUM {UP,DOWN,RIGHT,LEDT}
                    使用枚举值,或者与switch配合使用
            指针:整型(整数),表示的是内存的编号
        自建:C程序自己设计的数据类型
            结构
            联合
            数组

    变量(容器)与常量
       
        常量:字面值,宏常量,枚举值,初始化过并且被const修饰的全局变量
        变量:
            全局变量:普通全局变量,静态全局变量
                作用域不同
            局部变量:普通全局变量,静态全局变量
                存储位置不同:普通在栈,静态在bss
            块变量:普通块变量,静态块变量
        变量名:
            1、由数字、字母、下划线组成
            2、不能以数字开头
            3、不能与关键字重名
            4、见名知义
                功能、范围、类型
               
        输入数据
            scanf 占位符 变量地址
            scanf返回值,成功接取数据的个数
            如何不理输入缓冲区:
                getchar()
            scanf("%*[^ ]"),scanf("%*c");
            stdin->_IO_read_ptr = stdin->_IO_read_end;
        输出数据
            printf 占位符 变量名
            数据遇到什么条件才会从缓存区到达屏幕:
                1、满4k(4096byte)
                2、遇到
                3、遇到输入类型的函数
                4、手动刷新 fflush(stdin);
                5、程序结束
    数组
        数组的定义:类型 数组名[数量];
            在内存的分布上优先定义数组,再定义变量
        数组的初始化:类型 数组名[数量] = {val1,val2...};
            1、初始化值过多会有警告
            2、初始化值不够补0
            3、类型 数组名[数量] ={};
            4、类型 数组名[] = {val1,val2...};
        数组的越界:
            1、脏数据
            2、段错误
            3、一切正常
        变长数组:数组的长度在编译时无法确定,在运行时可以发生变化,当执行到定义数组语句时,数组的长度就确定下来了,不可再变
            优点:根据需求在确定数据的长度,节约内存。
            缺点:不能初始化(数组的初始化是由编译器帮助完成)
        多维数组:
            一维数组:变量组成的队列
            二维数组:变量组成的方阵
            三维数组:变量组成的立方体

    流程控制语句:
        分支
        if    else if else
        switch
            小括号中只能是整型数据
            case后必须是常量
            default 最后执行
            break 关闭执行开关
        循环
        for
            for([1];[2];[3])
            {
                [4]
            }
            for 语法灵活,1,2,3,4都可以缺少
                用循环变量i(index)引导for的运行,负责明确知道循环次数的情况       
        while
            是for的一种精简,负责只知道循环条件
        do while
            先执行循环体,在判断循环条件,直到循环

        if、for、while 如果没有大括号,默认下一行代码是它的语句体,但不建议这样使用,大括号不要省略(安全性、可扩展性),如果执行异常,记得检查小括号后面是否有多余的分号
        跳转
        goto
            goto 标签;功能是在函数内可以任意跳转,这种跳转会破坏原先的分支,循环结构
            大多数公司会禁止使用goto,禁止的方式就是把goto定义为病毒(应用层程序)
            但在驱动编程时goto非常适合用来处理异常
        break
            1、switch中关闭开关
            2、在循环中使用可以跳转一层循环
        continue
            只能在循环中使用,功能是结束本次循环进入下次循环
        return   
            1、返回函数的执行结果
            2、提前结束函数的执行

    函数
        函数的声明:
            extern 返回值类型 函数名(参数类型,参数名,..);
            返回值类型 函数名(参数类型,参数名,...);
            返回值类型 函数名(参数类型1,参数类型2,...);
        函数的定义:
            返回值类型 函数名(参数类型,参数名,...);
            {
                函数体
            }

        使用函数要注意的问题:
            1、函数传参全部都是值传递(内存拷贝)
                由于数据名就是指针,以数组当函数参数时也是值传递,而且数组的长度也会丢失,
            2、函数的隐式声明
                当调用函数,如果没有提前声明,编译器会猜测函数的格式,如果猜测正确函数则正常执行如果猜错,则会执行异常。
            3、如果函数不需要参数要写void
                定义函数时如果小括号中是空的,则意味着任意类型,任意个参数都可以调用函数
            4、不写return不表示没有返回值
           
        递归:
            函数自己调用自己的行为叫递归,这种解决问题的思想:分支
            这种调用极易引发死循环,递归编写的格式:
            1、出口
            2、解决一部分问题
            3、再次调用自己
           
            递归是一种解决复杂问题的常见手段,也比较适合解决树型结构问题,容易理解但不能模拟它的执行过程

    指针:
        什么是指针:一种数据类型,代表内存编号的整数
            使用它可以定义指针变量
        什么情况下使用指针:
            1、函数之间共享变量
            2、优化函数传参
            3、使用堆内存必须配合指针
          指针的使用方法:
            定义:类型* 变量名_p;
            1、指针的类型决定了,通过指针访问内存时的字节数
            2、指针不能连续定义
                int* p1,p2,p3;//p1是指针,p2是int变量
                int *p1,*p2,*p3;
            3、指针的默认是随机的(野指针),如果没有确定的值可以初始化为NULL(空指针)
            4、指针变量与普通变量的使用方法有很大区别,因此最好从名字上就能区分开,所以以p结尾
            arr,str
            赋值:指针变量名 = 内存编号
                1、类型要匹配,否则会有警告
                2、类型指针<=>void*
                3、void*不能直接使用,要转换成有类型的指针
                int* p = malloc(4);
            访问内存:*指针变量
                int *p = &num;
                *p <=>num;
                这个过程是有可能产生段错误的
                访问内存的字节数由指针的类型决定的           
        使用指针要注意的问题
            1、空指针
                指针变量的值为NULL,NULL不一定是0
                使用空指针的后果就是一定产生段错误
                0地址是操作系统的复位地址,存储了重启时要使用的数据,因此不能让应用程序访问,NULL也是应用程序的错误标志,如果函数的返回值是NULL说明函数执行错误
                    使用来历不明的指针钱要先检查NULL == p
                    strlen strcat strcpy strcmp
                   
            2、野指针
                指针变量的值不确定
                使用野指针不一定出错,肯呢过产生的后果:
                1、脏数据
                2、段错误
                3、一切正常
                出现野指针比出现空指针的后果更严重,因此野指针无法判断
                防止野指针出错是只能从根源着手,不制造野指针:
                1、定义指针变量时一定要初始化
                2、不持有局部变量的地址
                3、堆内存一旦初始释放,指针要及时设置为空

            3、指针的运算
                因此指针变量的值就是整数,所以整数数据可以使用的运算符它基本都可以使用,但是要以实际意义为准则
           
            4、指针与数组名
                数组名:是一种常指针,他与数组的首地址是对应关系
                指针和数组名的用法是可以互换的:
                    p[i] = *(p+i);
                    *(arr+i) = arr[i];

    修饰变量的关键字
        auto    不能与static 一起用,全局不变量也不能使用
            定义自动分配,释放的变量,不加就代表加
        unsigned:定义无符号整型变量
        signed:定义有符号整型变量,不加就代表加
        const:为数据提供一种保护机制,被它修饰过的变量不能显示修改
            变量、函数参数、返回值、指针
            const 全局变量 初始化 = 常量   
            const int *p; 不能通过 *p修改内存的值
            inr const *p;同上
            int* const p; p的值不能修改
            const int* const p; 不能通过*p修改内存的值,p的值也不能修改
           
        static
            限制作用域:全局变量、函数
            改变存储位置:局部、块变量
            延长生命周期:局部、块变量
        volatile
            防止编译器优化变量的取值过程
        register
            申请把变量存储到寄存器
        extern
            声明变量、函数
    程序在内存中的分布
        代码:可以执行文件会被全部加载到此段
        只读:字面值、常量
        全局:被初始化过的全局变量
        bss:静态变量、未初始化的全局变量
            程序执行前会把这段内存清理为0
        栈:局部变量、块变量
        堆:程序员自己变量、无法取名、足够大

    字符串
        串:是一种数据结构,由若干个相同类型的数据组成,有一个明确的结束标志''。
        字符串字面值:
            以地址形式存储在只读内存中。
            如果在程序中已经存在一份字符串字面值,当再使用它时不会在内存中再定义一份。
            字符串可以换行写,编译器会自动把它们连接。
        定义:
            const char* str = "hehe";
            char str[] = "hehe";
        处理字符串的函数:
            输入:
                scanf
                gets
                fgets
                getstr
                fscanf
                fread
            输出:
                printf
                puts
                fpritnf
                fwirte
            string.h
                strlen
                strcat/strncat
                strcpy/strncpy
                strcmp/strncmp
               
                strchr
                strstr
                atoi
                memset
                memcpy
               
                sscanf/sprintf
                字符串-》数值 数值-》字符串
    堆内存使用
        C语言中是没有提供内存管理的语句,只能靠标准库提供的库函数(stdlib.h)。
        内存芯片-》操作系统-》malloc-》a.out
       
        malloc 申请内存
        calloc 按块申请内存,并把申请的内存初始化
        realloc 调整已有内存的大小,把内存调大就相当于申请内存,把内存调小就相当于在释放内存。
        free 内存的释放。
       
        使用堆内存要注意的问题:
            1、重复释放
            2、越界:
                前续错误
                后续错误
                段错误
                脏数据
                一切正常
            3、泄漏
                谁申请,谁释放
                谁知道该释放,谁释放
               
    结构、联合
        typedef struct 结构名
        {
            成员类型 成员名=-1;
            void func(void); // eroor
            void (*funcp)(void); // 允许
            char sex:1;
        }结构类型;
       
        1、在定义结构变量时struct不能省略。
        2、结构的成员不能初始值。
        3、结构的成员不能是函数,但可以是函数指针。
        4、结构变量可对结构变量直接赋值
            Student stu1 = {};
            Student stu2 = stu1;
            stu2 = stu1;
           
        结构的大小:
            补齐:结构的总字节数要是它最大成员的整数倍,如果不是则添加空白字节补齐。
            对齐:每个成员在结构中的内存起始编号,要是它自身大小的整数倍,如果不是则添加空白字节保持对齐。
            Linux和Windows系统对待补齐和对齐的区别?
                Window会严格按照补齐和对齐的规定严格执行
                Linux对待补齐和对齐时,超过4字节按4字节计算。
                补齐和对齐的字节数是可以设置的。
           
        联合:节约内存的一种手段。
        联合常考的问题:
            1、联合的字节数。
                union data
                {
                    char arr[5];
                    int num;
                };
               
            2、使用联合判断大、小端系统。
                0x010203 高位数据1 低位数据3
                0x18[][][][] 高位地址0x1B 低位地址0x18
                大端 0x01020304
                小端 0x04030201
    文件操作:
        文件的分类:
            二进制文件:数据的补码。
            文本文件:存储的是ASCII的二进制。
           
        windows系统对待换行与Linux系统不同。
           
           
           
        文件的打开方式:
            r
            w
            a
            r+
            w+
            a+

            wb ->
            w  ->
           
        文件操作函数:
            fopen
            fscanf/fprintf
            fgets/fputs
            fread/fwrite   
            fclose
           
            fseek 调整文件位置指针
            ftell 返回文件位置指针的位置
            rewind 调整文件指针到文件的开头。





















       






    附件列表

    • 相关阅读:
      2020 HDU校赛 Problem J
      2020 HDU校赛 Problem I
      2020年HDU校赛 Problem A
      HDU 2553 N皇后 (dfs+回溯)
      D
      #6177. 「美团 CodeM 初赛 Round B」送外卖2(floyed + 三进制枚举 )
      E
      B
      大数加法模板(可能有问题,目前没发现)
      H
    • 原文地址:https://www.cnblogs.com/LyndonMario/p/9326068.html
    Copyright © 2020-2023  润新知