首先用vi编辑器创建一个c程序文件(以.c结尾)
如:
vi hello.c
#include
int main()
{
printf(“Hello World!\n”);
return 0;
}
创建好hello.c文件后,保存退出,接下来就是进行编译程序。
gcc hello.c
此时,用ls -al命令查看当前目录下的文件,可以发现,多出了一个a.out文件,注意该文件权限的最后一列是x,即表示该文件是可执行文件,让我们执行文件看看会有什么结果!
./a.out
命令窗口出现了“Hello World”。但现在有个问题,如果我们不想生成的可执行使用默认名称,那要怎么办呢?这里可以使用-o这一选项决定生成文件的名称,我们就给执行文件命名为run吧。
gcc hello.c -o run
这次,在用ls -al查看当前目录,发现出现了run可执行文件,再次运行该文件:
./run
结果和./a.out是一样的。
(2)
有了上面的基础后,我们继续接下来的教程。这次我们修改上面的.c文件:
vi hello.c
使之内容如下,实现简单的相加功能:
#include
int main()
{
double x = 1.3, y = 2.4;
printf(“sum:%d”, x + y);
return 0;
}
仔细的观察,会发现,输出格式上问题,我们要输出的是一个double型的数据,但输出格式是按照整形输出,虽说这不影响程序的运行,但却可能是一个隐藏的错误。让我们按照上一节的方法编译文件:
gcc hello.c -o run
结果,编译器没有提示任何的警告。这对于一些对代码规范要求比较严格的人来说,是一个严重的
漏洞。那么,要怎样才可以看到提示警告呢。我们可以使用-Wall选项来显示警告。
gcc -Wall hello.c -o run
这次编译器就显示警告消息了。接下来,我们的大部分例子都是使用-Wall这一选项,我会在之后的内容中对-Wall的使用进一步详解。
(3)
在
编程中,我们经常会调用其他文件的函数,因为不可能把所有的函数都在一个文件上实现,这样会让代码很难管理。那么如果在linux上,存在多文件关系又要怎样编译呢?下面我举一个简单例子:
首先是,add.c文件
vi add.c
int add(int x, int y){
return x + y;
}
接着就是包含该函数声明的头文件math.h
vi math.h
int add(int x, int y);
然后是调用add这一函数的main.c文件:
vi main.c
#include
#include”math.h”
int main()
{
int sum = 0;
sum = add(4, 3);
printf(“sum:%d\n”, sum);
return 0;
}
这里,我简单地讲讲gcc编译器的工作流程,首先是对源程序进行预处理,然后是生成目标文件,最后是将目标文件链接在一起形成可执行文件。大概的流程是这样,想要知道更具体的细节,大家可以自己到网上去找相关的资料,这里我就不展开讲了。接下来就是生成目标文件:
gcc -Wall -c main.c
使用ls -al查看当前目录,可以见到新增了两个目标文件,分别是add.o 和main.o。这里,我们使用-c表示只生成目标文件,不生成可执行文件。所以编译其并没有报错。接下来就是将两个目标文件链接在一起形成最终的可执行文件。
gcc -Wall main.o add.o -o result
查看当前目录,这是就出现了result这一可执行文件,让我们运行看看是否程序是否正确。
./result
没错,输出的结果就是7。这是大家就会疑问了,难道就没有简单一点的方法吗,其实上面的步骤可以用一句命令来代替:
gcc -Wall main.c add.c -o result
我之所以将上面一种比较麻烦的方法是想让大家了解一下gcc的编译流程,因为到了后面我们还会继续用到这种方法。
这时,一些细心的朋友可能会发现math.h文件没有在命令行列,那是因为#include”math.h”中编译器已经将math.h中的内容包含到main.c中了。
(4)上面的程序很简单,这次我们创建一个更复杂点的程序,让我们把math.h头文件下的函数补充完善
, 分别追加minus.c divide.c以及multiply.c其实就是把我们常用的加减乘除功能全部实现。
vi minus.c
int minus(int x, int y){
return x – y;
}
vi divide.c
int divide(int x, int y){
return x / y;
}
vi multiply.c
int multiply(int x, int y){
return x * y;
}
然后是将各个函数的声明添加之math.h文件中,
vi math.h
int add(int x, int y);
int minus(int x, int y);
int divide(int x, int y);
int multiply(int x, int y);
同时,我们修改一下main.c,让其调用divide函数:
vi main.c
#include
#include”math.h”
int main()
{
int sum = 0;
sum = add(4, 3);
printf(“sum:%d\n”, sum);
int result = 0;
result = divide(4,2);
printf(“result:%d”, result);
return 0;
}
这次由于main.c中,我们只调用了add和divide函数,则编译命令如下:
gcc -Wall main.c add.c divide.c -o result
查看当前目录,result已经生成,运行一下程序:
./result
结果正常。我们继续把剩下的两个minus.c和multiply.c生成目标文件,供以后使用。这时用ls -al查看当前目录,我们就有add.o、minus.o、divide.o、multiply.o和main.o四个目标文件。
让我们回过头来看看前面的代码,细心的朋友会发现,我们的divide函数有个漏洞,如果分母y为0,那么程序就会出错,我们再次编辑divide.c文件:
vi divide.c
添加一个判断语句即可。
#include //由于我们调用了printf
系统自带的函数
int divide(int x, int y){
if(y == 0){
printf(“y can't be zero\n”);
return 0;
}
return x / y;
}
然后,我们修改main.c,测试一下分母为0时是否可以正常运行。
vi main.c