[英]global char[] variable, how to declare it in other files?
我在一個文件中定義了全局變量char buf[1024]
,那么在其他文件中聲明它的正確方法是什么? extern char buf[1024]
, extern char buf[]
或extern char *buf
嗎? 我發現extern char buf[]
有效,而extern char *buf
無效,但想了解更多解釋。
extern char buf []和extern char buf [1024]都可以。
在某些情況下,該數組是通過指針實現的,例如在兩個函數之間傳遞參數。
當您將變量設為extern時,是向編譯器指示該變量的符號(地址)將在另一個.o文件中找到-(在鏈接階段完成)。
因此,當您將變量設為extern時,只需提及名稱即可,因為它可以提供有關地址和大小的信息
這是數組和指針可互換的老問題。 數組和指針是不可互換的:它們恰好是大多數時間,因為在大多數情況下,您在表達式中使用數組名稱時,它會分解為指針。
在專家C編程-深度C秘密中徹底解釋了在一個文件中定義為char數組並在另一個文件中聲明為char指針的特定情況。 請參閱第4章。
數組的聲明為您提供了一個數組,而指針的聲明為您提供了一個指針。 區別在於,數組是地址(第一個元素的地址),並且不是可修改的L值,即無法分配給它。 另一方面,指針是保存地址的變量。
通常,上下文足以說明您是指變量的地址還是賦值中變量的內容。 該聲明
i = j;
是說要的內容存儲j
中的地址i
。 在編譯器術語中, i
表示l值, j
表示r值。 編譯器必須產生寫入的存儲器地址的內容代碼j
中的存儲器地址i
。
考慮以下聲明:
char a[1024];
char *a;
寫a[i] = j;
會發生什么? ?
對於前一種情況,編譯器將只選擇a
的內容的地址,該地址在數組中是第一個元素的地址; 縮放i
,並將其求和到基址。 然后它將把存儲j
的地址的內容寫入該地址。
對於后一種情況,它是完全不同的:編譯器必須檢查存儲a
的存儲位置,加載該存儲位置的內容,使用THAT作為地址,並將j
的內容寫入該地址。
如果在file1.c
聲明這樣的字符數組:
char a[] = "Hello";
然后在file2
定義
extern char *a;
然后,執行a[0] = 'x';
在file2.c
中將崩潰:由於您告訴編譯器a
是指針,它將檢查存儲a
值的地址。 實際上,該地址保存着'H'
的字符代碼,但是編譯器錯誤地將其解釋為地址,並最終生成了將'x'
寫入地址'H'
代碼,如果幸運的話,會因違反細分而使您的程序崩潰。
因此,在這種情況下,聲明和定義必須匹配:如果將其聲明為數組,則將其定義為數組;如果聲明為數組,則將其定義為數組。 如果您將其聲明為指針,則將其定義為指針。 您必須在其他文件中將buf
聲明為字符數組。 這些形式中的任何一種都是合法的和等效的:
extern char buf[1024];
要么
extern char buf[];
可分配的全局char變量。 使所有人可見:
// shared_header.h
extern char current_mode[];
定義,實例化和更新:
// main.c
#include "shared_header.h"
char current_mode[160];
int main(int argc, char * argv [])
{
strcpy(current_mode, "MODE_CONFIGURE");
int a = randomNumber(102);
strcpy(current_mode, "MODE_EXECUTE");
int b = do_foo(a);
// other stuff
strcpy(current_mode, "MODE_TEARDOWN");
// close up shop
}
閱讀或更新:
// foo.c
#include "shared_header.h"
int do_foo(int a)
{
printf("Current mode is %s", current_mode);
if (a > 100) {
strcpy(current_mode, "MODE_EXECUTE_SPECIAL_CASE");
printf("Switching to mode %s", current_mode);
}
// do useful things
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.