linux下C编程详解

合集下载

Linux下C编程

Linux下C编程
第五章 Linux下C编程 Linux下
5.1 C语言简介 C语言简介
在80年代末期美国国家标准协会 80年代末期美国国家标准协会 (American National Standards Institute)发布了一个被称为ANSI C的 Institute)发布了一个被称为ANSI C的C 语言标准。这更加保证了将来在不同平台 上的C 上的C的一致性。 Linux上可用的C编译器是GNU C编译器, Linux上可用的C编译器是GNU C编译器, 它建立在自由软件基金会的编程许可证的 基础上,因此可以自由发布。你能在Linux 基础上,因此可以自由发布。你能在Linux 的发行光盘上找到它
5.3 用gdb调试GCC程序 gdb调试GCC程序
gdb是一个用来调试C C++程序的常用调 gdb是一个用来调试C和C++程序的常用调 试工具之一。 gdb所提供的一些功能: gdb所提供的一些功能: 监视程序中变量的值。 设置断点以使程序在指定的代码行上停止 执行。 逐行执行代码。 分析崩溃程序的产生的core文件 分析崩溃程序的产生的core文件
程序自动维护工具make 程序自动维护工具make
make是一种自动生成和维护目标程序的工具。 make是一种自动生成和维护目标程序的工具。 可以调用编译器、连接器等 根据程序各部分的修改情况,重新编译链接目 标代码 输入make命令后,系统自动检测系统文件和 输入make命令后,系统自动检测系统文件和 以定义的规则,完成整个创建过程
基本编译选项
-o选项 你能用 -o 编译选项来为将产生的可执行文件指 定一个文件名来代替 a.out。 a.out。 例:gcc 例:gcc –o count count.c -c选项:告诉GCC仅把源代码编译为目标代码而 选项:告诉GCC GCC仅把源代码编译为目标代码而 跳过汇编和连接的步骤。这个选项使用的非常频 繁,因为它使得编译多个C 繁,因为它使得编译多个C程序时速度更快并且 更易于管理。缺省时GCC建立的目标代码文件有 更易于管理。缺省时GCC建立的目标代码文件有 一个.o的扩展名。 一个.o的扩展名。 例:gcc 例:gcc –c test2.c

第三章Linux下的C编程

第三章Linux下的C编程

Emacs剪切和粘贴 剪切和粘贴
目录
目录内容
目录 M-k C-y
目录内容 剪切从光标位置到句 尾的内容
M剪切光标前的单词 Delete M-d C-k 剪切光标前的单词
剪切从光标位置到行尾 的单词
将缓冲区中的内容粘 贴到光标所在的位置 C-x u 撤销操作(先操作 C撤销操作( x,接着再单击 ) ,接着再单击u)
Vi编辑器 编辑器
Linux系统提供了一个完整的编译器家族系 系统提供了一个完整的编译器家族系 列:Ed,Ex,Vi和Emacs等;按功能它们 , , 和 等 可以分为两大类:行编辑器( , ) 可以分为两大类:行编辑器(Ed,Ex)和 全屏编辑器( , 全屏编辑器(Vi,Emacs)。 )。 行编辑器每次只能对一行进行操作。 行编辑器每次只能对一行进行操作。 全屏编辑器可以对整个屏幕进行编辑, 全屏编辑器可以对整个屏幕进行编辑,用 户编辑的文件直接显示在屏幕上,克服了 户编辑的文件直接显示在屏幕上, 行编辑的那种不知管的操作方式。 行编辑的那种不知管的操作方式。
注释: <chr>表示按住 表示按住Ctrl键的同时键入字符 键的同时键入字符<chr>,因此 因此, 注释:C-<chr>表示按住Ctrl键的同时键入字符<chr>,因此, C-f就表示按住Ctrl 键同时键入f。 就表示按住Ctrl 键同时键入f M-<chr>表示当键入字符<chr>时同时按住Alt键。 <chr>表示当键入字符 表示当键入字符<chr>时同时按住 键 时同时按住Alt
中保存文档的功能键为“ 在Emacs中保存文档的功能键为“C-x C中保存文档的功能键为 s”,这是在屏幕底下回出现 , “Wrote/root/workplace/editor/why”字 字 样。 Emacs有自动保存机制,自动保存的文件 有自动保存机制, 有自动保存机制 名前后都有一个“ , 名前后都有一个“#”,例如编辑名为 的文件, “hello.c”的文件,自动保存后为 的文件 “#hello.c#”.

linuxc编程基础内容

linuxc编程基础内容

linuxc编程基础内容Linux是一种开源的操作系统,广泛应用于各种计算机设备和嵌入式系统中。

在Linux系统中,C语言是一种常用的编程语言,被广泛用于开发各种应用程序和系统组件。

本文将介绍Linux C编程的基础内容,包括编译和运行C程序、变量和数据类型、控制流、函数和文件操作等方面的知识。

一、编译和运行C程序在Linux系统中,使用gcc编译器来编译C程序。

首先,我们需要创建一个以.c为扩展名的源代码文件,比如hello.c。

在文件中编写C程序代码,然后使用以下命令进行编译:gcc hello.c -o hello其中,hello.c是源代码文件的名字,-o hello表示将编译生成的可执行文件命名为hello。

编译成功后,可以使用以下命令来运行程序:./hello二、变量和数据类型在C语言中,我们可以定义各种类型的变量来存储不同种类的数据。

常见的数据类型包括整型、浮点型、字符型和指针类型等。

在Linux C编程中,我们可以使用int来表示整型变量,float或double来表示浮点型变量,char来表示字符型变量,以及void*来表示指针类型变量。

三、控制流控制流是指程序在执行过程中根据条件选择不同的执行路径。

在C 语言中,我们可以使用if语句、switch语句、for循环、while循环和do-while循环等结构来实现控制流。

这些结构可以帮助我们实现条件判断、循环执行和跳转等功能,从而实现复杂的程序逻辑。

四、函数函数是C语言中的重要概念,它可以将一段代码封装成一个可以重复使用的模块。

在Linux C编程中,我们可以通过函数来实现程序的模块化和结构化。

函数可以接受参数并返回一个值,也可以不接受参数或不返回值。

使用函数可以提高程序的可读性和可维护性。

五、文件操作在Linux系统中,文件操作是一种常见的需求。

C语言提供了一组用于文件操作的函数,包括打开文件、读取文件、写入文件和关闭文件等操作。

C语言在Linux环境编程

C语言在Linux环境编程

C语言在Linux环境编程C语言是一种广泛使用的编程语言,而Linux作为一种开源的操作系统,提供了强大的开发环境和工具,使得C语言在Linux环境下编程成为了广大开发者的首选。

本文将探讨C语言在Linux环境下的编程特点及常用技巧。

一、Linux环境下的C语言开发工具在Linux环境下,开发者可以使用多种工具进行C语言的编程和调试。

其中,最常用的是gcc编译器和gdb调试器。

gcc是GNU Compiler Collection的缩写,它是一套基于GNU计划的开源编译器套件,支持多种编程语言,包括C语言。

gdb是GNU Debugger的缩写,它是一个功能强大的调试器,可以帮助开发者定位和修复程序的错误。

二、C语言在Linux环境下的编写风格在Linux环境下编写C语言程序时,程序员通常采用一些特定的编写风格和规范,以便提高代码的可读性和可维护性。

以下是一些常用的编写风格:1. 缩进:使用适当的缩进来使代码结构清晰,建议使用4个空格或一个制表符进行缩进。

2. 命名规范:变量、函数和常量的命名应具有一定的描述性,遵循驼峰命名法或下划线命名法。

3. 注释:在代码中添加必要的注释,解释代码的作用和设计意图,以便其他人能够理解和维护代码。

4. 模块化:将程序分解为多个小模块,每个模块负责一个特定的功能,提高代码的可复用性和可测试性。

三、Linux环境下的C语言编译与运行在Linux环境下,通过gcc编译器可以将C语言源代码编译成可执行文件。

编译C语言程序的基本命令是:gcc source.c -o output其中,source.c是源代码文件的名称,-o是选项,用于指定生成的可执行文件的名称,output是可执行文件的名称。

编译成功后,可以使用以下命令来运行程序:./output四、Linux环境下的C语言调试在Linux环境下,使用gdb调试器可以帮助开发者定位和修复程序的错误。

以下是一些常用的调试技巧:1. 加入调试信息:在编译时,可以使用-g选项来生成包含调试信息的可执行文件,以便在调试过程中更容易定位错误。

请简述linux环境下c程序的编译执行过程。

请简述linux环境下c程序的编译执行过程。

请简述linux环境下c程序的编译执行过程。

在Linux环境下,C程序的编译执行过程包括预处理、编译、汇编、链接和执行五个步骤。

下面将会对每个步骤进行详细的说明。

1.预处理:预处理是在编译前对源代码进行处理的阶段。

预处理器将执行一系列操作,包括宏展开、头文件包含、条件编译等。

预处理的结果是生成一个经过处理的输出文件,通常是一个带有".i"扩展名的文件,也称为预处理文件。

在Linux环境下可以使用以下命令对源文件进行预处理:```bashgcc -E source.c -o output.i```2.编译:编译是将预处理文件转换为汇编代码的阶段。

编译器将预处理文件作为输入,对其进行词法分析、语法分析和语义分析,并将其转换成汇编代码。

编译的结果是一个带有".s"扩展名的文件,也称为汇编代码文件。

```bashgcc -S output.i -o output.s```3.汇编:汇编是将汇编代码转换为机器码的阶段。

汇编器将汇编代码作为输入,将其转换为二进制机器指令,生成一个带有".o"扩展名的目标文件(也称为目标代码文件)。

在Linux环境下可以使用以下命令将汇编代码转换为目标代码:```bashgcc -c output.s -o output.o```4.链接:链接是将目标文件与库文件进行合并,并解析所有的外部符号引用的过程。

链接器将目标文件作为输入,将其与系统库文件和用户库文件合并,生成一个可执行文件。

链接的结果是一个可执行文件,没有扩展名。

```bashgcc output.o -o executable```5.执行:执行是将可执行文件加载到内存中,并运行程序的过程。

操作系统将可执行文件加载到内存中的进程空间,然后执行程序的入口点,开始运行程序。

程序会根据代码的逻辑执行相应的操作,最终会得到预期的结果。

除了以上的基本编译执行过程外,还可以使用Makefile来管理项目的编译过程。

Linux下的C语言编程-基础知识

Linux下的C语言编程-基础知识

Linux下的C语言编程--基础知识篇前言:这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容:源程序编译Makefile的编写程序库的链接程序的调试头文件和系统求助--------------------------------------------------------------------------------1.源程序的编译在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们以一个实例来说明如何使用gcc编译器.假设我们有下面一个非常简单的源程序(hello.c):int main(int argc,char **argv){printf("Hello Linux\n");}要编译这个程序,我们只要在命令行下执行:gcc -o hello hello.cgcc 编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.命令行中 gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件.gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了. -o选项我们已经知道了,表示我们要求输出的可执行文件名. -c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件. -g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息.知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了,如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明.2.Makefile的编写假设我们有下面这样的一个程序,源代码如下:/* main.c */#include "mytool1.h"#include "mytool2.h"int main(int argc,char **argv){mytool1_print("hello");mytool2_print("hello");}/* mytool1.h */#ifndef _MYTOOL_1_H#define _MYTOOL_1_Hvoid mytool1_print(char *print_str);#endif/* mytool1.c */#include "mytool1.h"void mytool1_print(char *print_str){printf("This is mytool1 print %s\n",print_str);}/* mytool2.h */#ifndef _MYTOOL_2_H#define _MYTOOL_2_Hvoid mytool2_print(char *print_str);#endif/* mytool2.c */#include "mytool2.h"void mytool2_print(char *print_str){printf("This is mytool2 print %s\n",print_str);}当然由于这个程序是很短的我们可以这样来编译gcc -c main.cgcc -c mytool1.cgcc -c mytool2.cgcc -o main main.o mytool1.o mytool2.o这样的话我们也可以产生main程序,而且也不时很麻烦.但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了.是的对于这个程序来说,是可以起到作用的.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译?为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个Makefile的文件是:# 这是上面那个程序的Makefile文件main:main.o mytool1.o mytool2.ogcc -o main main.o mytool1.o mytool2.omain.o:main.c mytool1.h mytool2.hgcc -c main.cmytool1.o:mytool1.c mytool1.hgcc -c mytool1.cmytool2.o:mytool2.c mytool2.hgcc -c mytool2.c有了这个Makefile文件,不过我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件她连理都不想去理的.下面我们学习Makefile是如何编写的.在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是:target: componentsTAB rule第一行表示的是依赖关系.第二行是规则.比如说我们上面的那个Makefile文件的第二行main:main.o mytool1.o mytool2.o表示我们的目标(target)main的依赖对象(components)是main.o mytool1.o mytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令.就象我们的上面那个Makefile第三行所说的一样要执行 gcc -o main main.o mytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键Makefile有三个非常有用的变量.分别是$@,$^,$<代表的意义分别是:$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件.如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:# 这是简化后的Makefilemain:main.o mytool1.o mytool2.ogcc -o $@ $^main.o:main.c mytool1.h mytool2.hgcc -c $<mytool1.o:mytool1.c mytool1.hgcc -c $<mytool2.o:mytool2.c mytool2.hgcc -c $<经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里我们学习一个Makefile的缺省规则.c.o:gcc -c $<这个规则表示所有的 .o文件都是依赖与相应的.c文件的.例如mytool.o依赖于mytool.c这样Makefile还可以变为:# 这是再一次简化后的Makefilemain:main.o mytool1.o mytool2.ogcc -o $@ $^.c.o:gcc -c $<好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile规则可以查看相应的文档.3.程序库的链接试着编译下面这个程序/* temp.c */#includeint main(int argc,char **argv){double value;printf("Value:%f\n",value);}这个程序相当简单,但是当我们用 gcc -o temp temp.c 编译时会出现下面所示的错误./tmp/cc33Kydu.o: In function `main':/tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'collect2: ld returned 1 exit status出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我们必须和数学库连接,为此我们要加入 -lm 选项. gcc -o temp temp.c -lm这样才能够正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc 编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的 -L选项指定路径.比如说我们有一个库在 /home/hoyt/mylib下,这样我们编译的时候还要加上 -L/home/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib /usr/lib /usr/local/lib 在这三个路径下面的库,我们可以不指定路径.还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢?很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程(thread)函数的库文件(libpthread.a). 当然,如果找不到,只有一个笨方法.比如我要找sin这个函数所在的库. 就只好用 nm -o/lib/*.so|grep sin>~/sin 命令,然后看~/sin文件,到那里面去找了. 在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0 W sin 这样我就知道了sin在 libm-2.1.2.so库里面,我用 -lm选项就可以了(去掉前面的lib和后面的版本标志,就剩下m了所以是 -lm). 如果你知道怎么找,请赶快告诉我,我回非常感激的.谢谢!4.程序的调试我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选择xxgdb.记得要在编译的时候加入 -g选项.关于gdb的使用可以看gdb的帮助文件.由于我没有用过这个软件,所以我也不能够说出如何使用. 不过我不喜欢用gdb.跟踪一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用.5.头文件和系统求助有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得着函数在那个头文件进行了说明.这个时候我们可以求助系统.比如说我们想知道fread这个函数的确切形式,我们只要执行 man fread 系统就会输出着函数的详细解释的.和这个函数所在的头文件说明了. 如果我们要write这个函数的说明,当我们执行man write时,输出的结果却不是我们所需要的. 因为我们要的是write这个函数的说明,可是出来的却是write这个命令的说明.为了得到write的函数说明我们要用 man 2 write. 2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3表示函数是C的库函数.记住不管什么时候,man都是我们的最好助手.。

Linux下C语言编程:编写函数,删除字符串中的空格

Linux下C语言编程:编写函数,删除字符串中的空格

Linux下C语言编程:编写函数,删除字符串中的空格.
//一维字符串数组" h a sdf g "
//指针指着第一个元素,判断是否为零,为零则++,不为零则赋值给另一个指针
//再把两个指针都++操作
//最后需要把新的数组后加'\0'
#include<stdio.h>
void del_space (char *s1);
//定义,定义后面要加分号";"表示语句结束
int main(int argc,char*argv[])
{
char s[] = " h a sdf g " ;
puts(s);
//字符串输出
del_space(s);
//调用删除空格函数
puts(s);
//打印删除空格后的字符串
return 0;
}
void del_space (char *s1)
//实现部分,后面不加封号";"表示语句没有结束
{
char *s2;
//去空格后保存的位置
s2 = s1;
//赋初值
while (*s1) {
if (*s1 != ' ')
{
*s2 = *s1;
s1 ++;
s2 ++;
}
else
{
s1 ++;
}
}
*s2 = '\0'; //新字符串最后加'\0' }
结果:
>> h a sdf g
>>hasdfg。

Linux系统的C编程

Linux系统的C编程

//文件f3.c的内容 #include <stdio.h> main() { fprintf(stderr,‖Begine:\n‖); f1(15); f2(‖Hello World!‖); fprintf(stderr,‖:End\n‖); exit(0); }
编译与链接
可以采用各模块文件分别编译然后再统一链接 的办法进行编译。 • cc –c f1.c f2.c //生成f1.o和f2.o • cc –o f f3.c f1.o f2.o //生成f • cc –o fp f3.c f1.c f2.c //生成fp • cc –c f1.c f2.c f3.c //生成f1.o,f2.o和f3.o • cc –o myp f1.o f2.o f3.o //生成myp
– – – – dlerror dlopen dlsym dlclose。
1. dlopen
• 功能:
– 用于打开指定共享库,并返回文件描述符。
• 原型及用法:
– void *dlopen(const char *filename, int flag);
• 返回值:
– 成功时返回文件描述符,否则返回NULL。
11.5 共享库
• Linux系统的另一种库文件为共享库,用于 生成动态链接的可执行程序。
– 共享库文件名的格式为: libNAME.so.N – NAME为库名,N为版本号。
• 可用命令ldd和ldconfig命令管理共享库。
11.5.1 构造共享库
• 共享库构造非常简单,只需要在构造库的时 候使用-shared参数就可以了。 • 例如:用f1.c和f2.c构造共享库,方法是:
• 运行
– ./a.out – ./hello 或
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1)Linux程序设计入门--基础知识Linux下C语言编程基础知识前言:这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容:源程序编译Makefile的编写程序库的链接程序的调试头文件和系统求助--------------------------------------------------------------------------------1.源程序的编译在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们以一个实例来说明如何使用gcc编译器.假设我们有下面一个非常简单的源程序(hello.c):int main(int argc,char **argv){printf("Hello Linux ");}要编译这个程序,我们只要在命令行下执行:gcc -o hello hello.cgcc 编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.命令行中gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件.gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了. -o选项我们已经知道了,表示我们要求输出的可执行文件名. -c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件. -g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息.知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了,如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明.2.Makefile的编写假设我们有下面这样的一个程序,源代码如下:/* main.c */#include "mytool1.h"#include "mytool2.h"int main(int argc,char **argv){mytool1_print("hello");mytool2_print("hello");}/* mytool1.h */#ifndef _MYTOOL_1_H#define _MYTOOL_1_Hvoid mytool1_print(char *print_str);#endif/* mytool1.c */#include "mytool1.h"void mytool1_print(char *print_str){printf("This is mytool1 print %s ",print_str);}/* mytool2.h */#ifndef _MYTOOL_2_H#define _MYTOOL_2_Hvoid mytool2_print(char *print_str);#endif/* mytool2.c */#include "mytool2.h"void mytool2_print(char *print_str){printf("This is mytool2 print %s ",print_str);}当然由于这个程序是很短的我们可以这样来编译gcc -c main.cgcc -c mytool1.cgcc -c mytool2.cgcc -o main main.o mytool1.o mytool2.o这样的话我们也可以产生main程序,而且也不时很麻烦.但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了.是的对于这个程序来说,是可以起到作用的.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译?为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个Makefile的文件是:# 这是上面那个程序的Makefile文件main:main.o mytool1.o mytool2.ogcc -o main main.o mytool1.o mytool2.omain.o:main.c mytool1.h mytool2.hgcc -c main.cmytool1.o:mytool1.c mytool1.hgcc -c mytool1.cmytool2.o:mytool2.c mytool2.hgcc -c mytool2.c有了这个Makefile文件,不过我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件她连理都不想去理的.下面我们学习Makefile是如何编写的.在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是:target: componentsTAB rule第一行表示的是依赖关系.第二行是规则.比如说我们上面的那个Makefile文件的第二行main:main.o mytool1.o mytool2.o表示我们的目标(target)main的依赖对象(components)是main.o mytool1.o mytool2.o当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令.就象我们的上面那个Makefile第三行所说的一样要执行gcc -o main main.o mytool1.o mytool2.o注意规则一行中的TAB表示那里是一个TAB键Makefile有三个非常有用的变量.分别是$@,$^,$<代表的意义分别是:$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件.如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:# 这是简化后的Makefilemain:main.o mytool1.o mytool2.ogcc -o $@ $^main.o:main.c mytool1.h mytool2.hgcc -c $<mytool1.o:mytool1.c mytool1.hgcc -c $<mytool2.o:mytool2.c mytool2.hgcc -c $<经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里我们学习一个Makefile的缺省规则..c.o:gcc -c $<这个规则表示所有的.o文件都是依赖与相应的.c文件的.例如mytool.o依赖于mytool.c 这样Makefile还可以变为:# 这是再一次简化后的Makefilemain:main.o mytool1.o mytool2.ogcc -o $@ $^..c.o:gcc -c $<好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile规则可以查看相应的文档.3.程序库的链接试着编译下面这个程序/* temp.c */#include <math.h>;int main(int argc,char **argv){double value;printf("Value:%f ",value);}这个程序相当简单,但是当我们用gcc -o temp temp.c 编译时会出现下面所示的错误./tmp/cc33Kydu.o: In function `main':/tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'collect2: ld returned 1 exit status出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我们必须和数学库连接,为此我们要加入-lm 选项. gcc -o temp temp.c -lm这样才能够正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的-L选项指定路径.比如说我们有一个库在/home/hoyt/mylib下,这样我们编译的时候还要加上-L/h ome/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib /usr/lib /usr/local/lib 在这三个路径下面的库,我们可以不指定路径.还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程(thread)函数的库文件(libp thread.a). 当然,如果找不到,只有一个笨方法.比如我要找sin这个函数所在的库. 就只好用nm -o /lib/*.so|grep sin>;~/sin 命令,然后看~/sin文件,到那里面去找了. 在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0 W sin 这样我就知道了sin在libm-2.1.2.so库里面,我用-lm选项就可以了(去掉前面的lib和后面的版本标志,就剩下m了所以是-lm). 如果你知道怎么找,请赶快告诉我,我回非常感激的.谢谢!4.程序的调试我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选择xxgdb.记得要在编译的时候加入-g选项.关于gdb的使用可以看gdb的帮助文件.由于我没有用过这个软件,所以我也不能够说出如何使用. 不过我不喜欢用gdb.跟踪一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用.5.头文件和系统求助有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得着函数在那个头文件进行了说明.这个时候我们可以求助系统.比如说我们想知道fread这个函数的确切形式,我们只要执行man fread 系统就会输出着函数的详细解释的.和这个函数所在的头文件<stdio.h>;说明了. 如果我们要write这个函数的说明,当我们执行man write时,输出的结果却不是我们所需要的. 因为我们要的是w rite这个函数的说明,可是出来的却是write这个命令的说明.为了得到write的函数说明我们要用man 2 write. 2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3表示函数是C的库函数.记住不管什么时候,man都是我们的最好助手.------------------------------------------------------------------------好了,这一章就讲这么多了,有了这些知识我们就可以进入激动人心的Linux下的C程序探险活动.2)Linux程序设计入门--进程介绍Linux下进程的创建前言:这篇文章是用来介绍在Linux下和进程相关的各个概念.我们将会学到:进程的概念进程的身份进程的创建守护进程的创建--------------------------------------------------------------------------------1。

相关文档
最新文档