UC - Unix/Linux 系统下C的开发
Unix/Linux 系统的常识
gcc编译器
gcc的用法
gcc处理c语言时,分为4个阶段:
1.预处理 - 针对指令
2.编译 - 狭义的编译,语法的检测等
3.汇编 - 从高级语言-汇编语言-机器语言
4.连接 - 把用到的各种资源打包到一起
注:通常讲的编译是广义的,包括 预处理、编译和汇编,生成 .o 文件(目标文件)
gcc的选项:
-v 查看编译器的版本
-E 只执行预处理,不做其他的(-o xx. i)
-S 生成汇编文件
-c 只编译不连接
-o 改变目标文件名(各种类型)
-Wall 显示更多的警告
预处理指令 - #warning #error #pragma
环境变量
静态库和共享库
C语言的错误处理
环境表
指令中,最常见的就是:
#include
#define
条件编译 - #if #endif #ifdef #ifndef
#warning 产生一个警告
#error 产生一个错误
#pragma 提供一些额外的功能
#pragma GCC dependency "文件名a"
比较a和当前文件的最后修改时间,如果a比当前文件新,产生警告
#pragma GCC poison 标识符/关键字 (poison:毒药)
禁止使用posion后面的单词,否则产生错误
#pragma pack(长度) - 指定结构对齐和补齐的基准长度
-----------------------------------------------------------
1 #include <stdio.h>
2 #define VERSION 3
3 #if (VERSION<3)
4 #error "版本低"
5 #elif (VERSION>3)
6 #warning "版本高"
7 #endif
8 #pragma GCC dependency "a.txt"//比较a.txt和当前文件的最后修改时间,如果a.txt新 产生警告
9 #pragma GCC poison goto//禁止使用goto
10 #pragma pack(1)
11 int main()
12 {
13 //goto ok;
14 ok: printf("hello c\n");
15 struct s
16 {
17 char c1;
18 short int i;
19 int i2;
20 char c2;
21 };
22 printf("size=%d\n",sizeof(struct s));
23 return 0;
24 }
-----------------------------------------------------------
环境变量就是 预先加载到内存中的某些常用数据,为了区分数据的用途,给数据起了变量名,这写变量统称为环境变量
常见环境变量:
PATH(Path) - 系统路径,命令/可执行文件的目录如果放入PATH,在运行时可以省略路径名
在bash中,使用export 环境变量名=值 可以配置环境变量
比如:export PATH=$PATH:.
$PATH就是把以前配置好的拿过来,防止覆盖
: 是Unix/Linux路径分隔符,windows是 ;
echo $PATH 输出PATH环境变量
如果想永久生效,可以在 登陆目录/.bashrc中配置。配置完成后,重启机器生效。或者:配置完成后用source .bashrc 也可以
CPATH/C_INCLUDE_PATH - 定位c的头文件
LIBRARY_PATH - 定位库文件
LD_LIBRARY_PATH - 运行时 加载共享库
C语言中,自定义的头文件查找方法有三种:
1.用“路径”方式查找,从当前目录出发
2.gcc -l 路径
3.配置环境变量CPATH
IDE - 集成开发环境(开发工具/编程软件)
商业开发中,代码需要打包,打包成库文件,而不是用多个 .o文件。Unix/Linux提供两种库文件:静态库、共享库(动态库)
静态库是代码的合集,在使用时直接复制代码。
优点:执行速度稍快,运行时不需要静态库
缺点:可执行文件非常庞大,不利于修改和维护
共享库是代码的合集,在使用时提供的是代码在库中的地址(函数指针)。
优点:可执行文件小,便于修改和维护
缺点:执行速度稍慢,运行时必须提供共享库
商业应用基本都是使用 共享库。
gcc -static hello.c 纯静态库
静态库的创建和使用(.a文件)
1.创建
1.1 写源代码,保存退出
1.2 编译源代码,生成目标文件(.o文件)
1.3 使用 ar -r libXX.a xxx.o 命令创建静态库文件(XX是库名,libXX.a是文件名)
2.调用
2.1 写调用源代码test.c,保存退出
2.2 编译 gcc -c test.c
2.3 连接,有三种方法:
a gcc test.o libXX.a 直接连接
b 双L连接,gcc test.o -l库名 -L库路径
c 配置LIBRARY_PATH,省略-L
gcc test.o -l库名
经验:以后开发需要提供 一个头文件和一个库文件
共享库的生成和使用(.so文件)
1.生成
1.1 写源代码,保存退出
1.2 编译 gcc -fpic -c add.c , 其中 -fpic省略也可以
1.3 gcc -shared add.o -o libXX.so 生成共享库文件(XX是库名,libXX.so是文件名)
2.调用
调用方式和静态库基本一样
共享库在使用时,也需要提供头文件和共享库文件,有些共享库文件名的后缀是 .so.数字
注:在运行时如果调用共享库需要配置 LD_LIBRARY_PATH 才能找到共享库(系统库不需要,已经加载)
命令ldd a.out 或者 库文件名 可以查看相关库
程序员可以在 代码中直接使用共享库
#include <dlfcn.h>
dlopen(const char *filename,int flag) - 打开共享库,失败返回NULL
dlsym(void *handle,const char *symbol) - 从打开的共享库中找函数(按函数名)
dlclose(void *handle) - 关闭共享库
dlerror(void) - 验证前面3个函数 是否出错,返回NULL代表没错
C语言的错误处理 - 后期语言基本都是使用异常机制进行错误处理,C语言中没有异常
C程序员一般都是用返回值 判断是否出错,有以下4种情况:
1.如果返回值类型为int,并且返回的数据不可能是负数,可以-1代表出错
2.如果返回值类型为int,并且返回的数据可能是负数,那么返回值就 只代表是否出错,而不再返回数据,数据 用指针带回来,返回-1代表出错,0代表 正确
3.如果返回值类型是指针,返回NULL代表出错,非空代表正确。某些函数返回(void*) -1 代表出错
4.如果不需要考虑出错问题,返回值类型都用void
注:上面的情况都只是经验,不是绝对的
C语言中函数的参数有三种:传入参数,传出参数,传入传出参数
练习:
有4个函数,设计一下错误处理(用返回值)
打印传入的字符串。
如果传入的字符串是“error”,返回“ok”,否则返回错误
生成0-9的随机数,如果随机到5,报错,其它数返回
比较两个数的大小并返回最大值,相等报错。
Unix/Linux 系统的常识
gcc编译器
gcc的用法
gcc处理c语言时,分为4个阶段:
1.预处理 - 针对指令
2.编译 - 狭义的编译,语法的检测等
3.汇编 - 从高级语言-汇编语言-机器语言
4.连接 - 把用到的各种资源打包到一起
注:通常讲的编译是广义的,包括 预处理、编译和汇编,生成 .o 文件(目标文件)
gcc的选项:
-v 查看编译器的版本
-E 只执行预处理,不做其他的(-o xx. i)
-S 生成汇编文件
-c 只编译不连接
-o 改变目标文件名(各种类型)
-Wall 显示更多的警告
预处理指令 - #warning #error #pragma
环境变量
静态库和共享库
C语言的错误处理
环境表
指令中,最常见的就是:
#include
#define
条件编译 - #if #endif #ifdef #ifndef
#warning 产生一个警告
#error 产生一个错误
#pragma 提供一些额外的功能
#pragma GCC dependency "文件名a"
比较a和当前文件的最后修改时间,如果a比当前文件新,产生警告
#pragma GCC poison 标识符/关键字 (poison:毒药)
禁止使用posion后面的单词,否则产生错误
#pragma pack(长度) - 指定结构对齐和补齐的基准长度
-----------------------------------------------------------
1 #include <stdio.h>
2 #define VERSION 3
3 #if (VERSION<3)
4 #error "版本低"
5 #elif (VERSION>3)
6 #warning "版本高"
7 #endif
8 #pragma GCC dependency "a.txt"//比较a.txt和当前文件的最后修改时间,如果a.txt新 产生警告
9 #pragma GCC poison goto//禁止使用goto
10 #pragma pack(1)
11 int main()
12 {
13 //goto ok;
14 ok: printf("hello c\n");
15 struct s
16 {
17 char c1;
18 short int i;
19 int i2;
20 char c2;
21 };
22 printf("size=%d\n",sizeof(struct s));
23 return 0;
24 }
-----------------------------------------------------------
环境变量就是 预先加载到内存中的某些常用数据,为了区分数据的用途,给数据起了变量名,这写变量统称为环境变量
常见环境变量:
PATH(Path) - 系统路径,命令/可执行文件的目录如果放入PATH,在运行时可以省略路径名
在bash中,使用export 环境变量名=值 可以配置环境变量
比如:export PATH=$PATH:.
$PATH就是把以前配置好的拿过来,防止覆盖
: 是Unix/Linux路径分隔符,windows是 ;
echo $PATH 输出PATH环境变量
如果想永久生效,可以在 登陆目录/.bashrc中配置。配置完成后,重启机器生效。或者:配置完成后用source .bashrc 也可以
CPATH/C_INCLUDE_PATH - 定位c的头文件
LIBRARY_PATH - 定位库文件
LD_LIBRARY_PATH - 运行时 加载共享库
C语言中,自定义的头文件查找方法有三种:
1.用“路径”方式查找,从当前目录出发
2.gcc -l 路径
3.配置环境变量CPATH
IDE - 集成开发环境(开发工具/编程软件)
商业开发中,代码需要打包,打包成库文件,而不是用多个 .o文件。Unix/Linux提供两种库文件:静态库、共享库(动态库)
静态库是代码的合集,在使用时直接复制代码。
优点:执行速度稍快,运行时不需要静态库
缺点:可执行文件非常庞大,不利于修改和维护
共享库是代码的合集,在使用时提供的是代码在库中的地址(函数指针)。
优点:可执行文件小,便于修改和维护
缺点:执行速度稍慢,运行时必须提供共享库
商业应用基本都是使用 共享库。
gcc -static hello.c 纯静态库
静态库的创建和使用(.a文件)
1.创建
1.1 写源代码,保存退出
1.2 编译源代码,生成目标文件(.o文件)
1.3 使用 ar -r libXX.a xxx.o 命令创建静态库文件(XX是库名,libXX.a是文件名)
2.调用
2.1 写调用源代码test.c,保存退出
2.2 编译 gcc -c test.c
2.3 连接,有三种方法:
a gcc test.o libXX.a 直接连接
b 双L连接,gcc test.o -l库名 -L库路径
c 配置LIBRARY_PATH,省略-L
gcc test.o -l库名
经验:以后开发需要提供 一个头文件和一个库文件
共享库的生成和使用(.so文件)
1.生成
1.1 写源代码,保存退出
1.2 编译 gcc -fpic -c add.c , 其中 -fpic省略也可以
1.3 gcc -shared add.o -o libXX.so 生成共享库文件(XX是库名,libXX.so是文件名)
2.调用
调用方式和静态库基本一样
共享库在使用时,也需要提供头文件和共享库文件,有些共享库文件名的后缀是 .so.数字
注:在运行时如果调用共享库需要配置 LD_LIBRARY_PATH 才能找到共享库(系统库不需要,已经加载)
命令ldd a.out 或者 库文件名 可以查看相关库
程序员可以在 代码中直接使用共享库
#include <dlfcn.h>
dlopen(const char *filename,int flag) - 打开共享库,失败返回NULL
dlsym(void *handle,const char *symbol) - 从打开的共享库中找函数(按函数名)
dlclose(void *handle) - 关闭共享库
dlerror(void) - 验证前面3个函数 是否出错,返回NULL代表没错
C语言的错误处理 - 后期语言基本都是使用异常机制进行错误处理,C语言中没有异常
C程序员一般都是用返回值 判断是否出错,有以下4种情况:
1.如果返回值类型为int,并且返回的数据不可能是负数,可以-1代表出错
2.如果返回值类型为int,并且返回的数据可能是负数,那么返回值就 只代表是否出错,而不再返回数据,数据 用指针带回来,返回-1代表出错,0代表 正确
3.如果返回值类型是指针,返回NULL代表出错,非空代表正确。某些函数返回(void*) -1 代表出错
4.如果不需要考虑出错问题,返回值类型都用void
注:上面的情况都只是经验,不是绝对的
C语言中函数的参数有三种:传入参数,传出参数,传入传出参数
练习:
有4个函数,设计一下错误处理(用返回值)
打印传入的字符串。
如果传入的字符串是“error”,返回“ok”,否则返回错误
生成0-9的随机数,如果随机到5,报错,其它数返回
比较两个数的大小并返回最大值,相等报错。