头文件剖析

基本概念

​ 在一个C文件中除了main、跳转标号不需要声明之外所有的标识符在使用之前都需要进行声明,一般我们把函数的声明放在头文件中。

变量声明 != 变量定义 ===> 区别:是否分配内存

变量定义:生成相关的汇编指令

变量声明:告诉编译器,有可能存在于别的文件,编译时候先不要报错,在连接的时候到相应的文件中查找,没有 再报错

定义只有一次,声明可以有多次

  1 #include <stdio.h>                                                                    
  2 
  3 #ifndef __LCD_H__
  4 #define __LCD_H__
  5 
  6 #define PI 3.14
  7 void lcd_init(void);
  8 #endif

注:

隐式声明

==如果没有进行声明只产生一个警告,不会报错,并且增加一个隐式声明==

给出的隐式声明可能会与原函数的数据格式有区别,造成错误

变量声明与定义

extern:使用文件外的参数

//1.c
  1 int i = 0;                                                                            
  2 int a[10] = {1, 2, 3, 4, 5,6 ,7 ,8 ,9 , 0};
  3 struct student
  4 {
  5     int age;
  6     int num;
  7 };
  8 struct student stu = {20, 1001};
  9 int k;
 10 
//main.c
  1 #include <stdio.h>                                       
  2 
  3 extern int i;
  4 extern int a[10];
  5 struct student{
  6     int age;
  7     int num;
  8 };
  9 extern struct student stu;
 10 extern int k;
 11 
 12 int main(void)
 13 {
 14     printf("%s: i = %d\n", __func__, i);
 15     for(int j = 0; j<10 ; j++)
 16         printf("s[%d]: %d\n", j, a[j]);
 17     printf("stu.age = %d, num = %d\n", stu.age, stu.num);
 18     printf("%s: k = %d\n", __func__, k);
 19     return 0;
 20 
 21 }


result: 

main: i = 0
s[0]: 1
s[1]: 2
s[2]: 3
s[3]: 4
s[4]: 5
s[5]: 6
s[6]: 7
s[7]: 8
s[8]: 9
s[9]: 0
stu.age = 20, num = 1001
main: k = 0

试探性定义:该变量可能在别的文件中有声明,如果没有按照规则声明并初始化默认值:NULL, 0,

​ undefined value等 。如果别的文件中有定义,那把他当成声明

产生原因

​ 由于内存原因,早期的C语言一次只能编译一个文件,每个源文件单独编译,只编译一次

前向引用

没有声明就可以使用

不完全类型

int array_print(int i[], int len);

struct LIST_NODE
{
    struct LIST_NONE *next;//在定义结束前已经使用
    int data;
};
goto error;

:在进行对不完全类型的引用时候只能使用类型属性,其他的如变量值,结构成员,大小等不能使用

​ 如果只是用指针就可以不用考虑这些

struct person;\\前向声明
struct student{
    struct person *p;
    int score;
    int no;
};

模块的封装

add.h

int add(int a, int b);

add.c

#include "add.h"
int add(int a, int b)
{
    return 	a+b;
}

main.c

#include <stdio.h>
#include "add.h"

int main(void)
{
    int sum;
    sum = add(1, 2);
    return 0;
}

头文件路径

可以使用gcc -I来指定目录

搜索顺序<>:

搜索顺序””:

Linux常用的路径

头文件中的内联函数