詳解C語言中的變量

什麼是變量

變量在C語言中就是一個容器,通常是一塊內存。

聲明變量

變量類型 變量名;
例如:
int x;

在上面的代碼裏,int就是變量類型,x就是變量名。變量類型用來說明數據寬度,變量名的命名規則與函數名一致。。

變量類型 數據寬度
int 4個字節
short 2個字節
char 1個字節

全局變量

  • 編譯的時候就已經確定了內存和寬度,變量名就是內存地址的別名。
int x;			//聲明變量

void main()		//入口
{
	x = 1;		//賦值
	return;		//程序結束
}

我們從反彙編中查看一下這個程序,從這裏可以看到,全局變量它有一個獨一無二的內存編號,從這裏我們可以理解,什麼是變量名?變量名就是內存地址的別名。
在這裏插入圖片描述

  • 如果不重寫編譯,全局變量的內存地址不變,遊戲外掛中找“基址”其實就是找全局變量。

    這句話怎麼理解呢,就是我們編寫完程序按F7構建,現在我不按F7了,依然是剛纔的程序,我直接按F5讓它運行,我們看一下它內存地址的變化:

int x;			//聲明變量

void main()		//入口
{
	x = 1;		//賦值
	return;		//程序結束
}

在這裏插入圖片描述可以看到,內存地址沒有發生變化,也就是隻要不重建,內存編號就始終不會改變。

做一個小“外掛”

我們做一個小實驗,假設我們在玩傳奇,下面的這一段代碼是我們的攻擊頻率與攻擊力,我們怎麼樣來達到每刀999的效果呢?

#include <stdio.h>
#include <windows.h>	//文件頭

int x;					//全局變量

void main()				//程序入口
{
	x = 80;				//攻擊力

	while(1)			//攻速
	{
		Sleep(3000);		//每3秒砍一刀
		printf("%d\n",x);	//輸出攻擊力

	}

	return;				//程序結束
}

這裏用到一款軟件,CE,它可以修改程序的變量,我們先打開CE,把程序跑起來,可以看到,這裏每3秒砍一刀,一刀80,接下來我們就讓它每刀999
在這裏插入圖片描述

把文件加載到CE裏,具體怎麼加載這裏不多介紹。
在這裏插入圖片描述

搜一下80這個變量,這裏有一個綠色的,這就是全局變量,咱們更改變量數值爲999
在這裏插入圖片描述點擊確定,看看效果如何。
在這裏插入圖片描述這樣我們接下來砍的每一刀都是999,外掛的原理跟這個是一樣的,只不過操作起來麻煩一點罷了,這裏我們就用到了上文所說的“基址”,也就是確定了的全局變量的地址。

也就是說:

  • 全局變量中的值任何程序都可以改,是公用的。

局部變量

  • 局部變量是函數內部申請的,如函數沒有執行那麼局部變量沒有內存空間。
  • 局部變量的內存是在堆棧中分配的,程序執行時才分配,我們無法預知程序何時執行,這也就意味着,我們無法確定局部變量的內存地址。
  • 因爲局部變量內存地址是不確定的,所以局部變量只能在函數內部使用,其他函數不能使用。

之前的變量我們是在函數外面聲明的,現在我們把它刪掉,在函數內部聲明。

#include <stdio.h>
#include <windows.h>

int plus()		//定義函數
{
	int x;			//局部變量
	x = 123456;		//賦值

	return 0;
}

void main()		//這裏加這個函數是爲了不讓程序掛掉
{
	;while(1)	//無限循環
	{
		Sleep(3000);
	}
	return;
}

這段代碼執行以後,我們是搜不到“123456”這個局部變量的,原因很簡單,就是局部變量沒有使用,它沒申請內存地址,所以我們用CE搜多少次都是搜不到的。

我們修改一下代碼,讓函數調用這個局部變量:

#include <stdio.h>
#include <windows.h>

int plus()		//定義函數
{
	int x;			//局部變量
	x = 123456;		//賦值
	
	while(1)		//延長程序的執行時間
	{
		Sleep(3000);
	}
	return 0;
}

void main()
{
	plus();
	
	return;
}

這裏用CE雖然搜到了,但是它並不是全局變量,而且每次搜到的地址都是不一樣的,這也證實了上面的觀點。
在這裏插入圖片描述
所以局部變量與全局變量最大的差異就是:局部變量在函數邊,函數用它纔有值,函數不用,它就沒有值,而且它的地址沒法確定,因爲我們也不知道這個函數什麼時候會被調用。

關於變量的初始值

這裏全局變量可以沒有初始值,系統默認爲零,是可以直接使用的。

例如這段代碼:

#include <stdio.h>
#include <windows.h>

int x;		//定義全局變量

void main()	//程序入口
{
	while(1)	//無限循環,每一秒輸出一個x的值
	{
		Sleep(1000);
		printf("%d\n",x);
	}

return;		//程序結束
}

運行結果可以看到,我們並沒有給x賦值,系統默認NULL就給它賦值爲0.
在這裏插入圖片描述
但是局部變量爲什麼不可以呢?下面這段代碼執行報錯:

#include <stdio.h>
#include <windows.h>

int plus()
{
	int x;
	{
//		x = 666;

		while(1)
		{
			Sleep(1000);
			printf("%d\n",x);
		}
	}
}


void main()
{
	plus();

	return;	
}

在這裏插入圖片描述
這是因爲,未初始化的局部變量的值是不確定的,上一次誰使用過這一塊的棧區,恰好留在局部變量所在區域的值等於幾,這次局部變量的未初始化的默認值就是幾,這一點是非常麻煩的,所以一定要給局部變量初始化。

總結

  • 變量就是一個容器。
  • 變量類型用來確定變量的內存寬度。
  • 變量名就是內存的編號。
  • 全局變量中的值任何程序都可以改,是公用的。
  • 局部變量必須初始化。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章