环境编程01

程序员必备技能:
一门编程语言:C语言、C++
数据结构和算法:表 树 图 查找 排序 STL
操作系统:Linux系统
网络通信:TCP/IP (Socket、TCP、UDP、FTP、HTTP)
数据库:MySQL
界面设计:Qt

课程内容介绍:
内存管理
文件管理
信号处理
进程管理
进程通信
线程管理
线程同步
网络通信

UNIX系统介绍:
最早版于1970年问世于贝尔实验室,作者是丹尼斯.里奇和肯.汤普逊。
是最早的多用户、多任务、支持多种CPU架构,高安全性、高稳定性、高可靠性。
既能构架大型关键性业务系统的商用服务器,也能支持嵌入式设备。

MiniX基于微内核加载的类UNIX系统,名为MINIX(即小型的UNIX),并开放全部源代码给大学教学和研究工作,Linux之父林纳克斯,正是在受了MiniX的启发,才开发了Linux系统。

Linux系统介绍:
Linux,全称GNU/Linux,其内核由林纳斯·托瓦兹于1991年第一次公开在校内网的FTP服务器上。

它主要受到Minix和Unix思想的启发,是一个基于POSIX(可移植操作系统接口)和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。

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

相关知识:
Linux的标志:小企鹅,因为企鹅是南极的标志性动物,而南极目前没有被任何任何国家占有,是属于全世界人民的。

GNU组织:通用的非商业类UNIX系统,目前也是全世界最大的开源组织,负责Linux内核源的升级维护。

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

POSIX:统一的操作系统接口,UNIX和Linux都遵循了该标准,所有它们的命令、API接口基本上是通用的。

发行版:Linux只是内核,内核+Shell+基础软件才是可用的操作系统。
其它公司可以根据Linux内核制作出不同版的Linux系统。
ubuntu、redhat、CentOS、debian、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 头文件的编译结果,会被优先使用
.i 预处理文件
.c 源文件
.s 汇编文件
.o 目标文件
.a 静态库文件
.so 共享库文件
编译参数:
-E 只预处理
-S 编译
-c 汇编
-g 生成调试信息
-o 设置编译结果的名字
-std 设置语法标准
-Wall 产生尽可能多的警告
-Werror 把警告当错误处理
-L 设置库文件的查找路径
-I 设置头文件的查找路径
-l 指定要加载的库文件的名字
-On 优化等级
-pedantic 对于不符合 ANSI/ISO 语法标准的代码产生警告。
预处理指令:
#include <>/"" 包含头文件
#define 定义宏常量、函数
# 把标识符转换成字符串
## 连接标识符
#ifdef 宏名存在条件为真
#ifndef 宏名不存在条件为真
#undef 删除宏
#if/#elif/#else/#endif 条件判断

#error 提示错误,并阻止生成可执行文件,要与条件判断配合使用。
#warning 提示警告,
#line 设置行号

#pragma pack(1/2/4/8) 对齐与补齐的最大字节数
#pragma once 相当于头文件卫士
#pragma GCC dependency “file.h” 监控文件
#pragma GCC poison “key” 设置关键字为病毒,禁止在代码中使用。

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

静态库:就是目标文件的集合,调用静态库就是把静态库中的二进制指令拷贝到可执行文件中。
优点:运行速度比共享库快。
缺点:可执行文件相对较大,当静态库修改后,可执行文件要重新编译。

共享库:就是没入口的可以执行文件,调用共享库就是记录共享中二进制指针的位置即可。当执行可执行文件时共享库会被一起加载到内存,可执行文件中可以跳转到共享库中执行。
优点:可执行文件相对较小,当共享库修改后,可执行文件不要重新编译。
缺点:运行速度比静态库慢,可执行文件运行时也需要依赖共享库。

静态库:
制作静态库:
1、编译出目标文件
gcc -c code.c
2、打包目标文件生成静态库
ar -r libname.a a.o b.o c.o …
使用静态库:
1、直接使用
gcc code.c libname.a
2、指定库文件的位置
-L指定库的路径 -l指定库名
gcc code.c -Lpath -lname
3、通过设置环境变量指定库的路径,-l指定库名
打开配置文件:vi ~/.bashrc
在文件的末尾添加:export LIBRARY_PATH=$LIBRARY_PATH:path
保存退出后重新加载:source ~/.bashrc
使用静态库:gcc code.c -lname
注意:删除环境变量,需要关闭终端,再重新打开。

共享库:
制作共享库:
1、编译生成目标文件
gcc -fpic -c code.c
fpic 位置无关
2、生成共享库
gcc -shared -fpic a.o b.o c.o … -o libname.so
使用共享库:
1、直接使用
gcc code.c libname.so
2、指定库文件的位置
-L指定库的路径 -l指定库名
gcc code.c -Lpath -lname
3、通过设置环境变量指定库的路径 LIBRARY_PATH
gcc code.c -lname
注意:设置程序执行共享库的加载路径
打开配置文件:vi ~/.bashrc
在文件的末尾添加:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path
保存退出后重新加载:source ~/.bashrc

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

练习:
把常用的数据结构和算法封装到libdsa.so文件中。

队列
通用链表
平均二叉树
顺序查找
二分查找
冒泡排序
快速排序
计数排序

动态加载共享库:
#include <dlfcn.h>

void *dlopen(const char *filename, int flag);
功能:打开共享库
filename:共享库的名字
flag:
RTLD_LAZY 延迟加载
RTLD_NOW 立即加载
返回值:共享库的句柄

char *dlerror(void);
功能:获取错误信息

void *dlsym(void *handle, const char *symbol);
功能:从共享库中获取函数指针
handle:共享库的句柄,也就是dlopen的返回值
symbol:函数名
返回值:成功返回函数的地址,失败返回NULL

int dlclose(void *handle);
功能:关闭共享库
返回值:成功返回0,失败返回-1。

注意:使用要添加dl库,这种方式的好处就是可以在编译时不依赖共享库。

静态库和共享库辅助工具:
ldd 查看可执行程序依赖那些共享库
nm 查看目标文件、可执行文件、静态库、共享库中的符号列表
strip 减肥,删除目标文件、可执行文件、静态库、共享库中的符号。
objdump 显示目标文件、可执行文件、静态库、共享库反汇编信息。

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

声明extern char** environ; 就可以使用。
操作环境变量表的函数:
char *getenv(const char *name);
功能:获取环境变量的值

int setenv(const char *name, const char *value, int overwrite);
功能:向环境变量表中添加环境变量
name:环境变量名
value:环境变量的值
overwrite:当环境存在时
为真修改环境变量的值
为假不修改环境变量的值

int putenv(char *string);
功能:name=value 添加或修改环境变量,如果已经存在则修改,不存在则添加。
返回值:成功返回0,失败返回-1。

int unsetenv(const char *name);
功能:删除环境变量
返回值:成功返回0,失败返回-1。

int clearenv(void);
功能:清空环境变量表

练习:
1、添加环境变量 HOME=/home/用户名
2、删除环境变量 LIBRARY_PATH
3、给LD_LIBRARY_PATH环境变量追加一个路径,用户主目录。
假如果LD_LIBRARY_PATH=/hehe/xixi
添加后LD_LIBRARY_PATH=/hehe/xixi:/home/用户名

错误处理
1、通过函数返回值表示错误
a、合法值表示成功,非法值表示失败。如计算大小、长度、查找
b、指针类型的返回值NULL或0xFFFFFFFF表示失败,其他表示成功。如malloc,mmap
c、返回0表示成功,-1表示失败,一般都是系统函数
d、永远成功,如printf
2、影响全局的错误编号 errno 定义在include<errno.h>文件中
char *strerror (int errnum);
根据编号找到错误原因 记录到日志中,或通过网络
perror(“func name”)可以直接显示错误原因
注意:error是一个全局变量,不能根据它的值判断是否产生错误

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

实现一个字符串查找函数,找到则返回子串第一次出现的位置,找不到则返回空
char* find_str(const char* str,char* sub)
实现一个求平均值的函数,考虑求和溢出,该函数不会失败
float avg(int f1,int f2);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值