第五章-#include与标准函数库
C语言的标准函数库
以输入输出函数(scanf/printf)举例:
- C语言本身不提供输入输出语句,输入输出操作是由C标准函数库中的函数来实现的.
- C提供的标准函数以库的形式在C的编译系统中提供,他们不是C语言文本中的组成部分.
- 各种C编译系统(VC6.0/clang/v2.0等等)提供的系统函数库是各软件公司编制的,它包括了C语言建议的全部标准函数,还根据用户的需求补充了一些常用的函数,已经对他们进行了编译,成为目标文件(.obj文件/.o文件).他们在程序连接阶段与由源程序经编译而得的目标文件(.obj文件/.o文件)相连接,生成一个可执行的目标程序(.ext文件/a.out文件).
- 不同的编译系统所提供的函数库中,函数的数量/名字/功能是不完全相同的.不过有些通用的函数(比如:printf/scanf等),各种编译系统都提供,成为各种系统的标准函数
- 在使用系统库函数时,要在程序的开头用预处理指令#include把有关头文件放在本程序中.
- 比如
#include<stdio.h>
,该头文件中包含了与标准I/O库有关的变量定义和宏定义以及对函数的声明 - 那么为什么要包含头文件呢?
- 我们知道,当一个函数只要有声明,即使没有定义,我们也可以调用这个函数,而且编译不会报错,但是连接的时候才会报错,那么就说明,编译仅仅是为了检查有没有语法错误,然后转化成相应的二进制,当连接时才会真正的使用函数的定义
- 由于stdio.h中包含了printf/scanf的声明,因此,只要我们导入该文件,当使用了这两个函数的时候,编译就不会报错了
- 这就是.h文件的作用:仅仅为了做一些声明,确保在编译时不会报错,或者在调用某些函数/变量时,证明他们存在,以至于在编译时不会报错.真正用到的是连接,连接时候就会把所有的.c(或者.m)源文件合并在一起,形成一个完整的可执行文件
#include的基本使用
#include+头文件
:就是把头文件中的所有内容copy到相应的位置而已,stdio.h里面有函数printf的声明,因此编译时不会报错,当连接时,会把系统的函数库中函数定义连接进来,就会有printf的定义了- 这里的头文件其实确切来说是文件的路径
- 为何有的用”“,有的用<>呢?我们自己写的文件用”“,系统的文件用<>
- 代码举例:
#include<stdio.h>
int main(){
printf("哈哈哈哈哈\n");
#include"abc.text"
//相对路径
#include"def/def.text"
//绝对路径
#include"/Users/xyj/Desktop/C语言笔记记录/代码/include的使用/def/def.text"
}
/*
//打印结果如下:
哈哈哈哈哈
我是abc文件中的内容
我是def中的内容
我是def中的内容
*/
文件目录如下图:
多文件开发
创建两个.c文件zhangsan.c lisi.c .c文件代码如下
/*
zhangsan.c文件
张三:主要编写main函数
*/
#include<stdio.h>
#include"lisi.h"
int main (){
int score1 = 100;
int score2 = 70;
int c = average(score1,score2);
printf("平均分是%d\n",c);
return 0;
}
李四.c文件:
/*
lisi.c文件
李四:编写一些运算函数
*/
int average(int a ,int b){
return (a + b)/2;
}
int sum(int a, int b)
{
return a + b;
}
int minus(int a, int b)
{
return a - b;
}
int multiply(int a, int b)
{
return a * b;
}
李四.h文件
/*
lisi.h文件
编写函数的声明
*/
int average(int a, int b);
int sum(int a, int b);
int minus(int a, int b);
int multiply(int a, int b);
解析:
- 当没有lisi没有.h文件,只有.c文件时,同一个文件夹下有zhangsan.c和lisi.c文件
- 要想运行成功步骤如下:
- 编译zhangsan.c文件,虽然有警告(average函数没有声明),但是仍然可以编译成功生成zhangsan.o文件
- 编译lisi.c文件,生成lisi.o文件
- 同时连接zhangsan.o与lisi.o文件生成可执行文件a.out
- 或者:直接省略上面3步:cc zhangsan.c lisi.c 编译/连接同时进行生成a.out文件,但是也会产生同样警告
- 运行a.out
-
终端代码如下:
xyjdeMacBook-Pro:多文件开发 xyj$ cc -c zhangshan.c zhangshan.c:11:13: warning: implicit declaration of function 'average' is invalid in C99 [-Wimplicit-function-declaration] int c = average(score1,score2); ^ 1 warning generated. xyjdeMacBook-Pro:多文件开发 xyj$ cc -c lisi.c xyjdeMacBook-Pro:多文件开发 xyj$ cc zhangshan.o lisi.o xyjdeMacBook-Pro:多文件开发 xyj$ ./a.out 平均分是85
- 要想解决上面的警告有以下两种解决办法:
- 办法一:
- 找到lisi.c文件中所有的函数定义,然后分别写对应的函数声明到zhangsan.c文件中
- 缺点:李四每写一个函数,你就要copy函数名,到张三.c文件中写函数声明,这样太麻烦;
- 方法二:
- 李四新建一个lisi.h文件,把lisi.c中的所有函数都写对应的声明到lisi.h文件中去,每当定义一个函数时,就相应在.h文件中写声明
- 在zhangsan.c文件中只需要写上#include”lisi.h”文件就可以了”,在执行
cc zhangsan.c lisi.c
生成a.out就不会有警告了
- 办法一:
总结:
- 函数的定义放.c文件,函数的声明放.h文件
- 如果要使用某个.c文件中定义的函数,只需要#include这个.c文件对应的.h文件
- .h文件的作用:(仅仅)被别人拷贝。编译链接的时候都不需要管.h文件
- cc xx.o xxx.o 将多个目标文件链接在一起
cc xx.c xxx.c 将多个源文件编译、链接 - 编译:检查语法是否有错误
- 连接:把项目中所有相关联的.o目标文件/c语言的库函数合并在一起,生成可执行文件