歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C的鏈接詳解

C的鏈接詳解

日期:2017/3/1 9:53:34   编辑:Linux編程

多目標文件的鏈接

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