Linux 环境编程 day01 Linux系统介绍、GNU编译工具、静态/动态库、环境变量表

  • 学习Linux环境编程的原因
  • UNIX系统介绍
  • Linux系统介绍
  • GNU工程
  • POSIX标准
  • GNU通用公共许可证
  • GNU编译工具
    • 静态库的创建与使用
    • 共享库的创建与使用
  • 辅助工具
  • 错误处理
    • 通过函数返回值表式错误
    • 通过errno表示错误,系统的API出错时会影响errno的值。

学习Linux环境编程的原因

  C语言、C++语言、数据结构和算法,重点关注算法逻辑,不关注平台。UNIX系统、Linux系统,重点关注系统接口,需要关注代码的运行平台。通过学习操作系统的接口,来提高函数的设计能力,在理解操作系统的运行机制的基础上,写出功能更强、更安全、更高效的代码。

UNIX系统介绍

诞生于1971年美国AT&T公司的贝尔实验室,主要开发者是丹尼斯.里奇、肯.汤普逊。
系统特点:多用户、多任务、支持多种处理器架构、高安全性、高可靠性、高稳定性。
既可以构建大型关键业务系统的商业服务器,也可以构建面向移动终端、手持设备、可穿戴设备的嵌入式应用。(苹果的内核就是unix)

Linux系统介绍

是一款类UNIX系统,免费开源,不同的发行版使用相同的内核,一般用在手机、平板、路由器、台式计算机、大型计算机、超级计算机。从严格意义上来说,Linux仅指的是操作系统内核,隶属于GNU工程,发起人叫 Linus Benedict Torvalds。标志:是一只企鹅,是南极的标志性动物,而目前南极不属于任何国家,为全人类所共有的,而Linux用它来当操作系统就意味这款系统属于全人类。Minix操作系统:荷兰的Andrew S. Tanenbaum教授所开发的一款不包含任何UNIX源码的类UNIX系统,Linus Torvalds虽然深受Minix的启发写出了第一版本的Linux内核。

GNU工程

发起于1984年,由自由软件基本会提供支持,它基本原则就是共享,目的是发展出一个有别一切商业UNIX系统的,免费且开源的类UNIX系统,也叫GNU Linux,是目前全球最大的开源组织。

POSIX标准

可移植操作系统接口(英语:Portable Operating System Interface,缩写为POSIX)是IEEE为要在各种UNIX操作系统上运行软件,而定义API的一系列互相关联的标准的总称。

Linux完全遵循了POSIX标准,所以在Linux下编写的代码,经过稍微修改可移植到UNIX上。这两操作系统的API,名字相同、参数相同、返回值相同。

GNU通用公共许可证

简称为GPL,是由自由软件基金会发行的用于计算机软件的协议证书,使用该证书的软件被称为自由软件。大多数的GNU程序和超过半数的自由软件使用它。

GNU编译工具

是GNU组织为了编译Linux内核源码而开发的一款编译工具,经过长时间的发展目前已经成为一个编译平台,能够支持多种编程语言(C、C++、Java、Objective-C、Ada、C#)和操作系统(UNIX、Linux、Windows),gcc -v 可以查看编译器版本。构建(Build)过程:预处理、编译、汇编、链接gcc -E code.c -o code.i -> code.igcc -S code.i -> code.sgcc -c code.s -> code.ogcc code.o ... -> a.out文件后缀:.h 头文件.h.gch 头文件的编译结果,会被优先使用,建议立即删除.c 源文件.i 预处理文件.s 汇编文件.o 目标文件.a 静态库文件.so 共享(动态)库文件参数:-E 预处理-S 产生汇编文件-c 只编译不链拉-o 指定输出文件的名字-Wall 尽可能多的产生警告-Werror 把警告当错误处理-x 指定源代码的语言-g 生成调试信息-I 指定头文件的加载路径-L 指定库文件的加载路径-lname 要额外加载的库名libname.a libname.so-pedantic 对不符全ANSI标准的语法产生警告(对gcc扩展的语法产生警告)。以下几个都是GNU独有的语法:typeof case 1 ... 5#define debug(...)编译多个文件:1、头文件作用头文件卫士声明外部变量、函数、类、结构、联合、枚举定义宏、类型别名包含其它头文件2、包含头文件时要注意#include <> 从系统指定的位置加载。#include "" 先从当前目录下加载,如果当前目前没有再从系统指定的位置加载。当没函数声明时,编译器会猜测函数的格式,这种猜测行为叫函数隐式声明。编译器支持的预处理指令:#include 导入头文件#define 定义宏常量、宏函数## 连接两个标识符# 把参数转换成字符串字面值#undef 删除宏#if 判定#ifdef/#ifndef 宏定义判定#else 与#if/#ifdef/#ifndef配合使用#elif 相当于else if#endif 判定的结束标志#error 产生错误#warning 产生警告#line 修改当前行号#pragma GCC dependency "文件名.c" 监控某个文件不被私自修改#pragma GCC poison <标识> 把某个标识符当病毒处理,监控某个标识符不被使用。#pragma pack(1/2/4) 修改结构、联合的补齐、对齐字节数
预定义的宏:__FILE__    文件名__func__    函数名__LINE__    行号__DATE__    日期__TIME__    时间头文件的三种定位方式:
1、#include "路径/xxx.h" 直接把路径写在代码中,但如果头文件路径发生变化,需要修改源代码。2、gcc -I目录 在编译时指定加载头文件的路径。(大写的i,不是小写L)加了这个之后添加头文件可以使用<>和""添加指定目录的头文件
例如:有一个头文件tools.h在上一级目录,那么在编译的时候输入gcc 源文件名 -I ../,就能把这个头文件导入了。 3、设置C_INCLUDE_PATH环境变量,来添加头文件的查找路径。添加完之后,可以用#include<头文件名>导入该头文件了。打开配置文件:vim ~/.bashrc在文件末尾添加一行内容: export C_INCLUDE_PATH=$C_INCLUDE_PATH:.......(.....处填写需要加入头文件的位置)重新加载配置文件:source ~/.bashrcenv命令可以查看所有环境变量。扩展:PATH环境变量代表是命令的查找路径,把.添加进去以后再执行程序就不需要./了。注意:删除环境变量时需要退出终端,再重新打开

库:也叫代码库,把一个些目标文件合并在一起方便使用,有静态库和共享库两种。
静态库:在链接时把库的二进制指令复制到调用模块中。
共享库:会和调用者一起加载到内存,当执行调用语句时会从程序的调用位置跳转到共享库中运行。
优缺点:静态库的优点是运行速度快,但维护麻烦,当静态库中人内容更新后需要重新编译程序,使用静态库编译出的可执行文件会比共享库的要大。共享库的优点是使用方便,共享库如果发生变化不需要重新编译程序,使用它编译出的可执行文件比使用静态库要小,运行速度要比使用静态库慢。
注意:静态库的扩展名是.a,共享库的扩展名是.so,共享库要有执行权限。

静态库的创建与使用

1、创建静态库编辑静态库原码:vim .c/.h编译出目标文件:gcc -c xxx.c -> xxx.o把目标文件打包成静态库文件:ar -r libxxx.a x1.o x2.o ...ar 是一个专门控制静态库的命令-r 把目录文件合并成一个静态库,如果静态库文件已经存在则更新。-q 向静态库中添加目录文件-t 查看静态库中有哪些目标文件-d 从静态库中删除目标文件-x 把静态库展开为目标文件
2、使用静态库1、直接调用把共享库当作目标文件一样,与调用者的目标文件一起合并出可执行文件。gcc main.c libtools.a2、通过gcc -L参数来指定库的路径gcc main.c -L../tools/ -ltools3、通过设置LIBRARY_PATH环境变量来指定库的路径1、打开~/.bashrc文件 vim ~/.bashrc2、在末尾添加:export LIBRARY_PATH=$LIBRARY_PATH":/home/zhizhen/tools/"3、保存退出后,执行:source ~/.bashrcgcc main.c -l 头文件名字(无后缀) 需要通过-l来指定库名

共享库的创建与使用

1、创建共享库编辑静态库原码:vim .c/.h编译出目标文件:gcc -c -fpic xxx.c -> xxx.o把目标文件打包成共享库:gcc -shared x1.o x2.o ... -o libxxx.so-fpic编译出位置无关代码,在代码中使用相对地址,这样共享库就可以遇到内存的任何位置。
2、使用共享库1、直接调用gcc main.c libcalc.so注意:需要设置共享的加载路径,LD_LIBRARY_PATH2、通过设置LIBRARY_PATH环境变量来指定库的路径gcc main.c -l calc 需要通过-l来指定库名注意:如果静态库和共享库同时存在,优先使用共享库,通过-static可以指定使用静态库。3、通过gcc -L参数来指定库的路径gcc main.c -L./calc/ -lclac4、动态加载共享库#include <dlfcn.h>void *dlopen(const char *filename, int flag);功能:打开共享库filename:共享库的路径flag:打开方式RTLD_LAZY:延迟加载,使用到共享库时再加载RTLD_NOW:立即加载返回值:成功返回共享库的句柄,失败返回NULLvoid *dlsym(void *handle, const char *symbol);功能:通过函数名在共享库中获取函数指针handle:共享库的句柄symbol:函数名返回值:函数地址,失败返回NULLchar *dlerror(void);功能:获取错误信息int dlclose(void *handle);功能:卸载共享库注意:编译时添加-ldl参数

辅助工具

nm:查看目标文件、可执行文件、静态库、共享库文件的符号列表。
ldd:查看可执行文件依赖了哪些共享库
strip:删除目标文件、可执行文件、静态库、共享库文件中符号列表、调试信息,可以有效降低文件的大小。
objdump:可以显示二进制文件的汇编信息

错误处理

通过函数返回值表式错误

    1、返回值合法表示成功,非法表示失败。2、返回有效指针表示成功,返回NULL/0xFFFFFFFF 表示失败。3、成功返回0,失败返回-1。4、永远成功,如:printf

通过errno表示错误,系统的API出错时会影响errno的值。

    可以根据errno的错误编号来获取错误原因1、strerror 根据errno错误转换字符串信息2、printf %m 同上3、perror 同上注意:errno是一个全局的变量,需要通过函数的返回值判断函数执行是否出错误,再通过errno获取错误原因。如果API执行成功并不会修改errnor值,所以不能通过errno的值判断函数执行是否成功。

九、环境变量表
每个程序执行时都收到一张操作系统传递给的环境变量表,方便该程序了解当系统的环境配置,env命令可以在终端查看环境变量表。

环境变量表是一个以NULL结尾的字符指针数数组。
该表是系统环境变量的拷贝,程序对当前这张进行修改,并不影响操作系统。
char *getenv(const char *name);
功能:根据环境变量名获取环境变量的值int putenv(char *string);
功能:name=value向环境变量表中添加环境变量,环境变量不存在则添加,存在则修改。
返回值:0表示成功,非零表示失败
注意:不会把字符串拷贝到环境变量表中,而是把字符串地址存储到数组中。int setenv(const char *name, const char *value, int overwrite);
功能:以name,value的形式向环境变量表添加环境变量,如果环境变量不存在则直接添加,如果存在则根据overwrite参数进行修改。
overwrite:零 环境变量已经存在则不修改非零 功能相当于putenv
返回值:0表示成功,非零表示失败int unsetenv(const char *name);
功能:删除环境变量
返回值:0表示成功,非零表示失败int clearenv(void);
功能:清空环境变量

Linux 环境编程 day01 Linux系统介绍、GNU编译工具、静态/共享库、环境变量表相关推荐

  1. 从事UNIX/LInux服务器编程最方便的代码编译工具------(eclipse for c/c++)、(FileZilla)、(Secure CRT) 这三种一定要一起使用 之3...

    这篇博文主要是安装eclipse for c/c++.同时也让我感受到eclipse工具的强大,尽然也支持c++,虽然在linux编程中仅仅起到编码的作用但是功能不容小觑. 下面进行eclipse f ...

  2. alin的学习之路(Linux系统编程:三)(vim,gcc,库,gdb)

    alin的学习之路(Linux系统编程:三)(vim,gcc,库,gdb) 1.vim的使用 vim有三种模式:命令模式,末行模式,编辑模式 光标的移动[命令模式] h 向左 ,j 向下,k 向上,l ...

  3. linux c编程项目实例,Linux c编程实例_例子

    例一:字符与整型变量的实现 #include int main() { int c1,c2; char c3; c1='a'-'A'; c2='b'-'B'; c3='c'-; printf(&quo ...

  4. linux c 如何编译静态库,Linux C 编程入门之一:gcc 编译动态库和静态库

    主调用程序源代码3-1:main.c /** * main.c */ #include #include #include "hello_fn.h" int main () { h ...

  5. linux环境编程unp,linux网络编程之怎么配置好unp.h文件

    1.获取unp源码 然后用tar -zxvf unpv13e.tar.gz命令解压 2.进入unpv13e目录执行configure cd unpv13e ,然后执configure文件 3.打开RE ...

  6. 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)

    文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...

  7. linux c++编程教程,Linux下的C++编程入门教程.ppt

    <Linux下的C++编程入门教程.ppt>由会员分享,可在线阅读,更多相关<Linux下的C++编程入门教程.ppt(14页珍藏版)>请在人人文库网上搜索. 1.Linux下 ...

  8. 【Linux系统编程】Linux进程管理

    00. 目录 文章目录 00. 目录 01. 概述 02. 进程相关概念 03. 进程的状态 04. 进程调度 05. 程序调度函数 06. 附录 01. 概述 在Linux的内核的五大组成模块中,进 ...

  9. 【Linux系统编程】Linux系统调用

    00. 目录 文章目录 00. 目录 01. 系统调用概述 02. 系统调用实现 03. 系统调用和库函数的区别 04. 附录 01. 系统调用概述 系统调用顾名思义,说的是操作系统提供给用户程序调用 ...

最新文章

  1. 谈谈服务雪崩、降级与熔断
  2. R语言stats包的setNames函数和data.table包的setnames函数为数据对象设置名称实战
  3. 自动化测试有缺点吗?
  4. 100m和1000m网线的常见制作方法
  5. Python元组tuple(不可变)
  6. python36 mysql_python-day36(初识MySQL数据库)
  7. 转载-jmeter进阶功能
  8. python代码_Python发送邮件基础知识与代码讲解!
  9. Unity的渲染管线
  10. poi解析excel文件(支持xls和xlsx)java学习版
  11. 群晖修改php文件系统,群晖6.2版本修改eSATA挂载NTFS硬盘设置方法
  12. 计算机断电无法启动不了系统,电脑突然断电后无法启动怎么回事
  13. 51单片机74HC595级联测试proteus
  14. 对焦过程中消除摩尔纹
  15. Linux怎么给命令创建别名,linux设置命令别名
  16. 今天不发技术文,发点粉丝福利
  17. Jenkins框架原理
  18. 更相减损术--最大公约数
  19. FITC Phalloidin|FITC标记鬼笔环肽,915026-99-2
  20. 程序员的另面爱好(一)

热门文章

  1. 管理大师德鲁克60句经典名言,建议领导者最少读3遍,实用干货
  2. 代码敲累了,停一下,来欣赏下顶级配色~
  3. JVM----------垃圾收集器详解
  4. android4.1动态壁纸,动态壁纸大全APP
  5. 恒压板框过滤实验数据处理_襄樊米粉板框压滤机专业生产,非金属矿压滤机
  6. 什么算超级计算机,超级计算机都算什么?
  7. 【SpinalHDL快速入门】4.6、复合类型之Vec
  8. 七年级上计算机教学记录,七年级信息技术上册教学反思
  9. 七年级计算机的发展是教案,七年级信息技术上学期 第三课计算机的发展与应用 教案...
  10. 评财新网县级公立医院改革方案有四大虚招