歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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

提示出錯信息如下:

但是代碼是可以執行的

定義和聲明

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。

Copyright © Linux教程網 All Rights Reserved