C的链接详解


多目标文件的链接

stack.c

#include <stdio.h>

#define STACKSIZE 1000

typedef struct stack {
 int data[STACKSIZE];
 int top;
} stack;

stack s;
int count = 0;

void pushStack(int d)
{
 s.data[s.top ++] = d;
 count ++;
}

int popStack()
{
 return s.data[-- s.top];
}

int isEmpty()
{
 return s.top == 0;
}

link.c

#include <stdio.h>

int a, b;

int main()
{
 a = b = 1;

 pushStack(a);
 pushStack(b);
 pushStack(a);

 while (! isEmpty()) {
  printf("%d\n", popStack());
 }
 
 return 0;
}

编译方式:

gcc -Wall stack.c link.c -o main

提示出错信息如下:

C的链接详解

但是代码是可以执行的

定义和声明

static和extern修饰函数

上述编译出现错误的原因是:编译器在处理函数调用代码时没有找到函数原型,只好根据函数调用代码做隐式声明,把这三个函数声明为:

int pushStack(int);
int popStack(void);
int isEmpty(void);

编译器往往不知道去哪里找函数定义,像上面的例子,我让编译器编译main.c,而这几个函数定义却在stack.c里,编译器无法知道,因此可以用extern声明。修改link.c如下:

#include <stdio.h>

int a, b;

extern void pushStack(int d);
extern int popStack(void);
extern int isEmpty(void);

int main()
{
 a = b = 1;

 pushStack(a);
 pushStack(b);
 pushStack(a);

 while (! isEmpty()) {
  printf("%d\n", popStack());
 }
 
 return 0;
}

这样编译器就不会报警了。这里extern关键字表示这个标识符具有External Linkage.pushStack这个标识符具有External Linkage指的是:如果link.c和stack.c链接在一起,如果pushStack在link.c和stack.c中都声明(在stack.c中的声明同时也是定义),那么这些声明指的是同一个函数,链接后是同一个GLOBAL符号,代表同一个地址。函数声明中的extern可以省略不写,不屑extern的函数声明也表示这个函数具有External Linkage。

  • 1
  • 2
  • 下一页

相关内容