簡體   English   中英

這個C代碼有什么問題?

[英]What's the wrong with this C Code?

我寫了一個關於結構的示例程序。 我寫了3個源文件和1個頭文件。 這是該計划的完整來源:

main.c中:

#include <stdio.h>
#include <stdlib.h>
#include "fish.h"

/*
struct fish
{
    const char *name;
    const char *species;
    int teeth;
    int age;
};
*/

/*
void catalog(struct fish f)
{
    printf("%s is a %s with %i teeth. He is %i.",
           f.name, f.species, f.teeth, f.age);
}


void label(struct fish f)
{
    printf("Name: %s\n", f.name);
    printf("Species: %s\n", f.species);
    printf("Teeth: %i\n", f.teeth);
    printf("Age: %i\n", f.age);
}
*/

int main()
{
    struct fish snappy = {"Snappy", "Piranha", 69, 4};
    catalog(snappy);
    label(snappy);

    return 0;
}

label.c:

#include "fish.h"

void label(struct fish f)
{
    printf("Name: %s\n", f.name);
    printf("Species: %s\n", f.species);
    printf("Teeth: %i\n", f.teeth);
    printf("Age: %i\n", f.age);
}

catalog.c:

#include "fish.h"

void catalog(struct fish f)
{
    printf("%s is a %s with %i teeth. He is %i.",
           f.name, f.species, f.teeth, f.age);
}

我還寫了一個makefile:

fish.o: main.c label.c catalog.c fish.h
    gcc -c main.c label.c catalog.c
fish: fish.o
    gcc fish.o -o fish

我在cmd中編譯程序:

make fish

它說:

gcc -c main.c label.c catalog.c
label.c: In function 'label':
label.c:5:5: warning: incompatible implicit declaration of built-in function 'printf'    [enabled by default]
catalog.c: In function 'catalog':
catalog.c:5:5: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
cc   fish.o   -o fish
cc.exe: error: fish.o: No such file or directory
cc.exe: fatal error: no input files
compilation terminated.
make: *** [fish] Error 1

如果我刪除main.c中的注釋並僅編譯它,它可以工作,但是當我如上所述闖入小塊時它不起作用。

怎么了?

您需要將所有.c文件一起編譯,以便可以使用main.clabel.ccatalog.c中定義的函數。

您可以使用gcc一步完成此操作:

gcc main.c label.c catalog.c -o fish

這將編譯每個單獨的源文件並生成目標文件 ,這些文件將鏈接在一起以生成可執行文件。 您正在看到的錯誤發生在鏈接階段,當gcc嘗試查找cataloglabel功能時。

gcc main.c -o fish只編譯main.c main.c不知道label.c 它只知道它必須調用一個名為“label”的函數,這個函數在別處定義。 然后,鏈接器查看所有生成的目標文件,並將它們“鏈接”到一個可執行文件中:

gcc main.c -c
gcc label.c -c
gcc catalog.c -c
ld main.o label.o catalog.o -o fish

這是明確的版本

gcc main.c label.c catalog.c -o fish

此鏈接規則:

fish: fish.o
    gcc fish.o -o fish

適用於從單個目標文件fish.o構建程序fish (可能是從fish.c編譯的)。

您需要一個不同的規則:

OBJECTS = main.o label.o catalog.o

fish: ${OBJECTS}
    ${CC} -o $@ ${OBJECTS}

如果需要,您可以根據需要將${CFLAGS}${LDFLAGS}${LDLIBS} (或${LDLIBES} )添加到鏈接行,但對於簡單程序,我顯示的就足夠了。

您不必告訴make如何將main.c轉換為main.o ; 它已經知道了。 它將使用如下規則:

%.o: %.c
    ${CC} -c ${CFLAGS} $<

從匹配的.c文件創建.o文件。 (這是GNU Make表示法; POSIX make和其他經典版本的make使用替代但松散等效的符號.co:代替%.o: %.c%.o: %.c 。)

如果您不介意每次編譯所有源,您可以使用類似的規則:

SOURCES = main.c label.c catalog.c

fish: ${OBJECTS}
    ${CC} ${CFLAGS} -o $@ ${SOURCES}

這一次, ${CFLAGS}幾乎是強制性的(盡管你的裸機樣本程序中沒有它就會離開)。


請注意, make很挑剔; 命令行如${CC}行必須以TAB開頭; 空白不會這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM