[英]Calling #define from another file
這是我的代碼。 我有file1.c和file2.c。 我想從file2.c調用MESSAGE,但似乎無法執行。 我是C語言的新手,所以我真的不知道該怎么辦。 我已經進行了研究,但似乎找不到具體答案。 謝謝。
#define MESSAGE "this is message!"
helloworld(){
printf("%s",MESSAGE);
getch();
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file2.c"
int main(void)
{
helloworld();
}
您有一些誤解:首先是“調用”宏的概念。 即使宏看起來像一個函數,它也不是函數,並且宏實際上不是由編譯器處理的,這是不可能的。 相反,宏是由預處理器處理的另一種語言的一部分,該預處理器獲取源文件並對其進行修改以生成編譯器可以看到的翻譯單元 。 (有關“編譯”不同階段的更多信息,請參見此參考資料 。)
預處理器基本上通過在輸入源文件中進行搜索替換來實現此目的:當看到宏“調用”時,它只是將其替換為宏的“主體”。 當它看到#include
指令時,它將對文件進行預處理,然后將內容替換為該指令。
因此,在您的代碼中,當預處理器看到宏MESSAGE
它實際上將被"this is message!"
取代"this is message!"
。 實際的編譯器根本看不到MESSAGE
,而只看到字符串文字。
另一個誤解是如何使用#include
指令。 您不應使用它來包含源文件。 相反,您可以分別編譯源文件(創建目標文件),然后將生成的目標文件與形成最終可執行文件所需的任何庫鏈接在一起。
要解決宏(和其他聲明)可用於所有源文件的問題,請使用頭文件 。 這些就像源文件一樣,但是僅包含聲明和宏。 然后,您將標頭文件包含在兩個源文件中,並且兩個源文件都將了解標頭文件中可用的聲明和宏。
因此,在您的情況下,您應該具有三個文件:主源文件,包含函數的源文件以及包含宏和函數聲明的頭文件(也稱為原型)。 就像是
頭文件,例如header.h
:
// First an include guard (see e.g. https://en.wikipedia.org/wiki/Include_guard)
#ifndef HEADER_H
#define HEADER_H
// Define the macro, if it needs to be used by all source files
// including this header file
#define MESSAGE "this is message!"
// Declare a function prototype so it can be used from other
// source files
void helloworld();
#endif
主源文件,例如main.c
:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
int main(void)
{
// Use the macro
printf("From main, MESSAGE = %s\n", MESSAGE);
// Call the function from the other file
helloworld();
}
另一個文件,例如hello.c
:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
void helloworld(void)
{
printf("Hello world!\n");
printf("From helloworld, MESSAGE = %s\n", MESSAGE);
}
現在,如果您使用gcc
或clang
類的命令行編譯器,則只需執行以下操作即可構建所有內容:
$ gcc -Wall main.c hello.c -o myhello
該命令將獲取兩個源文件main.c
和hello.c
並對其運行預處理器和編譯器以生成(臨時)目標文件。 然后將這些目標文件與標准C庫鏈接在一起以形成程序myhello
(這是-o
選項的工作,為輸出文件命名)。
然后可以運行myhello
:
$ ./myhello From main, MESSAGE = this is message! Hello world! From helloworld, MESSAGE = this is message!
在您的file1.c
, MESSAGE
是一個預處理程序宏,這意味着文本MESSAGE
將被替換為字符串"this is message!"
。 在文件外部不可見。 這是因為在C語言中, translation units
是編譯器的最終輸入,並且轉換單元已經將所有預處理器宏替換為相應參數的標記。
如果要使用公共變量,則應在.h
頭文件中將該變量聲明為extern
,然后在需要使用的位置#include
該文件。
請參閱在程序中編譯多個C文件
您必須將#define
放在.h
文件中,並將其包含在要使用它的.c
文件中。
這是代碼嘗試此:
在File1.C中
#define FILE1_C
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
在File2.C中
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
}
在File1.h中
#ifdef FILE1_C
#define MESSAGE "this is message!"
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN helloword()
您可以按照以下步驟編寫文件並按照我在以下步驟中提到的方式編譯代碼。
文件1.h
#ifndef _FILE1_H
#define _FILE1_H
#define MESSAGE "this is message!"
extern void helloworld();
#endif
文件1.c
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
文件2.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
return 0;
}
為了進行編譯,
gcc -Wall file1.c file2.c -o myprog
./myprog
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.