Linux环境编程1

程序员必备技能:

    一门编程语言: C语言、C++

    数据结构与算法: 表、树、图、查找、排序、STL

    操作系统: UNIX/Linux系统

    网络编程: TCP\IP协议簇(Socket技术、TCP、UDP、FTP协议)

    数据库: MySQL

    界面设计Z: Qt

课程介绍:

    环境介绍

    内存管理

    文件管理

    信号处理

    进程管理

    进程通信

    线程管理

    线程同步

    网络编程

UNIX系统介绍:

    BCPL->newB->C->UNIX->Minix->Linux->gcc

    最早版本诞生于1970年,属于美国贝尔实验室,作者丹尼斯.里奇和肯.汤姆逊,是最早的多用户、多任务、支持多种CPU架构、高安全性、高稳定性、高可靠性,既能够构建大型关键业务系统的商用服务器、也能支持嵌入式设备

    Minix是一种基于微内核架构的类Unix系统,并开放全部源代码给大学教学和研究工作,Linux之父林纳斯.托瓦兹正式受到Minix的启发,才开发了第一个版本的Linux系统

Linux系统介绍:

    Linux,全称GNU/Linux,其内核其内核由林纳斯·托瓦兹于1991年首次发布

    它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统

    Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统

    相关知识:

        Linux的标志: 小企鹅,因为企鹅是南极洲的标志性动物,而南极目前不被任何国家占有,属于全人类

        GNU组织: 通用的非商业的类UNIX系统,目前全球最大的开源组织,负责Linux内核代码的升级维护

        GPL通用许可证: 在带有GPL证书的代码的基础上开发出的软件也必须支持GPL证书

        POSIX: 可移植操作系统接口,Linux完全遵循该标准,UNIX也大部分遵循该标准,所以它们的命令、API接口基本上都是通用的

        发行版: Linux只是内核,内核+shell+基础软件才是可用的操作系统,由不同公司依据Linux内核制作出不同发行版的Linux系统

        Ubuntu、redhat、CentOS、debian、deepin、UOS

    GNU编译工具:

        多样性:

            支持多种编程语言、支持各种操作系统

            gcc -v 查看版本信息

        构建过程:

            预处理: gcc -E code.c -o code.i ->code.i

            编译: gcc -S code.i ->code.s

            汇编: gcc -c code.s ->code.o

            链接: gcc a.o b.o ... ->a.out

        文件类型:

            .h 头文件

            .h.gch 头文件的编译结果,会被优先使用

            .c 源文件

            .i 预处理文件

            .s 汇编文件

            .o 目标文件

            .a 静态库文件

            .so 共享库文件

        编译参数:

            -E 只进行预处理

            -S 只进行编译

            -c 只编译,不链接

            -o 设置编译结果名字

            -std 设置语法标准

            -g  生成调试信息

            -Wall 尽可能多地产生警告

            -Werror 把警告当做错误处理

            -l 指定要加载的库文件的名字

            -I 指定头文件的加载路径

            -L 设置库文件的查找路径

            -D 定义宏

            -On(1\2\3) 优化等级

            -pedantic 以ANSI/ISO C标准列出的所有警告

            -ansi 会对typeof产生警告

        预处理指令:

            #include <>/"" 包含头文件

            #define 定义宏常量、宏函数

                # 把标识符转换成字符串

                ## 拼接标识符

            #ifdef 宏名存在条件为真

            #ifndef 宏名不存在条件为真

            #undef 删除宏

            #if/#elif/#else/#endif 条件编译

            #error 提示错误,并且能阻止生成可执行文件,一般与条件编译判断配合

            #warning 提示警告

            #line 设置行号,影响错误,警告提示的行号

            #pragma pack(1\2\4) 对齐和补齐时的最大字节

            #pragma once 相当于头文件卫士

            #pragma GCC dependency "filename" 监控文件

            #pragma GCC poison key 设置关键词key为有毒的,禁止在代码中使用关键词key

    库:

        库文件就是目标文件的集合,可以被其它代码调用,把代码封装成库文件后方便调用、方便管理、安全性高、保密性更好

        静态库:

            就是目标文件的集合,调用静态库就是把静态库中的二进制指令拷贝到可执行程序中

            优点: 运行速度比共享库快,不需要依赖共享库

            缺点: 最终的可执行文件相对较大,当静态库修改后,可执行文件必须要重新编译

            制作静态库:

                1、编译出要合并的文件的目标文件

                    gcc -c code.c

                2、打包目标文件生成静态库

                    tar -r libxxx.a a.o b.o c.o ...

                    注意: 库名格式必须是libxxx.a

            使用静态库:

                1、直接使用

                    gcc code.c libxxx.a

                2、指定库文件的位置

                    -L 指定库的路径 -l 指定库名

                        【库名去掉前缀和后缀 -lm m为库名】

                3、通过设置环境变量来指定库的查找路径 -l指定库名

                    1、打开配置文件: vim ~/.bashrc

                    2、在配置文件末尾添加: 

                        export LIBRARY_PATH=$LIBRARY_PATH:路径

                    3、保存退出并重新加载: source ~/.bashrc

                    注意: 如果是删除环境变量,需要关闭终端再打开

                    直接使用静态库: gcc code.c -lxxx

        共享库:

            就是带入口的可执行文件,调用共享库其实就是记录共享库中二进制指令在内存中的位置即可,当可执行文件执行时,共享库会被一起加载到内存中,可执行文件可以跳转到共享库中执行

            优点: 可执行文件相对较小,当共享库修改后,可执行文件不需要重新编译

            缺点: 运行速度比静态库慢,可执行文件运行时需要依赖共享库

            制作共享库:

                1、编译生成目标文件

                    gcc -fpic -c code.c

                    fpic: 位置无关

                2、生成共享库

                    gcc -shared -fpic a.o ... -o libxxx.so

            使用共享库:

                1、直接使用

                    gcc code.c libxxx.so

                        error while loading shared libraries: libxxx.so: cannot open 

                        shared object file: No such file or directory

                    注意: 失败是因为执行共享库时,默认的加载路径是/lib

                2、指定库文件的位置

                    -L 指定库的路径 -l 指定库名

                        【库名去掉前缀和后缀 -lm m为库名】

                3、通过设置环境变量来指定库的查找路径 -l指定库名

                    打开配置文件: vim ~/.bashrc

                    在配置文件末尾添加: 

                        export LIBRARY_PATH=$LIBRARY_PATH:路径

                    保存退出并重新加载: source ~/.bashrc

                        gcc code.c -lxxx

                    注意: 需要设置程序执行共享库的加载路径

                        1、打开配置文件: vim ~/.bashrc

                        2、在配置文件末尾添加: 

                            export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:路径

                        3、保存退出并重新加载: source ~/.bashrc

        注意: 当同名共享库与静态库同时存在时,编译器会优先使用共享库,加上-static编译参数可以优先使用静态库

作业: 把常用的数据结构和算法封装到libxxx.so

    栈

    队列

    通用链表

    平衡二叉树

    顺序查找

    二分查找

    冒泡排序

    快速排序

    静态库和共享库的辅助工具:

        ldd 查看某个可执行程序依赖哪些共享库 ldd ./a.out

        nm 查看目标文件、可执行文件、静态库、共享库中的符列表

        strip 删除目标文件、可执行文件、静态库、共享库中符号列表

        objdump 显示目标文件、可执行文件、静态库、共享库反汇编信息

    环境变量表:

        每个程序执行时操作系统都会给一张环境变量表,该表中记录了操作系统的所有的环境变量,这些环境变量反映了操作系统的配置、情况以及当前操作系统所处的系统环境

        声明 extern char** environ; 就可以直接使用该程序的环境变量表

        注意: 可以随意修改,因为只是操作系统提供的一个备份

        操作环境变量表的函数:

            int setenv(const char* name,const char* value,int overwrite);

            功能: 向环境变量表中添加、修改环境变量

            name: 环境变量名

            value: 环境变量的值

            overwrite:

                当环境变量存在时

                为真则修改圆的环境变量的值

                为假则不修改

            返回值: 成功返回0,失败返回-1

            int unsetenv(const char* name);

            功能: 删除环境变量

            返回值: 成功返回0,失败返回-1

            char* getenv(const char* name);

            功能: 获取环境变量的值

            int putenv(char* string);

            功能: 以 name=value 格式添加或修改环境变量,如果已经存在则修改反之则添加

            返回值: 成功返回0,失败返回-1

        

            int clearenv(void);

            功能: 清空环境变量表

    错误处理:

        1、通过函数的返回值表示错误

            a、合理值表示成功,非法值表示失败

                例如: 计算大小、查找

            b、指针类型的返回值NULL或者0xFFFFFFFFF表示失败

                例如: malloc mmap

            c、返回0表示成功,-1表示失败,一般都是系统函数

            d、永远成功 例如: printf

        2、通过影响全局的错误编码 errno,定义在 errno.h 中

            char* strerror(int errnum);

            功能: 根据错误编码的值,获取详细的错误信息,通过返回值返回,记录到日志中,或者通过网络通信发送出去

            注意: errno是一个全局变量,不能根据它的值就轻易判断是否产生错误

            void perror(const char* s);

            功能: 直接显示出系统错误原因

作业:

task1.c

1、添加环境变量 HOME=/home/peter

2、删除环境变量 LIBRARY_PATH

3、给 LD_LIBRARY_PATH 环境变量追加一个新路径(先拷贝到字符串)

    假如 LD_LIBRARY_PATH=/hehe/xixi

    添加后 LD_LIBRARY_PATH=/hehe/xixi:/haha

task2.c

4、实现一个函数计算文件的大小

5、实现一个字符串查找函数

    如果在A字符串中找到了B字符串,则返回子串第一次出现的位置,如果找不到

    char* find_str(const char* str,cocn bbvgvgnst char* sub);

6、实现一个求平均值的函数(考虑溢出风险)

    (num/2.0 就可以转换成double类型且可以防止溢出风险)

    double avg(int num1,int num2);

上一篇:Problem 1030A In Search of an Easy Problem (Codeforces 800)


下一篇:使用Visual Studio Code开发AngularJS应用