C語言中跨檔案的全域性變數
宣告:突然看到這篇文章,發現了c語言中使用全域性變數的錯誤,特轉之。
func.c
123456 | int buf = 0; void func() { buf = 2; /* Do something else */ } |
main.c
1234567891011 | #include <stdio.h> int buf; void func(); int main() { buf = 1; func(); printf("%d\n", buf); return 0; } |
編譯兩個檔案,輸出的結果是怎樣的呢?一眼看上去,可能會輸出1,因為兩個全域性變數buf在不同檔案中,又沒有extern宣告,顯然是兩個嘛。然而實際上它的執行結果卻是2,這說明了這兩個檔案中引用到的其實是一個變數!
這是為什麼呢?原因是在編譯時,C語言編譯器將全域性符號標記為strong和weak兩類:
- 函式和初始化的全域性符號被標記為strong
- 未初始化的全域性符號被標記為weak
連線時,聯結器對多重定義的全域性符號的解析原則如下:
- 同一個符號不允許有多個strong定義;
- 假如一個符號有一個strong定義和多個weak定義,那麼採用該符號的strong定義;
- 假如一個符號有多個weak定義,那麼選取任意一個weak定義
由於兩個變數一個初始化了,一個沒有初始化,所以一個是strong,一個是weak,所以聯結器在符號解析時會把他們當成一個。
如果我們把main.c中的buf也初始化了:
1 |
#include <stdio.h> int buf = 0; void func(); int main() { buf = 1; func(); printf("%d\n", buf); return 0; } |
再次編譯就會發現
duplicate symbol _buf in:
/var/folders/44/_cc501qx1jd1p5bfrjbk6b100000gn/T//ccZ87C6g.o
/var/folders/44/_cc501qx1jd1p5bfrjbk6b100000gn/T//ccZlES8n.o
ld: 1 duplicate symbol for architecture x86_64
collect2: ld returned 1 exit status
這是因為兩個全域性變數都是strong的。
相關推薦
C語言中跨檔案的全域性變數
宣告:突然看到這篇文章,發現了c語言中使用全域性變數的錯誤,特轉之。 func.c 123456 int buf = 0; void func() { buf = 2; /* Do something else */ } ma
簡單的C語言巨集定義結合全域性變數的方法實現微控制器串列埠實現透傳模式
何謂透傳? 根據百度百科給出的定義如下: 透傳,即透明傳輸(pass-through),指的是在通訊中不管傳輸的業務內容如何,只負責將傳輸的內容由源地址傳輸到目的地址,而不對業務資料內容做任何改變。 在現實微控制器產品開發過程中,如果存在多個
Python跨檔案全域性變數的方法
Python 中 global 關鍵字可以定義一個變數為全域性變數,但是這個僅限於在一個模組(py檔案)中呼叫全域性變數,在另外一個py檔案 再次使用 global x 也是無法訪問到的,因
c語言中對檔案的建立和讀寫
在c語言中,fopen用於建立檔案,fwrite用於將資料寫入檔案,而fread用於讀取檔案中的資料,fclose用於關閉檔案(在有些編輯器中如VS2017要使用fopen_s、fwrite_s和fread_s、fclose_s或者在程式碼開始前使用#pragram warn
C語言中的檔案流
所謂檔案(file)一般指儲存在外部介質上資料的集合,比如我們經常使用的mp3、mp4、txt、bmp、jpg、exe、rmvb等等。這些檔案各有各的用途,我們通常將它們存放在磁碟或者可移動盤等介質中。那麼,為什麼這裡面又有這麼多種格式的檔案呢?原因很簡單,它們各有各的用
Python跨檔案全域性變數
儘管某些書籍上總是說避免使用全域性變數,但是在實際的需求不斷變化中,往往定義一個全域性變數是最可靠的方法,但是又必須要避免變數名覆蓋。Python 中 global 關鍵字可以定義一個變數為全域性變數,但是這個僅限於在一個模組(py檔案)中呼叫全域性變數:我們知道Python
淺談C語言中文字檔案與二進位制檔案
C語言中,按檔案中的資料組織形式來分,資料檔案可分為ASCII碼檔案(即文字檔案)和二進位制檔案。 文字檔案在磁碟中存放時每個字元對應一個位元組,用於存放對應的ASCII碼。 二進位制檔案把資料按其在記憶體中的儲存形式存放在磁碟上,一個位元組並不一定對應一個字元。 對於A
C語言中的常量、變數及其屬性,型別、儲存空間
部落格源地址 http://www.codertown.cn/blog/?p=134 常量和變數其實就是C語言裡的值,其他程式語言同樣存在,這個跟數學裡的是一樣的。 1、常量 固定的值,不可改變的值是常量,幾種型別: 在表示式中直接用數值表示;巨集定義當然也是
標準C語言中的檔案操作函式的記憶體版
1. 初衷 專案需要,itron作業系統中實裝freetype+harfbuzz的字型引擎,但itron系統中沒有支援檔案系統! 所以只能將依賴庫中的libdatrie和libthai中的檔案操作換成記憶體版。 2. 程式碼 廢話不說,直接上程式碼。 #include
python實現跨檔案全域性變數
Python 中 global 關鍵字可以定義一個變數為全域性變數,但是這個僅限於在一個模組(py檔案)中呼叫全域性變數。 多個檔案之間使用同一個全域性變數demo_value: 檔案1:globalvar.py class GlobalVar:
51微控制器C語言程式設計雜談基礎----全域性變數和區域性變數
< 部落格宗旨:文章短,時間短,不考驗耐力 > 我記著我在開始編寫51微控制器程式的時候,老是在思考一個問題:怎麼把一個函式中的值傳到另一個函式中去呢???讓我痛不堪言。雖然簡單,但是在那個時候我還是不知道的。 全域性變數:就是在整個工程都可以使用
【好程式設計師筆記分享】—— C語言中的檔案包含
我們在C語言中引用檔案,有時候會出現重複引用的情況,為了避免發生此種情況,我們想到了一個解決方案。程式碼如下: #include <stdio.h> #include "one.h" #include "two.h" int main(){
Python實現跨檔案全域性變數的方法
原文地址: https://www.cnblogs.com/rnckty/p/7722603.html Python 中 global 關鍵字可以定義一個變數為全域性變數,但是這個僅限於在一個模組(py檔案)中呼叫全域性變數,在另外一個py檔案 再次使用 global
關於C語言中返回區域性指標變數
前言 寫這篇文章,是因為同學在leetcode上遇到了這樣一個錯誤: - 題目:Two Sum - 程式碼如下: int* twoSum(int* nums, int numsSize, int target) { int i,j; in
C語言中對檔案操作的小結
在C語言中,檔案的操作是通過FILE結構體進行了,具體實現時,先利用fopen返回一個指向FILE結構體的指標: FILE *fopen( const char *filename, const char *mode ); filename:檔名,mode:開啟的模式,規定
C/C++語言中變數作用域:區域性變數,全域性變數,檔案級變數
C/C++語言中的變數分為全域性變數和區域性變數。這種劃分方式的依據是變數的可見範圍或者叫做作用域。 1 區域性變數 區域性變數指的是定義在{}中的變數,其作用域也在這個範圍內。雖然常見的區域性變數都是定義在函式體內的,也完全可以人為的增加一對大括號來限定變
C語言如何在兩個檔案中訪問同一個全域性變數
方法一: 不使用標頭檔案。 1.c 中 int var; 2.c 中 extern int var; 方法二: 使用標頭檔案. 1.c 中 int var; 不必新增#include "1.h" 1.h 中 extern int var; 2.c 中新增 #include
解決C/C++語言中全域性變數重複定義的問題
前言 今天,在整理自己的程式碼的時候,考慮到我寫的程式碼從一至終都是在一個cpp檔案裡面。於是,想把自己的程式碼中的各個模組分離開來,以便更好地閱讀和管理。 遇到的問題 我的做法是: 1. 巨集定義、結構體定義、函式宣告以及全域性變數定義
C語言中區域性變數和全域性變數變數的儲存類別(static,extern,auto,register)
C語言中區域性變數和全域性變數變數的儲存類別(static,extern,auto,register) 1----區域性變數和全域性變數 在討論函式的形參變數時曾經提到,形參變數只在被呼叫期間才分配記憶體單元,呼叫結束立即釋放。這一點表明形參變數只有在函式內才是有效的,離開該函式就不能再使用了。
C語言跨檔案呼叫變數方法
使用示例 分別新建三個檔案,a.c ,a.h ,b.c 內容如下 a.c #include<stdio.h> int a = 10;a.h extern int a;b.c