1. 程式人生 > >對全域性變數的multiple definition的一點理解

對全域性變數的multiple definition的一點理解

Q:使用#ifndef在標頭檔案中定義全域性變數,然後兩個.c檔案分別訪問(#include),編譯時就會出現multiple definition的提示,但是已經使用了條件編譯,理論上第二次應該跳過定義過程,這是為什麼呢?

A:這類條件編譯是為了防止同一個.c檔案包含同一個標頭檔案多次。
樓主要明白:每一個.c檔案最後都會編譯生成對應的.obj檔案的。所以你的兩個.c檔案對應的兩個.obj檔案都會有你說的那個全域性變數的,連結的時候,連結器就會發現有定義了兩個同名變數,於是就報multiple definition錯誤。
正確的做法是:是其中一個.c檔案定義這個變數,在另外一個.c檔案用extern宣告

也就是確保只定義一次,而宣告則可以多次
因為標頭檔案很容易被不同的.c檔案include,生成多個.obj目標檔案,因此正確的做法就是不要在標頭檔案中定義全域性變數,而應該在.c/.cpp檔案中定義

相關推薦

全域性變數 multiple definition of 問題解決方法

解決方法:1.給每一個頭檔案加上條件編譯:注:此方法不是解決上述問題的方法,只是解決multiple definition of的一個方法。 當多個檔案包含同一個標頭檔案時,而標頭檔案中沒有加上條件編譯,就會獨立的解釋,然後生成每個檔案生成獨立的標示符。在編譯器連線時

全域性變數multiple definition一點理解

Q:使用#ifndef在標頭檔案中定義全域性變數,然後兩個.c檔案分別訪問(#include),編譯時就會出現multiple definition的提示,但是已經使用了條件編譯,理論上第二次應該跳過定義過程,這是為什麼呢? A:這類條件編譯是為了防止同

全域性變數一點發現

有三個檔案ex1.c ex1.h main.c想來測試一下多檔案共同編譯時,他們的"共同變數"究竟是有著怎樣的關係 ex1.c:  #include "ex1.h" int a=0; void numadd() {         a++;         b+

事件循環的一點理解

.post require 順序 this ref abcd his cti 如何 最近工作需要學習了解webworker-threads以應對Javascript多線程處理CPU密集型的可能性;參考文檔JavaScript多線程之二 Node.js中的Web Worker

淺談後綴自動機的一點理解

字符串 變化 post .... 初始 mar 一起 樹狀 子集 後綴自動機入門詳解及模板

頁面中 全域性變數 的更新(ajax也可以全域性變數 進行更新)

1 2 3 4 5 6 7 8 9 10 11 12 function checkoldpass($pass) {     $.ajax({     &nb

狀壓dp的一點理解

博主是初學者,以下僅代表個人觀點,若有錯誤歡迎指出。 狀壓dp       此dp可以理解為最暴力的dp,因為他需要遍歷每個狀態,所以將會出現2^n的情況數量,所以明顯的標誌就是資料不能太多(好像是<=16?),然後遍歷所有狀態的姿勢就是用二進位制來表示,01串,1表

spring cloud config的一點理解

  以下部分純屬個人理解,但是結果都是經過demo驗證。 一、spring cloud config介紹   spring cloud是spring家族中的一個微服務工具包,其中包含了很多微服務的工具。偏向於與spring boot類似的配置方式,有許多許多預設配置。spring cloud config是其

js中區域性變數全域性變數和閉包的理解

對js中區域性變數、全域性變數和閉包的理解 區域性變數 對於區域性變數,js給出的定義是這樣的:在 JavaScript函式內部宣告的變數(使用 var)是區域性變數,所以只能在函式內部訪問它。(該變數的作用域是區域性的)。可以在不同的函式中使用名稱相同的區域性變數,因為只有宣告過該變數的函式才能識別出該變數

UIRect 的一點理解

mat wan function end height 默認 標記 targe 影響   UIRect,一個繼承 MonoBehaviour 的抽象類,主要實現了錨點功能。 2.1 UIRect 簡單介紹   UIRect 內實現了類 AnchorPoint,它保存了具體的

機器學習的一點理解

求導 分段 梯度下降法 部分 技術分享 直接 標註 sqrt 插件 ????機器是什麽,機器就是電腦、芯片、代碼這些東西。讓電腦遵循人的指令,完成一件特定的任務從計算機發明那天開始就在研究了,現在的各種編程語言、數據結構和編程算法等都是在做這個。但是它們只能依賴於程序員輸入

面向過程與面向象的一點理解

面向過程 -- 數據格式 一點 理解 格式 tro 數據 結構 面向過程  首先確定編程計算機應采取的操作,然後使用編程語言來實現這些操作。(使問題滿足語言) 面向對象  設計與問題的本質特性相對應的數據格式--類,對象是根據這種規範構造的特定數據結構。(使

求有向圖強連通分量的tarjan算法原理的一點理解

深度優先 含義 出現 組合 分支 ron 滿足 根節點 節點和 先簡單敘述一下tarjan算法的執行過程(其他諸如偽代碼之類的相關細節可以自己網上搜索,這裏就不重復貼出了): 用到兩類數組: dfs[]:DFS過程中給定節點的深度優先數,即該節點在DFS中被訪問的次序 lo

成員變數和區域性變數一點了解

package com.HelloWorld; public class HelloWorldd { public static void main(String[] args) { //用HelloWorldc類建立物件 HelloWorldc peopl

學習Java之關鍵字break和continue的一點理解

我們都知道關鍵字 ——   break 是 預設跳出當前距離此 break 最近的一個 for / while 迴圈語句塊 或  switch 開關語句塊; 例-1:跳出迴圈 for(;;) { while(true)

計算機網路學習的一點心得1之網路整體協議架構理解

網路整體協議架構理解 我們都知道,在學習《計算機網路》這門課時,RFC文件把OSI(開放系統互連參考模型  - Open System Interconnect )分為了七層,它們從現實世界到網路世界再到計算機世界分別是——物理層、資料鏈路層、網路層、傳輸層、會話層、表示層、

編寫一個程式,一個整型陣列的元素求和,結果使用全域性變數sum儲存,另外陣列元素中的奇數求和,結果使用區域性變數sum儲存,在主程式將兩個結果輸出。

#include<iostream> using namespace std; int sum_1(int a[]);//定義計算奇數的和; int main() { int a[]={1,2,3,4,5,6,7,8,9,10};//定義陣列並附初值; int i,sum=0,s

LightGBM的一點理解

LightGBM是微軟團隊2017年發表在NIPS的一篇論文,也是一種基於GBDT的Boosting的方法。之前有了各種Boosting方法,以及在各類資料比賽中大放異彩的XGBoost,LightGBM的優勢在哪裡呢? LightGBM是一種基於GBDT的提升方法。對

先驗後驗概率的一點理解

先驗概率是由某些起因推匯出結果發生的概率,如用在全概率公式中。 利用過去歷史資料計算得到的先驗概率,稱為客觀先驗概率; 當歷史資料無從取得或資料不完全時,憑人們的主觀經驗來判斷而得到的先驗概率,稱為主觀

梯度下降法和反向傳播BP的一點理解

       最近在學習深度學習中的梯度下降與反向傳播方面的知識。偶有心得,特此記錄。若有不足之處,煩請指正賜教。        在訓練階段,深度神經網路經過前向傳播之後,得到的預測值與先前給出真實值之間存在差距。我們可以使用損失函式來體現這種差距。損失函式的作用可以理解為