来历:网海拾贝
1.弁言
Linux应用细碎在干事器范畴的应用和普遍曾经有较长的汗青,这源于它的开源特点以及其逾越Windows的平静性和不乱性。而近年来,Linux应用细碎在嵌入式细碎范畴的延长也可谓是蒸蒸日上,良多版本的嵌入式Linux细碎被开辟出来,如ucLinux、RTLinux、ARM-Linux等等。在嵌入式应用细碎方面,Linux的职位地方是不容疑心的,它开源、它包括TCP/IP协议栈、它易集成GUI。
鉴于Linux应用细碎在干事器和嵌入式细碎范畴愈来愈普遍的应用,社会上越来越必要基于Linux应用细碎停止编程的开辟职员。
浏览良多论坛,常常碰到多么的发问:“今朝是不是很盛行unix/linux下的c编程?以是想进修一下!然则不晓得该从何学起,若何动手!有什么好的发起吗?列位高手!哪些书籍对照适宜初学者?在深切浅出的进程中应该看哪些差别条理的书?比如好的网站、论坛请大师见示!不慎谢谢!”
鉴于读者的需求,在本文中,笔者将对Linux平台下C编程的几个方面停止实例讲授,并力争回答读者们眷注的成绩,以与读者冤家们停止交换,合营进步。在本文的连载进程中,有任何成绩或发起,您可以给笔者发送email:21cnbao@21cn.com,您也可以进入笔者的博客参预评论斗嘴:http://blog.donews.com/21cnbao。
笔者发起在PC内存充沛大的外形下,不要直接安置Linux应用细碎,最好把它安置在运转VMWare虚拟机软件的Windows平台上,如下图:
在Linux平台下,可用恣意一个文本编辑东西编辑源代码,但笔者发起运用emacs软件,它具有语法高亮、版本节制等附带服从,如下图:
2.GCC编译器
GCC是Linux平台下最重要的开辟东西,它是GNU的C和C 编译器,其根柢用法为:
gcc [options] [filenames]
options为编译选项,GCC总共供应的编译选项逾越100个,但只要大都几个会被频繁运用,我们仅对几个常用选项停止引见。
假定我们编译一输入“Hello World”的程序:
/* Filename:helloworld.c */
main()
{
printf("Hello Worldn");
}
最大抵的编译法子是不指定任何编译选项:
gcc helloworld.c
它会为目标程序生成默许的文件名a.out,我们可用-o编译选项来为将发生的可执行文件指定一个文件名来替代a.out。比方,将上述名为helloworld.c的C程序编译为名叫helloworld的可执行文件,必要输入如下下令:
gcc –o helloworld helloworld.c
-c选项通知GCC仅把源代码编译为目标代码而跳过汇编和衔接的步骤;
-S 编译选项通知GCC 在为 C代码发生了汇编言语文件后截止编译。GCC 发生的汇编言语文件的缺省扩展名是.s,上述程序运转如下下令:
gcc –S helloworld.c
将生成helloworld.c的汇编代码,运用的是AT&T汇编。用emacs翻开汇编代码如下图:
-E选项指示编译器仅对输入文件停止预处置责罚。当这个选项被运用时,预处置责罚器的输入被送到规范输入(默认为屏幕)而不是储存在文件里。
-O选项通知GCC对源代码停止根柢优化从而使得程序执行地更快;而-O2选项通知GCC发生尽可以小和尽可以快的代码。运用-O2选项编译的速率比运用-O时慢,但发生的代码执行速率会更快。
-g选项通知GCC发生能被GNU调试器运用的调试信息以便调试你的程序,可喜的是,在GCC里,我们能联用-g和-O (发生优化代码)。
-pg选项通知GCC在你的程序里参预额外的代码,执行时,发生gprof用的解析信息以透露表现你的程序的耗时外形。
3.GDB调试器
GCC用于编译程序,而Linux的另一个GNU东西gdb则用于调试程序。gdb是一个用来调试C和C 程序的强力调试器,我们能经过它停止一系列调试任务,包孕设置断点、观观查变量、单步等。
其最常用的下令如下:
file:装入想要调试的可执行文件。
kill:截至正在调试的程序。
list:列表透露表现源代码。
next:执行一行源代码但不进入函数外部。
step:执行一行源代码并且进入函数外部。
run:执行以后被调试的程序
quit:截至gdb
watch:监视一个变量的值
break:在代码里设置断点,程序执行到这里时挂起
make:不插足gdb而重新发生可执行文件
shell:不分隔断距离绝涣散gdb而执行shell
上面我们来演示怎样用GDB来调试一个求0 1 2 3 … 99的程序:
/* Filename:sum.c */
main()
{
int i, sum;
sum = 0;
for (i = 0; i < 100; i )
{
sum = i;
}
printf("the sum of 1 2 ... is %d", sum);
}
执行如下下令编译sum.c(加-g选项发生debug信息):
gcc –g –o sum sum.c
在下令行上键入gdb sum并按回车键就可以入部下手调试sum了,再运转run下令执行sum,屏幕上将看到如下内容:
list下令:
list下令用于列出源代码,对上述程序两次运转list,将出现如下画面(源代码被标行号):
依据列出的源程序,如果我们将断点设置在第5行,只需在gdb 下令行提示符下键入如下下令设置断点:(gdb) break 5,执行外形如下图:
这个时分我们再run,程序会截止在第5行,如下图:
设置断点的另一种语法是 break <function>,它在进入指定函数(function)时停住。
相反的,clear用于清除齐备的已定义的断点,clear <function>清除设置在函数上的断点, clear <linenum>则清除设置在指定行上的断点。
watch下令:
watch下令用于观观查变量或表达式的值,我们观观查sum变量只必要运转watch sum:
watch <expr>为表达式(变量)expr设置一个观观测点,一量表达式值有变化时,程序会截止执行。
要观观查以后设置的watch,可以运用info watchpoints下令。
next、step下令:
next、step用于单步执行,在执行的进程中,被watch变量的变化外形将及时出现(划分透露表现Old value和New value),如下图:
next、step下令的区别在于step碰到函数挪用,会跳转到到该函数定义的入部下手行去执行,而next则不进入到函数外部,它把函数挪用语句看成一条往常语句执行。
4.Make
make是齐备想在Linux细碎上编程的用户必须把握的东西,关于任何稍具局限的程序,我们都市运用到make,确实可以说不运用make的程序不具有任何实用价值。
在此,我们有必要表明编译和衔接的区别。编译器运用源码文件来发生某种法子的目标文件(object files),在编译进程中,外部的标识表记标帜参考并没有被表明或交换(即外部全局变量和函数并没有被找到)。因此,在编译阶段所报的错误一样往常都是语法错误。而衔接器则用于衔接目标文件和程序包,生成一个可执行程序。在衔接阶段,一个目标文件中对其余文件中的标识表记标帜的参考被表明,如果有标识表记标帜不克不及找到,会呈报衔接错误。
编译和衔接的一样往常步骤是:第一阶段把源文件一个一个的编译成目标文件,第二阶段把齐备的目标文件加上必要的程序包衔接成一个可执行文件。多么的进程很痛苦,我们必要运用大量的gcc下令。
而make则使我们从大量源文件的编译和衔接任务中束缚出来,综合为一步完成。GNU Make的重要任务是读进一个文本文件,称为makefile。这个文件记录了哪些文件(目的文件,目的文件不一定是最后的可执行程序,它可以是任何一种文件)由哪些文件(请托文件)发生,用什么下令来发生。Make请托此makefile中的信息搜检磁盘上的文件,如果目的文件的创建或修正工夫比它的一个请托文件旧的话,make就执行响应的下令,以便更新目的文件。
假定我们写下如下的三个文件,add.h用于声明add函数,add.c供应两个整数相加的函数体,而main.c中挪用add函数:
/* filename:add.h */
extern int add(int i, int j);
/* filename:add.c */
int add(int i, int j)
{
return i j;
}
/* filename:main.c */
#include "add.h"
main()
{
int a, b;
a = 2;
b = 3;
printf("the sum of a b is %d", add(a b));
}
如作甚上述三个文件发生makefile呢?如下:
test : main.o add.o
gcc main.o add.o -o test
main.o : main.c add.h
gcc -c main.c -o main.o
add.o : add.c add.h
gcc -c add.c -o add.o
上述makefile应用add.c和add.h文件执行gcc -c add.c -o add.o下令发生add.o目标代码,应用main.c和add.h文件执行gcc -c main.c -o main.o下令发生main.o目标代码,最后应用main.o和add.o文件(两个模块的目标代码)执行gcc main.o add.o -o test下令发生可执行文件test。
我们可在makefile中参预变量,其余。情形变量在make进程中也被表明成make的变量。这些变量是大小写敏感的,一样往常运用大写字母。Make变量可以做良多事项,比方:
i) 存储一个文件名列表;
ii) 存储可执行文件名;
iii) 存储编译器选项。
要定义一个变量,只必要在一行的入部下手写下这个变量的名字,后面跟一个=号,再跟变量的值。援用变量的法子是写一个 $标识表记标帜,后面跟(变量名)。我们把后面的 makefile 应用变量重写一遍(并假定运用-Wall -O –g编译选项):
OBJS = main.o add.o
CC = gcc
CFLAGS = -Wall -O -g
test : $(OBJS)
$(CC) $(OBJS) -o test
main.o : main.c add.h
$(CC) $(CFLAGS) -c main.c -o main.o
add.o : add.c add.h
$(CC) $(CFLAGS) -c add.c -o add.o
makefile 中还可定义清除(clean)目标,可用来清除编译进程中发生的地方文件,比方在上述makefile文件中添加下列代码:
clean:
rm -f *.o
运转make clean时,将执行rm -f *.o下令,删除齐备编译进程中发生的地方文件。
不论怎样说,本人脱手编写makefile仍然是很庞大和啰嗦的,并且很方便出错。因此,GNU也为我们供应了Automake和Autoconf来匡助快速自动发生makefile,读者可以参阅相关材料。
5.小结
本章重要论述了Linux程序的编写、编译、调试法子及make,实际上便是指导读者进修怎样在Linux下编程,为后续章节做好预备。
版权声明:
原创作品,答应转载,转载时请务必以超链接法子标明文章 原始来由 、作者信息和本声明。不然将清查法则责任。