程序员必备技能:
一门编程语言:C语言、C++
数据结构与算法:表、树、图、查找、排序、STL
操作系统:UNIX/Linux系统
网络编程:TCP\IP(Socket技术、TCP、UDP、FTP协议)
数据库:MySQL
界面设计: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
编译: gcc -S code.i ->code.s
汇编: gcc -c code.s ->code.o
链接: gcc a.o b.o c.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\8) 对齐和补齐时的最大字节数
#pragma once 相当于头文件卫士
#pragma GCC dependency "filename" 监控文件
#pragma GCC poison key 设置关键字key为有毒的,禁止在代码中使用关键词key
库:
库文件就是目标文件的集合,可以被其它代码调用,把代码封装成库文件后方便调用、方便管理、安全性高、保密性更好
静态库:
就是目标文件的集合,调用静态库就是把静态库中的二进制指令拷贝到可执行程序中
优点:运行速度比共享库,运行时不需要依赖静态库
缺点:最终的可执行文件相对较大,当静态库修改后,可执行文件必须要重新编译
共享库:
就是带入口的可执行文件,调用共享库其实就是记录共享库中二进制指令在内存中的位置即可,当可执行文件执行时,共享库会被一起加载到内存中,可执行文件可以跳转到共享库中执行
优点:可执行文件相对较小,当共享库修改后,可执行文件不需要重新编译
缺点:运行速度比静态库慢,可执行文件运行时需要依赖共享库
静态库
制作静态库:
1、编译出目标文件
gcc -c code.c
2、打包目标文件生成静态库
ar -r libxxx.a a.o b.o c.o...
注意:库名格式必须是libxxx.a
使用静态库:
1、直接使用
gcc code.c libxxx.a
2、指定库文件的位置
-L 指定库的路径 -l指定库名 【库名去掉前缀和后缀 -lxxx】
3、通过设置环境变量的方式来指定库的查找路径 -l指定库名
打开配置文件:vim ~/.bashrc
在文件末尾添加:export LIBRARY_PATH=$LIBRARY_PATH:路径
保存退出并重新加载:source ~/.bashrc
注意:如果是删除环境变量,需要关闭终端、再打开
直接使用静态库:gcc code.c -lxxx
共享库:
制作共享库:
1、编译生成目标文件
gcc -fpic -c code.c
fpic:位置无关
2、生成共享库
gcc -shared -fpic a.o b.o c.o... -o libxxx.so
使用共享库:
1、直接使用
gcc code.c libxxx.so
注意:失败是因为执行共享库时,默认的加载路径是/lib
2、指定库文件的位置
-L 指定库的路径 -l指定库名 【库名去掉前缀和后缀 -lxxx】
3、通过设置环境变量的方式来指定库的查找路径 -l指定库名
打开配置文件:vim ~/.bashrc
在文件末尾添加:export LIBRARY_PATH=$LIBRARY_PATH:路径
保存退出并重新加载:source ~/.bashrc
gcc code.c -lxxx
注意:需要设置程序执行共享库的加载路径
打开配置文件:vim ~/.bashrc
在文件末尾添加:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:路径
保存退出并重新加载: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:
1、添加环境变量 HOME=/home/用户名
2、删除环境变量 LIBRARY_PATH
3、给LD_LIBRARY_PATH 环境变量追加一个新路径
假如 LD_LIBRARY_PATH=/hehe/xixi
添加后 LD_LIBRARY_PATH=/hehe/xixi:/haha
错误处理:
1、通过函数的返回值表示错误
a、合理值表示成功,非法值表示失败
例如:计算大小、查找
b、指针类型的返回值NULL或者0xFFFFFFFF表示失败
例如:malloc mmap
c、返回0表示成功,-1表示失败,一般都是系统函数
d、永远成功 例如:printf
2、通过影响全局的错误编码 errno ,定义在 errno.h中
char *strerror(int errnum);
功能:根据错误编码的值,获取详细的错误信息,通过返回值返回,记录到日志中,或者通过网络通信发送出去
注意:errno是一个全局变量,不能根据它的值就轻易判断是否产生错误
void perror(const char *s);
功能:直接显示出系统错误原因
作业2:
1、实现一个函数计算文件的大小
2、实现一个字符串查找函数
如果在A字符串中找到了 B字符串,则返回子串第一次出现的位置,如果找不到...
char* find_str(const char* str,const char* sub);
3、实现一个求平均值的函数,考虑溢出风险
double avg(int num1,int num2);