必备技能
编程语言:C语言,c++
数据结构与算法:表、树、图、查找、排序、STL
操作系统:Linux操作系统(学习操作系统的运行机制、管理规则)
网络通信:TCP/IP协议(Socket技术、TCP、UDP、FTP...协议)
数据库:MySQL
界面设计:Qt
课程内容:
系统介绍
内存管理
文件管理
信号处理
进程管理
进程通信
线程管理
线程同步
网络通信
一、UNIX系统介绍
最早版本于1970~1973年诞生美国贝尔实验室,作者丹尼斯.里奇和肯.汤普逊
最早的多用户、多任务、支持多种CPU架构、高安全性、高稳定性、高可靠性
能够构建大型关键性业务系统的商用服务器、也能够支持嵌入式设备
Minix操作系统是一种基于微内核架构的类UNIX计算机操作系统,并开发全部源代码
给大学教学和研究工作,Linux之父林纳斯正是受到MInix的启发,开根据Linux内核了第一个版本的Linux内核
二、Linux系统介绍
Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·托瓦兹于1991年首次发布。
它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。
它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。
Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统
相关知识:
Linux的图标:企鹅(南极)标志性动物,表示Linux是开源的
GUN组织:通用的非商业类UNIX操作系统,目前世界上最大的开源组织,负责Linux内核源码的升级维护
GPL通用许可证:在带有GPL证书的代码的基础上开发出来的任何的软件,都必须支持GPL证书
POSIX:统一的操作系统接口规范,UNIX和Linux都是基本遵循该标准,命令、API接口基本通用
发行版:Linux只是内核, 内核+shell+基础软件 才是用户可用的操作系统
其它公司可以根据Linux内核制作出不同版本的发行版系统
Ubuntu、CentOS、redhet、Debian、deppin
三、GUN编译工具gcc:
多样化:
支持各种编程语言、支持各种
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
编译参数:
-E 只进行预处理
-S 编译,得到汇编代码
-c 只编译不链接 得到目标文件
-o 指定输出结果名字
-std 设置编译语法标准 -std=gnu99
-g 生成调试信息 用于gdb调试
-Wall 尽可能多产生警告
-Werror 把警告当做错误处理
-L 设置库文件的查找路径
-l 指定要加载的库文件的名字 -lm
-I 设置头文件的查找路径 -Ipath
-pedantic 与-ansi此结合使用,这告诉编译器严格遵守ANSI标准,拒绝任何不符合的代码
预处理指令:
#include <>/"" 包含头文件
#define 宏名 定义宏常量、宏函数
#ifndef 宏名 宏名不存在条件为真
#ifdef 宏名 宏名存在条件为真
#undef 宏名 删除宏
#if/#elif/#else/#endif 条件编译
#error "提示语" 提示错误,并阻止生成可执行文件,一般与条件编译配合
#warning "提示语" 提示警告
#line 设置行号 设置错误、警告提示的行号
#pragma pack(1/2/4) 修改对齐补齐的最大字节数
#pragma once 相当于头文件卫士
#pragma GCC dependency "file.h" 监控文件,如果被监控的文件修改时间在当前文件之后,就会产生警告
#pragma GCC poison key 设置关键字key为毒药,禁止在代码中使用key
四、库
库文件就是目标文件的集合,可以被其它代码调用的,把代码封装编译成库文件是为了方便使用、方便管理
安全性高,保密性强、
静态库:
以.a 结尾
就是目标文件到集合,调用静态库时就是把静态库的二进制指令拷贝到可执行文件中
优点: 运行速度比共享库快,可执行文件运行时不需要依赖静态库文件
缺点: 可执行文件相对较大,当静态库修改后,可执行文件就需要重新编译
制作静态库:
1.编译出目标文件
gcc -c code.c
2.打包目标文件生成静态库文件
ar -r libname.a a.o b.o...
注意:静态库文件名字前缀(lib)、后缀(.a) 不能改变
使用静态库:
1.直接使用
gcc code.c libname.a
2.指定库文件查找位置
gcc code.c -L (位置) -lname
3.通过位置环境变量指定库的默认查找路径
打开操作系统的配置文件
vim ~/.bashrc
在文件末尾追加:
export LIBRARY_PATH=$LIBRARY_PATH:/home/ubuntu/mylib
保存退出,重新加载配置文件
source ~/.bashrc
使用: gcc code.c -lname
共享库(动态库)
以 .so 结尾
相当于带入口的可执行文件,当运行程序时,会把共享库一起加载到内存中,
调用共享库函数,函数名就是记录了它在共享库中的位置,
本质上是跳转到共享库中对应的位置执行
优点: 可执行文件相对较小,当共享库修改后,可执行文件不需要重新编译
缺点:运行速度比静态库慢,可执行文件运行时需要依赖共享库文件
制作共享库:
1.编译生成目标文件
gcc -fpic -c code.c
//-fpic 生成与位置无关
2.生成共享库
gcc -shared -fpic a.o .... -o libname.so
使用共享库
编译:
1.直接使用
gcc code.c libname.so
注意:只能编译成功,如果要运行成功,还要把共享库文件放入系统
指定的共享库加载路径
2.指定库文件查找位置
gcc code.c -L (位置) -lname
3.通过位置环境变量指定库的默认查找路径 + lname
运行:
运行可执行文件时,会去系统默认路径去加载共享库到内存中,
因此可以通过设置环境变量增加系统加载共享库的加载路径
vim ~/.bashrc
在文件末尾追加:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ubuntu/mylib
保存退出,重新加载配置文件
source ~/.bashrc
注意:编译时,如果同时存在同名的静态库和共享库,会优先使用共享库
加 -static 编译参数,优先使用同名的静态库
静态库和共享库的辅助工具:
ldd 查看可执行程序依赖了哪些共享库
nm 查看可执行文件、目标文件、静态库、共享库的符号列表
strip 删除可执行文件、目标文件、静态库、共享库的符号列表(不影响正常功能)
objdump -S 显示可执行文件、目标文件、静态库、共享库反汇编信息
五、环境变量表:
每个程序执行时操作系统都会分配一张环境变量表,该表中记录了操作系统所有的环境变量,
这些环境变量反映了操作系统的配置情况,以及程序所处于的操作系统环境
声明 extern char** environ; 就可以使用了
这个表可以随意修改,因为只是操作系统提供给程序的一个备份
#include <stdlib.h>
char *getenv(const char *name);
功能:获取一个环境变量的值
int setenv(const char *name,const char *value,int overwrite);
功能:修改环境变量的值\添加环境变量
name:环境变量名
value:环境变量的值
overwrite:当name存在时
值为真则修改成value
值为假则不修改
返回值:
成功返回0 失败返回-1
int putenv(char *string);
功能:以 "name=value" 格式修改或添加环境变量,如果已存在则修改,不存在则添加
返回值:成功返回0 失败返回-1
int unsetenv(const char *name);
功能:删除环境变量
返回值:成功返回0 失败返回-1
int clearenv(void);
功能:清空环境变量表
六、错误处理
1.通过函数的返回值表示错误
a.合法值表示成功、非法值表示失败
b.指针类型的返回值NULL或者0xFFFFFFFF表示失败,其他表示成功
c.返回0表示成功、-1表示失败,一般都是系统函数
d.永远成功 printf
2、修改全局的错误编号 errno 定义 <errno.h>中
void perror(const char *s);
功能:根据errno显示错误原因
char *strerror(int errnum);
功能:根据errnum,获取错误原因,记录到日志中或者发送到网络去
注意:因为errno是一个全局变量,不能根据它的值就判断程序出错