1. 程式人生 > >不要在標頭檔案中定義變數

不要在標頭檔案中定義變數

在寫C程式碼的時候,經常需要在標頭檔案中包含有些預定義的資訊。比如一些結構體的宣告,外部變數,函式的宣告等。

有時候覺得有必要在標頭檔案中定義一些變數,這樣在原始檔中就不需要定義了。但是這樣做,有很大的問題。

比如

//test.h
  1 #ifndef _TEST_H
  2 #define _TEST_H
  3 int x;
  4 const char *name = "hhcn";
  5 #endif
~              

//test.c

#include "test.h"

//main.c
  1 #include <stdio.h>
  2 #include "test.h"
  3 
  4 int main()
  5 {
  6     int j = x;
  7     printf("j= %d\n", j);
  8 
  9 const   char *p = name;
 10     printf("%s\n", p);
 11 
 12     return 0;
 13 }
~                                                                                                                                                                                                        
這樣,編譯的時候,都通過了,但是連結的時候,會報
cc    -c -o main.o main.c
cc    -c -o test.o test.c
gcc main.o test.o -o test
test.o:(.data+0x0): multiple definition of `x'
main.o:(.data+0x0): first defined here
test.o:(.data+0x4): multiple definition of `name'
main.o:(.data+0x4): first defined here
collect2: ld returned 1 exit status

make: *** [all] 錯誤 1

你或許會認為,x我沒有在其他地方定義啊!字串name也是一個常量,怎麼就會報重複定義呢?

其實,在test.c中包含了test.h,裡面定義了x和name,main.c中也是這樣。於是在連結的時候,不知道該用哪一個定義了。

正確的做法應該是隻在標頭檔案中宣告,而真正的定義放到原始檔中,這樣不管哪個原始檔包含了標頭檔案,都不會有問題,因為定義的地方只有一個,連結的時候會找到的。

如果你真的認為很有必要在標頭檔案中進行定義變數,那麼就在前面加上static吧。起碼可以保證你編譯,連結的時候不出錯。

相關推薦

不要檔案定義變數

在寫C程式碼的時候,經常需要在標頭檔案中包含有些預定義的資訊。比如一些結構體的宣告,外部變數,函式的宣告等。 有時候覺得有必要在標頭檔案中定義一些變數,這樣在原始檔中就不需要定義了。但是這樣做,有很大的問題。 比如 //test.h 1 #ifndef _TEST_H

全域性變數檔案定義

        看著標題,定義上面加了一個引號,這個得注意了。怎麼解釋呢,一般而言,變數只能定義在.c檔案中,宣告變數才在.h檔案中。下面就打破常規,把定義變數的語句放在.h檔案中,但是對實際而言,變數定義在標頭檔案中是表面上的。         下面直接給出程式碼,有三個

c++在檔案定義全域性變數時需要注意的地方

我們知道,在 C++(但不是在 C 語言)中,const 限定符對預設儲存型別稍有影響。在預設情況下,全域性變數的連結性為外部的,但 const 全域性變數的連結性為內部的。也就是說,在 C++ 看來,全域性 const 定義就像使用了 static 說明符一樣。

C/C++語言在檔案定義全域性變數

轉載:http://blog.csdn.net/chenqiai0/article/details/8490665 全域性變數可不可以定義在可被多個.C檔案包含的標頭檔案中?為什麼? 可以,在不同的C檔案中以static形式來宣告同名全域性變數。標頭檔案中不可以直接定

檔案定義static靜態變數的利弊

對於儲存位置:靜態變數的效果和全域性變數的效果是一樣的,他們都儲存在全域性資料區。頻繁使用其實效率更高,如果定義的靜態變數不用,那就會浪費記憶體,因為全域性資料區生命週期是從程式執行到結束。 區域性變數:每次棧上都要為區域性變數分配空間,因此區域性變數太多

錯誤:重複定義變數的解決辦法——不要檔案定義變數

在寫C程式碼的時候,經常需要在標頭檔案中包含有些預定義的資訊。比如一些結構體的宣告,外部變數,函式的宣告等。 有時候覺得有必要在標頭檔案中定義一些變數,這樣在原始檔中就不需要定義了。但是這樣做,有很大的問題。 比如 [cpp] view plain cop

能不能在檔案定義全域性變數

首先,這是一篇科普文,所以 比較雜,我儘量寫清楚一些。 1、ANSI C標準是什麼?GNU又是什麼?ld是什麼? ANSI C是C語言的標準規範,是國際標準化組織制定的國際標準。 雖然 ANSI C規範了C語言的實現,但是在實際情況中,各家C語言提供商都會根據平臺的不

為什麼inline函式應該在檔案定義?【轉】

(轉自:https://blog.csdn.net/ronnie_hu/article/details/62238311) inline函式(即行內函數)對編譯器而言必須是可見的,以便能夠在呼叫點展開該函式,與非inline函式不同的是,inline函式必須在呼叫該函式的每個檔案中定義。當然,對

codeblock無法編譯,提示函式沒有定義,但是函式已經 在檔案定義

你在新增檔案時沒有選中Targets。預設情況下,一個工程會有兩個Targets,一個叫Debug,一個叫Release,前者可以除錯,用於開發。後者不能除錯,用於生成最終釋出的軟體。CodeBloc

為什麼inline函式應該在檔案定義

inline函式(即行內函數)對編譯器而言必須是可見的,以便能夠在呼叫點展開該函式,與非inline函式不同的是,inline函式必須在呼叫該函式的每個檔案中定義。當然,對於同一程式的不同檔案,如果inline函數出現的話,其定義必須相同。 正因為如此,建議把

inline函式必須在檔案定義嗎?

前不久在寫程式碼的時候遇到一個link錯誤,程式碼的原型如下所示,基本就是定義了一個基類和派生類,在派生類的一個成員函式中用到了基類定義的一個行內函數。 [cpp] view plaincopyprint? // base.hclass Base  {  protected:     void

const物件為什麼可以在檔案定義

對於標頭檔案中為什麼可以定義const變數(或物件),以及推薦用const代替#define巨集定義,之前一直概念不清晰,今天就總結一下。 之前在網上查過,解釋的都不太到位,或者角度不一樣(從編譯原理、強弱定義?),總之不能清晰理解,發現《C++ Primer》上基本上涵蓋

檔案不能定義變數

標頭檔案中定義全域性變數會出現的問題 =====本文轉載的,在工作中,很受用,特此記錄之。====== 直接在標頭檔案中定義全域性變數,然後有多個檔案包含這個標頭檔案時,編譯通過不了,提示重複定義變數! 在標頭檔案中定義全域性變數時前面加上關鍵字static,此時編譯會通過但是此時全域性

檔案只能宣告變數不能定義變數 而宣告變數必須帶extern,為什麼檔案變數的宣告都沒有加

 1.標頭檔案中不可以放變數的定義!一般標頭檔案中只是放變數的宣告,因為標頭檔案要被其他檔案包含#include,如果把定義放在標頭檔案的話,就不能避免多次定義變數。C++不允許多次定義變數,一個程式中對指定變數的定義只有一次,宣告可以無數次。 三個例外:1)值在編譯時

[C/C++]在檔案使用static定義變數意味著什麼

宣告:本文乃轉載文章,轉載出處:https://www.cnblogs.com/computer1-2-3/p/6088388.html看到有一位同學在標頭檔案中這麼寫:1 static const wchar_t* g_str1 = … 2 static const wch

const變數定義檔案

一。、首先要知道強弱符號 編譯器編譯原始檔時會把原始檔的全域性符號(global symbol)分成強(strong)和弱(weak)兩類傳給彙編器,     而隨後彙編器則將強弱資訊編碼並儲存在目標檔案的符號表中。     那麼何謂強弱呢?編譯器認為函式與初始化了的全域性

檔案的巨集定義 檔案的巨集定義

標頭檔案中的巨集定義     程式碼: 1 #ifndef DSP_ADC_BSP_H_ //防止標頭檔案被重複包含 2 #define DSP_ADC_BSP_H_ 3 4 #ifdef _DSP_

檔案能否進行函式的定義

通常我們使用標頭檔案時都是在標頭檔案中進行宣告,在原始檔中定義,哪我們能否在標頭檔案中進行函式的定義 我們先進行一個測試,先宣告一個test.h和一個test.cpp檔案,並且在test.h中定義一個函式和一個變數 可以發現,程式執行沒有問題,結果也正確

[C++] 檔案不要用using namespace std

先總結下:   1. using namespce std;儘量不要(或者強硬一點,不許)在標頭檔案中使用。     解析: 不讓這麼用,主要原因就是防止名字重複(即自定義變數名和std中名字重複),因為標頭檔案會被很多地方使用,你不知道這個using能覆蓋多大範圍。 &

檔案寫類的實現出現函式重複定義的問題

先來做一個實驗,你在一個頭檔案中定義一個類,然後把內中的一個函式的實現寫在這個標頭檔案當中。 //A_test.h #ifndefine _A_TEST_ #define _A_TEST_ class A { void test(); }; void A::test() {