1. 程式人生 > >C++隨筆--1)函式,外部變數的定義與宣告問題,2)程式的編譯問題

C++隨筆--1)函式,外部變數的定義與宣告問題,2)程式的編譯問題

1) 函式,外部變數的定義和宣告問題

    1)(2017-9-17日目前認為) 區域性變數無論定義時賦值與否 (int a 或  int a = 2),我們都可以大概認為此時 定義和 宣告是一回事,但通過反彙編我們可以知道如果沒有賦初值那麼其實只是一種奇怪的宣告,並沒有定義,因為定義的概念是在儲存空間中有實體。

    2) 沒有static 的全域性變數 稱之為外部變數 (外部變數,固名思意,個人認為外部變數相當於開了上帝視角的變數,不受單個原始檔篇幅限制,其作用範圍可以利用extern宣告擴充套件到任何原始碼檔案的任何部位

)。ps: 正因為外部變數是在所有原始檔之外定義的,他們的作用範圍可以擴充套件到原始檔的任意地方。所以一個外部變數只能在一個cpp中定義,但可以多個cpp中宣告。

    3)函式的定義和宣告:

          在C++語言中函式不能在 函式內部定義,而且函式的“定義”也需要佔據儲存空間(在程式碼區儲存),所以函式(的定義)也就相當於外部變數。在函式宣告時 可以顯示的宣告 (+extern) 而我們大多數情況下是 隱示的宣告的。

    4)關於宣告的理解:

          宣告的作用在之前已經提到,是為了編譯的順利通過(定義是否缺失,是否重複,在連結部分執行),只要聲明瞭 相關的函式,外部變數,程式就不會顯示語法錯誤。宣告是為了告訴編譯器以下內容我在某一個地方定義了,讓編譯器從上到下編譯時認得某些函式或者變數(外部變數)的名字(認得就行,不管是否定義),從而順利編譯。詳見一下程式碼:ps 雖然不可以重複定義但是可以重複宣告。

          comA.h 檔案

namespace A{                                      //關於標頭檔案的作用,標頭檔案一般情況不包含函式,外部變數的定義(可能導致重複定義),只包含宣告。                                                      //在編譯的時候,我們只編譯cpp檔案,標頭檔案的作用只是 #include到cpp檔案中區。並不編譯生成.obj檔案

	extern void fun();                        //宣告一個在 A 名稱空間的 fun()函式,告訴編譯器 反正我在 某個地方定義了。
		/*{                               //在不使用 名稱空間時 如單純的 void fun();,表明 聲明瞭一個 全域性名稱空間的 fun()
		std::cout << "A"<< std::endl;
		}*/
	extern int x;                            //宣告一個 在A名稱空間中的 全域性變數 x ,其定義在 其他.cpp檔案中實現。讓編譯器 認得 A::x

}


           comA.cpp 檔案

#include <iostream>
#include "comA.h"

void A::fun(){
	std::cout << "this is A::fun()";
}

//namespace A{
//	int x = 33333;
//}                        //註釋和下一行等價,都是定義了一個 在A 中的 x = 3333

int A::x = 33333;
int x = 55555;

    main.cpp 檔案
#include <stdlib.h>
#include <iostream>
#include "comA.h"




//可以重複的宣告,但是不可以重複的定義  我可以連著 宣告 兩次 fun();

//extern int A::x;
int main(void)
{
	//std::cout<< x <<std::endl;
	std::cout<< A::x <<std::endl;

	A::fun();
	
	std::cout << "hello"<<std::endl;
	system("pause");
	return 0;
}

參考連結 我的論壇問答:問答

ps :所有原始檔都需要編譯,所以哪怕沒有用的原始檔都必須正確,因為一個工程中的,h檔案在#include到.cpp之後才能起作用(被編譯),所以標頭檔案若沒有被任何#include就可以有語法錯誤。

pps: 外部變數在.cpp編譯時在靜態儲存區分配記憶體,所以如果在不同.cpp中定義了相同的外部變數,就會重複定義。