标题:Linux下C编程(一)
只看楼主
guixiaolan
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:356
专家分:0
注 册:2006-4-20
 问题点数:0 回复次数:1 
Linux下C编程(一)
[bo]Linux下C编程(一)
[/bo]

[bo]1.源程序的编译[/bo]
[gxlinux@localhost hello]$ ls
hello.c  Makefile

[gxlinux@localhost hello]$ cat hello.c #查看源程序
int main(int argc,char **argv)
{
printf("Hello Linux\n");

[gxlinux@localhost hello]$ cat Makefile
hello:hello.c
        gcc -o hello hello.c

[gxlinux@localhost hello]$ gcc -g hello.c #-g参数进行调试,生成a.out文件
hello.c: In function ‘main’:
hello.c:3: 警告:隐式声明与内建函数 ‘printf’ 不兼容
hello.c:4:2: 警告:文件未以空白行结束

[gxlinux@localhost hello]$ ls
a.out  hello.c  Makefile

[gxlinux@localhost hello]$ ./a.out #执行a.out文件得到结果
Hello Linux

[gxlinux@localhost hello]$ gcc -c hello.c #-c参数生成代码文件hello.o
hello.c:4:2: 警告:文件未以空白行结束
hello.c: In function ‘main’:
hello.c:3: 警告:隐式声明与内建函数 ‘printf’ 不兼容

[gxlinux@localhost hello]$ ls
a.out  hello.c  hello.o  Makefile

[gxlinux@localhost hello]$ gcc -o hello hello.o #-o参数生成hello可执行文件,第一个hello就是要生成的可执行文件名

[gxlinux@localhost hello]$ ls
a.out  hello  hello.c  hello.o  Makefile
[gxlinux@localhost hello]$ ./hello
Hello Linux
注明:其实可以直接gcc -o hello hello.c生成可执行文件hello,上面是为了熟悉它的编译过程才分开写的


[bo]2.Makefile文件的编写[/bo]
相信大家已经看到了上面的文件夹中还有一个Makefile文件,程序内容如上述。
[gxlinux@localhost hello]$ ls
hello.c  Makefile
[gxlinux@localhost hello]$ make hello
gcc -o hello hello.c
hello.c: In function ‘main’:
hello.c:3: 警告:隐式声明与内建函数 ‘printf’ 不兼容
hello.c:4:2: 警告:文件未以空白行结束
[gxlinux@localhost hello]$ ./hello
Hello Linux

Makefile文件的格式(千万记住TAB键可别少了):
target(目标): components(依赖文件)
TAB rule

也许在你看来,这个Makefile文件根本没有必要,但是请你看以下一些文件。
[gxlinux@localhost makefile]$ ls
main.c  Makefile  Makefile.txt  mytool1.c  mytool1.h  mytool2.c  mytool2.h

[gxlinux@localhost makefile]$ cat main.c
#include "mytool1.h"
#include "mytool2.h"
int main(int argc,char **argv)
{
mytool1_print("hello");
mytool2_print("hello");
}

[gxlinux@localhost makefile]$ cat mytool1.h
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif

[gxlinux@localhost makefile]$ cat mytool1.c
#include "mytool1.h"
void mytool1_print(char *print_str)
{
printf("This is mytool1 print %s\n",print_str);
}

[gxlinux@localhost makefile]$ cat mytool2.h
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif

[gxlinux@localhost makefile]$ cat mytool2.c
#include "mytool2.h"
void mytool2_print(char *print_str)
{
printf("This is mytool2 print %s\n",print_str);

[gxlinux@localhost makefile]$ gcc -c main.c
在包含自 main.c:1 的文件中:
mytool1.h:4:7: 警告:文件未以空白行结束
在包含自 main.c:2 的文件中:
mytool2.h:4:7: 警告:文件未以空白行结束
main.c:7:2: 警告:文件未以空白行结束
[gxlinux@localhost makefile]$ gcc -c mytool1.c
在包含自 mytool1.c:1 的文件中:
mytool1.h:4:7: 警告:文件未以空白行结束
mytool1.c:5:2: 警告:文件未以空白行结束
mytool1.c: In function ‘mytool1_print’:
mytool1.c:4: 警告:隐式声明与内建函数 ‘printf’ 不兼容
[gxlinux@localhost makefile]$ gcc -c mytool2.c
在包含自 mytool2.c:1 的文件中:
mytool2.h:4:7: 警告:文件未以空白行结束
mytool2.c:5:2: 警告:文件未以空白行结束
mytool2.c: In function ‘mytool2_print’:
mytool2.c:4: 警告:隐式声明与内建函数 ‘printf’ 不兼容
[gxlinux@localhost makefile]$ gcc -o main main.o mytool1.o mytool2.o
[gxlinux@localhost makefile]$ ls
main    main.o    Makefile.txt  mytool1.h  mytool2.c  mytool2.o
main.c  Makefile  mytool1.c     mytool1.o  mytool2.h
[gxlinux@localhost makefile]$ ./main
This is mytool1 print hello
This is mytool2 print hello

我们可以看到像这样有很多库文件链接在内的时候,如果一个命令一个命令来敲的话,这将是一个很繁琐的工作,而且如果一旦有一个文件的内容有所改变,那么你还得来一个命令一个命令的来敲进去编译,毫无疑问这将是一个很坏的选择,所以我们只好借助于Makefile文件了。
[gxlinux@localhost makefile]$ ls
main.c  Makefile  Makefile.txt  mytool1.c  mytool1.h  mytool2.c  mytool2.h
[gxlinux@localhost makefile]$ cat Makefile
main:main.o mytool1.o mytool2.o
        gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
        gcc -c main.c
mytool1.o:mytool1.c mytool1.h
        gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
        gcc -c mytool2.c
[gxlinux@localhost makefile]$ make main
gcc -c main.c
在包含自 main.c:1 的文件中:
mytool1.h:4:7: 警告:文件未以空白行结束
在包含自 main.c:2 的文件中:
mytool2.h:4:7: 警告:文件未以空白行结束
main.c:7:2: 警告:文件未以空白行结束
gcc -c mytool1.c
在包含自 mytool1.c:1 的文件中:
mytool1.h:4:7: 警告:文件未以空白行结束
mytool1.c:5:2: 警告:文件未以空白行结束
mytool1.c: In function ‘mytool1_print’:
mytool1.c:4: 警告:隐式声明与内建函数 ‘printf’ 不兼容
gcc -c mytool2.c
在包含自 mytool2.c:1 的文件中:
mytool2.h:4:7: 警告:文件未以空白行结束
mytool2.c:5:2: 警告:文件未以空白行结束
mytool2.c: In function ‘mytool2_print’:
mytool2.c:4: 警告:隐式声明与内建函数 ‘printf’ 不兼容
gcc -o main main.o mytool1.o mytool2.o
[gxlinux@localhost makefile]$ ls
main    main.o    Makefile.txt  mytool1.h  mytool2.c  mytool2.o
main.c  Makefile  mytool1.c     mytool1.o  mytool2.h
[gxlinux@localhost makefile]$ ./main
This is mytool1 print hello
This is mytool2 print hello

其实这个Makefile文件还不是很简单,你可以改写为如下两种形式,自己摸索一下。
/*
main:main.o mytool1.o mytool2.o
        gcc -o $@ $^
main.o:main.c mytool1.h mytool2.h
        gcc -c $<
mytool1.o:mytool1.c mytool1.h
        gcc -c $<
mytool2.o:mytool2.c mytool2.h
        gcc -c $<
*/

/*
main:main.o mytool1.o mytool2.o
        gcc -o $@ $^
..c.o:
        gcc -c $<
*/
表示的意义如下:
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件

[bo]3.程序库的链接[/bo]
[gxlinux@localhost math]$ ls
temp.c
[gxlinux@localhost math]$ gcc -o temp temp.c
temp.c: In function ‘main’:
temp.c:5: 警告:隐式声明与内建函数 ‘printf’ 不兼容
/tmp/ccyNBwu3.o: In function `main':
temp.c:(.text+0x17): undefined reference to `cos'
collect2: ld 返回 1
[gxlinux@localhost math]$ ls
temp.c
[gxlinux@localhost math]$ gcc -o temp temp.c -lm
temp.c: In function ‘main’:
temp.c:5: 警告:隐式声明与内建函数 ‘printf’ 不兼容
[gxlinux@localhost math]$ ls
temp  temp.c
[gxlinux@localhost math]$ ./temp
Value:0.540302
我们知道在这个文件中链接有一个库函数,虽然GCC默认也能链接到一部分库函数,但是有一些库函数则必须通过链接来导入编译,如上例。

也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的-L选项指定路径.

比如说我们有一个库在/home/hoyt/mylib下,这样我们编译的时候还要加上-L /home/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib和/usr/lib和/usr/local/lib 在这三个路径下面的库,我们可以不指定路径.

还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢?很抱歉,对于这个问题我也不知道答案。如果你知道怎么找,请赶快告诉我,我会非常感激的.谢谢!

[bo]4.程序的调试[/bo]
我们知道很多大型程序都是需要调试的,在Linux下也有很多调试软件,你可以选择你自己喜欢的软件,但是最基本的一个软件是gdb,你可以查看帮助文件进行自由学习。

[bo]5.学会使用帮助文档[/bo]
我们已经知道了,怎么查看命令的帮助了,man ls或ls --help,同样使用man命令也可以查看C函数的帮助内容了。
比如你要查看write函数的帮助内容(注意,只是函数的帮助文件,而不是write命令的帮助文件,这时候我们该怎么做呢?)尝试以下命令练习。
[gxlinux@localhost math]$ man write
[gxlinux@localhost math]$ man 2 write
2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3,表示函数是C的库函数.记住不管什么时候,man都是我们的最好助手。
搜索更多相关主题的帖子: Linux 
2008-04-18 23:11
boot2046
Rank: 2
等 级:新手上路
威 望:3
帖 子:168
专家分:0
注 册:2007-7-23
得分:0 
写程序最好把警告全部去掉

Linux是简单的,你不需要成为天才也能理解这种简单,Windows是复杂的,就算你是天才也不能理解这种复杂
2008-04-28 13:24



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-209847-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.297587 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved