一点点C语言的知识

编译器

cc编译器是来自于Unixc语言编译器,是 c compiler 的缩写。

gcc来自Linux世界,是GNU compiler collection 的缩写,注意这是一个编译器集合,不仅仅是cc++

在现在Linux下调用cc时,其实际上并不指向unixcc编译器,而是指向了gcc,也就是说ccgcc的一个链接(快捷方式)。

可以从上面命令中看到cc指向了/etc/alternatives/cc,而/etc/alternatives/cc指向了gcc

另外我们也可以从他们两个的版本中看到一些信息。我们发会先,这两个命令输出的结果一模一样。

第一个C语言程序

进行编译

在默认情况下gcc会将编译的程序默认为a.out。我们可以使用-o参数进行重命名。

执行程序输出hello world

多个源文件、头文件与函数的定义

我们不可能将所有的代码都写到一个文件里面。那么我们就会进行将拆分。下面代码将会讲述整个过程。

我们写一个简单的比大小的程序。

我们先创建2个文件。

直接编译,编译器会提示我们main函数中找不到max函数,编译错误

我们使用下面方法编译,就会发现成功了。

但是这样编译有一个问题,在低版本的编译器中会报错,编译器会还是会告诉我们main函数中找不到max函数。现在成功只是高版本编译器帮我们做了一些事情而已。

正确的方式应该在main函数中,对max函数进行申明。如下:

编译

编译成功。

但是呢,现在还有个问题。

刚刚我们使用的是#include "max.c",其实呢这样只是把max.c的内容复制到main.c而已。如果有很多个文件(成百上千、成千上万)的话,编译速度会是特别慢的。

那么我们可以将这种.c文件事先编译好之后,他会生成一个.o文件,然后我们编译的时候带上.o文件就可以了。

如下:

编译

那么现在代码的编译速度上去了,随之而来有又一个问题,就是对于一些第三方公共类库或者框架之类,我们只有编译后的文件,没有源码。我们就不清楚函数需要传入哪些参数,返回什么类型的返回值。这个时候我们就引入了.h的头文件。

编译成功

Makefile

当我们编译大型项目(拥有成千上万文件)的时候,每当我们需要修改一点Bug的时候,就需要成重新输入编译命令,将非常耗时费力。这个时候呢,我们引入了Makefile。我们可以将编译命令写入Makefile文件就可以了。

以上面的例子来说,首先我们删除 .o.out文件。

编写Makefile

然后我们进行make编译即可。

注意: 编辑Makefile文件的时候,缩进必须为tab不能用空格替代。否则将会报错。

执行程序

main函数的参数及返回值

实际上main函数带有2个参数,如下:

argc 为传入的参数个数。
argv 为传入参数具体之的数组。

编译后运行:

标准输入流、输出流以及错误流

标准输入流

当程序执行到scanf("%d", &a);时候,程序会挂起,直至我们输入一个数字。

我们的键盘输入就是标准输入流。

标准输出流以及错误流都是输出到显示器屏幕上。

其实 printf函数底层调用的是fprintf函数,如下:

stdoutstderr就是标准输出流以及错误流。正常执行程序信息会输出到显示器屏幕上。我们可以修改程序,让其输出到文件中。

我们会发现屏幕上什么都没输出,而文件夹中多了2个文件err.logoutput.log

另外,linux操作系统也为我们提供了方便的改变输入流输出流错误流的方法。

这段代码正常情况下会冲键盘上得到数据,并且输出和输入都会在屏幕上。但是我们可以下面方法改变他。

一样会生成err.logoutput.log