达内Unix c编程.docx
- 文档编号:6005419
- 上传时间:2023-01-02
- 格式:DOCX
- 页数:32
- 大小:258.50KB
达内Unix c编程.docx
《达内Unix c编程.docx》由会员分享,可在线阅读,更多相关《达内Unix c编程.docx(32页珍藏版)》请在冰豆网上搜索。
达内Unixc编程
Unix环境与编译工具
讲稿
Version1.0
UnixProgrammingEnvironment&Tools
达内IT培训集团
加拿大达内集团
研发二部
修订历史
版本
1.0
目录
1.GCC的使用5
1.1.编译C程序5
1.1.1.编译执行文件5
1.1.1.1.C程序中的文件后缀名6
1.1.1.2.编译单源程序6
1.1.1.3.编译多源程序7
1.1.2.编译目标文件9
1.1.2.1.编译成目标文件9
1.1.2.2.使用目标文件编译9
1.1.3.预处理10
1.1.3.1.预处理编译10
1.1.3.2.编译预处理文件10
1.1.3.3.预处理指令介绍10
1.1.3.4.预定义宏介绍19
1.1.3.5.预处理与make选项20
1.1.3.6.编译环境变量21
1.1.4.生成汇编21
1.1.4.1.编译成汇编21
1.1.4.2.编译汇编21
1.1.5.创建静态库22
1.1.5.1.编译静态库22
1.1.5.2.ar指令22
1.1.5.3.使用静态库23
1.1.6.创建共享库23
1.1.6.1.编译共享库23
1.1.6.2.定位共享库24
1.1.6.3.使用共享库24
1.1.6.4.库工具程序介绍27
1.1.6.5.其他编译选项32
1.1.7.C语言扩展33
1.1.7.1.控制C语言版本33
1.2.编译C++程序(基本上同C一样)34
2.GDB的使用36
2.1.GDB基础36
2.1.1.生成调试信息36
2.1.2.启动调试36
2.1.3.调试模式设置37
2.1.4.退出调试37
2.1.5.查看帮助38
2.2.使用GDB控制调试过程39
1.GCC的使用
1.1.编译C程序
1.1.1.编译执行文件
Linux下最常用的编译器是gcc.(GNUCompilerCollection)她通过不同的前端模块来支持对各种不同语言的。
编译,如C、C++、ObjectC、Java、Fortran、Pascal、Ada等语言。
GCC是可以在多种硬件平台上编译出可执行。
程序的超级编译器.其执行效率与一般的编译器相比,平均效率要高20%--30%.
在使用GCC编译程序时,编译过程可以细分为4个阶段:
a.预处理。
b.编译。
c.汇编。
d.链接。
程序员可以对编译过程进行控制,同时GCC提供了强大的代码优化功能。
查看gcc的版本:
gcc–v
1.1.1.1.C程序中的文件后缀名
扩展名
说明
.a
静态对象库
.c
需要预处理的C语言源代码
.h
C语言源代码头文件
.i
不需要预处理的C语言源代码
.o
目标文件
.s
汇编语言代码
.so
共享对象库
1.1.1.2.编译单源程序
语法:
gcc[选项参数]c文件
例子:
gccch01.c
通用选项参数说明如下:
1、指定输出文件名
-o指定输出文件名
例子:
gcc-omainch01.c
2、警告与提示.
-pedantic检测不符合ANSI/ISOC语言标准的源代码,使用扩展语法的地方将产生警告信息。
-Wall生成尽可能多的警告信息。
-Werror要求编译器将警告当做错误进行处理。
例子:
gcc–Wall–omainch01.c
3、指定编译文件类型
-x指定编译代码类型,c、c++、assembler,none。
None根据扩展名自动确认。
例子:
gcc–xc-Wall–omainch01.c
4、生成调试信息与优化
-g生成调试信息
-O优化
5、建议:
在编译任何程序的时候都带上-Wall选项。
示例:
#!
/bin/bash
#GCC使用
echo"编译......"
gcc-xc-omain-Wallch01.c
echo"执行......"
./main
调试与优化:
1.1.1.3.编译多源程序
1、语法:
gcc[选项]C源代码1C源代码2C源代码3
2、示例:
代码ch01.c
#include
/*演示编译器gcc*/
//intadd(int,int);
intmain()
{
printf("%d+%d=%d\n",34,68,add(34,68));
return0;
}
代码ch01_1.c
/*函数实现*/
intadd(inta,intb)
{
returna+b;
}
编译脚本
gcc-xc-omain-Wallch01.cch01_1.c
注意:
在调用处,最好加上显示add函数声明,否则会报一个警告(去掉-Wall不会警告)。
Add函数的声明可以单独存放一个文件,就是头文件。
思考:
头文件的作用是什么?
1.1.2.编译目标文件
1.1.2.1.编译成目标文件
语法:
gcc-cC源代码文件
示例:
方式一:
每个C文件都生成一个目标文件
gcc-cch01.cch01_1.c
方式二:
多个C文件生成一个目标文件
gcc-omain.o-cch01.cch01_1.c
1.1.2.2.使用目标文件编译
语法:
gcc–o输出文件名目标文件1目标文件1
示例:
方式一:
编译多个目标文件
gcc-omainch01.och01_1.o
方式二:
编译一个目标文件
gcc-omainmain.o
1.1.3.预处理
1.1.3.1.预处理编译
语法:
gcc-EC源代码文件
示例:
gcc-E-och01.ich01.c
gcc-E-och01_1.ich01_1.c
注意:
预处理每次只能处理一个文件。
不能处理多个文件,就是每个.c文件对应一个.i文件。
不指定–o选项,预处理的结果输出到标准输出设备。
1.1.3.2.编译预处理文件
gcc-omainch01.ich01_1.i
1.1.3.3.预处理指令介绍
在C语法中引入很多预处理指令,这些指令影响到gcc的预编译处理结果。
预编译指示符号
说明
#define
定义宏
#elif
elseif多选分支
#else
与#if、#ifndef、#ifdef结合使用
#error
产生错误,挂起预处理程序
#if
判定
#endif
结束判定
#ifdef
判定宏是否定义
#ifndef
判定宏是否定义
#include
将指定的文件插入#include的位置
#include_next
与#include一样,但从当前目录之后的目录查找
#line
指定行号
#pragma
提供额外信息的标准方法,可用来指定平台
#undef
删除宏
#warning
创建一个警告
##
连接操作符号,用于宏内连接两个字符串
示例:
1、#define、#undef
#include
/*演示编译器gcc*/
#defineYQ
#defineLOUIS"ENGLISHNAME"
intmain()
{
printf("%s\n",LOUIS);
/*
#undefLOUIS
*/
printf("%s\n",LOUIS);
return0;
}
2、#error、#warning
#include
/*演示编译器gcc*/
intmain()
{
inta=20;
if(a==2)
{
//#error"错误很多"
#warning"警告一下!
"
}
return0;
}
3、#if、#elif、#else、#endif
#include
#defineVERSION3
/*演示编译器gcc*/
#if(VERSION<2)
#error"版本低"
#else
#warning"版本高"
#endif
intmain()
{
printf("Hellogcc使用!
\n");
return0;
}
4、#ifdef、#else、#endif
#include
#defineDEBUG
/*演示编译器gcc*/
#ifdefDEBUG
#warning"调试"
#else
#warning"非调试"
#endif
//这个指示符号的使用还是比较广泛的
intmain()
{
printf("Hellogcc使用!
\n");
return0;
}
使用#ifdef、#define可以防止头文件二次引入。
5、#include、#include_next
说明:
1.系统头文件使用#include<…>
2.用户头文件使用#include“…”
规则:
1.系统头文件会在I参数指定得目录中查找。
2.用户头文件会在当前目录查找。
3.Unix标准系统目录
/usr/local/include
/usr/lib/gcc-lib/…/版本/include
/usr/…/include
/usr/include
4.编译C++优先查找/usr/include/g++v3
5.#include
6.#include的文件名不不含扩展,*、?
无意义。
除非文件名中包含*。
6.#line
#include
intmain()
{
intre=0;
printf("Hellogcc使用!
\n");
for(inti=0;i<200)
{
re+=i;
}
printf("out:
%d\n",re);
//代码行数被修改
#line200
//另外得用法
//#line200"ch01_c.c"
printf("out:
%d\n",re,a);//人为错误
printf("out:
%d\n",re);
return0;
}
7、#pragma
所有GCC的pragma都定义两个词GCC+其他
1.#pragmaGCCdependency文件名提示符号
测试文件的时间戳,当指定文件比当前文件新的时候产生警告。
#include
#pragmaGCCdependency"ch02.c"
intmain()
{
intre=0;
printf("Hellogcc使用!
\n");
inti;
for(i=0;i<200;i++)
{
re+=i;
}
printf("out:
%d\n",re);
return0;
}
2.#pragmaGCCpoison
每次使用指定名字就会产生警告。
#include
#pragmaGCCdependency"ch02.c"
#pragmaGCCpoisonprintfadd
intmain()
{
intre=0;
printf("Hellogcc使用!
\n");
inti;
for(i=0;i<200;i++)
{
re+=i;
}
printf("out:
%d\n",re);
return0;
}
3.#pragmaGCCsystem_header
该指示符后的代码都做为系统头文件的一部分。
提示:
#pragma有一个等价的宏_Pragam
#include
#pragmaGCCdependency"ch02.c"
//#pragmaGCCpoisonprintfadd
intmain()
{
intre=0;
printf("Hellogcc使用!
\n");
inti;
_Pragma("GCCpoisonprintfadd")
for(i=0;i<200;i++)
{
re+=i;
}
printf("out:
%d\n",re);
return0;
}
8、##
#include
#pragmaGCCdependency"ch02.c"
//#pragmaGCCpoisonprintfadd
#defineHELLO(a)a##200
intmain()
{
intre=0;
printf("Hellogcc使用:
%s!
\n",HELLO(99));
return0;
}
1.1.3.4.预定义宏介绍
预定义的宏很多,下面列出常用的。
宏
说明
__BASE_LINE__
源代码的完整路径
__cplusplus
C++有效,程序不符合标准为1,否则是标准的年月
__DATE__
日期
__FILE__
源代码文件名
__func__
当前函数名
__FUNCTION__
同上
__INCLUDE_LEVEL__
包含层数,基本的为0
__LINE__
行数
__TIME__
时间
示例:
#include
intmain()
{
printf("Hellogcc使用:
%d!
\n",__LINE__);
printf("Hellogcc使用:
%s!
\n",__DATE__);
printf("Hellogcc使用:
%s!
\n",__BASE_FILE__);
return0;
}
1.1.3.5.预处理与make选项
选项
说明
-M
输出适合makefile的规则
-MD
同上,需要显示打开-E
-MMD
与-M同,但不列出头文件
-MF
指定输出文件名,与MMD,-MM,-M结合使用
-MG
假设头文件存在并不包含其他文件
-MM
与-M同,但不列出系统头文件
-MP
与-M或-MM使用,为每个包含文件生成哑目标
-MT
与-M或-MM使用,指定makefile规则的目标文件名
示例:
gcc-MG-MM-MFmakefilech01.c
效果
1.1.3.6.编译环境变量
C_INCLUDE_PATH:
查找头文件的目录。
C。
CPATH:
查找头文件,相当于-l选项。
CPLUS_INCLUDE_PATH:
查找头文件的目录。
C++。
LD_LIBRARY_PATH:
编译没有影响,主要影响运行。
指定目录便于定位共享库。
LIBRARY_PATH:
查找连接文件,相当于-l选项。
1.1.4.生成汇编
1.1.4.1.编译成汇编
gcc-Sch01.cch01_1.c
注意:
汇编编译也要依赖检验的。
1.1.4.2.编译汇编
gccch01.sch01_1.s-omain
1.1.5.创建静态库
1.1.5.1.编译静态库
gcc-c-staticch01_1.c
其中-static可选。
1.1.5.2.ar指令
ar-rlibmy.ach01_1.o
语法:
ar[选项]归档文件名目标文件列表
指令ar的常用选项
选项
说明
-d
从归档文件删除指定目标文件列表。
-q
将指定目标文件快速附加到归档文件末尾。
-r
将指定目标文件插入文档,如果存在则更新。
-t
显示目标文件列表
-x
把归档文件展开为目标文件
1.1.5.3.使用静态库
gcc-omainch01.clibmy.a
如果libmy.a在LIBRARY_PATH的指定目录中,还可以采用如下方式编译。
gccch01.c-omain-lmy
注意:
上面的先后位置错误可能导致编译错误。
1.1.6.创建共享库
1.1.6.1.编译共享库
编译共享库分成两个部分:
1.编译成位置独立代码的目标文件,选项-fpic
2.编译成共享库,选项-shared
gcc-c-fpicch01_1.c
gcc-sharedch01_1.o-olibmy.so
使用一条指令的效果一样
gcc-fpic-sharedch01_1.c-olibmy.so
1.1.6.2.定位共享库
共享库编译的时候与静态库一样依赖LIBRARAY_PATH,运行的时候依赖LD_LIBRARY_PATH。
下面是配置的LD_LIBRARY_PATH
规则:
1.查找LD_LIBRARY_PATH,目录使用冒号分隔。
2./ect/ld.so.cache中找到的列表。
工具ldconfig维护。
3.目录/lib
4.目录/usr/lib
1.1.6.3.使用共享库
gccch01.clibmy.so-omain
在代码中动态加载共享库:
共享库代码
intadd(inta,intb)
{
intc=a+b;
c=c/2;
returnc;
}
调用共享库代码
#include
#include
#include
intmain()
{
/*动态库*/
void*handle;
/*加载中的错误描述*/
char*error;
/*调用的函数指针*/
int(*myadd)(int,int);
/*加载共享库*/
handle=dlopen("./libadd.so",RTLD_LAZY);
error=dlerror();
if(error)
{
printf("libloaderror:
%s\n",error);
exit
(1);
}
myadd=dlsym(handle,"add");
error=dlerror();
if(error)
{
printf("libloaderror:
%s\n",error);
exit
(1);
}
inta=myadd(23,89);
printf("out:
%d\n",a);
dlclose(handle);
return0;
}
说明:
共享库的四个函数
SYNOPSIS
#include
void*dlopen(constchar*filename,intflag);
char*dlerror(void);
void*dlsym(void*handle,constchar*symbol);
intdlclose(void*handle);
其中dlopen的参数flag的含义如下:
RTLD_LAZY:
符号查找时候才加载。
RTLD_NOW:
马上加载。
1.1.6.4.库工具程序介绍
1、ldconfig
生成文件/etc/ld.so.cache2新版本:
ldconfig-v
其他选项:
选项
说明
-n
不产生缓冲文件,列出指定目录下的库
-p
显示缓存文件中所有库按字母排序的列表,包括连接库的完整路径
-v
示例:
ldconfig-v
ldconfig-vn/lib
ldconfig-vnp/lib
2、nm
列出目标文件中的符号名:
nmlibmy.a
其他常用参数
选项
说明
-p
不排序显示
-r
逆序排列显示
--size-sort
大小排列显示
-o
用源文件标识成员符号
-s
包含模块的索引信息
-D
对共享库显示动态符号,而不是静态符号
-g
显示定义为外部的符号
示例:
3、strip
去除指定目标文件与静态库中的调试信息:
stripch01_1.olibmy.a
4、ldd
列出共享库的依赖关系:
lddlibmy.so
5、objdump
显示目标文件的内部结构:
objdump–f–h–EBhello.o
1.1.6.5.其他编译选项
-I添加编译器搜索头文件的目录。
-L添加编译器搜索库文件的目录。
-l指示编译器链接指定的库文件。
总结常用编译选项
-c取消链接,生成目标文件
-Dmacro定义指定的宏,在代码中用#idef检测
-E预处理输出到标准输出设备
-g3获得调试的详细信息
-I头文件的搜索目录
-L库文件的搜索目录
-l库文件
-O-O2-O3编译优化
-S汇编输出
-v启动所有警报
-Wall发生警报时取消编译
-w禁止所有警报
1.1.7.C语言扩展
1.1.7.1.控制C语言版本
版本
说明
-ansi
编译标准程序,与GNU兼容
-pedantic
严格按照标准,提示警告信息
-std==c89
ISOC89标准
-std=C99
ISOC99标准
-std=gnu89
具有GNU扩展功能的ISOC89标准,某些C99标准
-traditional
兼容最原始的C语法检测
1.1.7.2.对齐
1.1.7.3.数组扩展
1.1.7.4.属性
1.1.7.5.使用复合语句的返回值
1.1.7.6.枚举不完全类型
1.1.7.7.函数原型
1.1.7.8.整数
1.1.7.9.更换关键字
1.1.7.10.标识地址
1.1.7.11.局部标签
1.1.7.12.switch语句
1.1.7.13.typedef
1.1.7.14.typeof
1.1.7.15.联合类型强制转换
1.2.编译C++程序(基本上同C一样)
1.2.1.编译执行文件
1.2.1.1.C++后缀名
1.2.1.2.编译单源程序
1.2.1.3.编译多源程序
1.2.2.编译目标文件
1.2.2.1.编译成目标文件
1.2.2.2.使用目标文件编译
1.2.3.预处理
1.2.3.1.预处理编译
1.2.3.2.使用预处理文件编译
1.2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 达内Unix c编程 Unix 编程
![提示](https://static.bdocx.com/images/bang_tan.gif)