Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 詳解關鍵字static,const,volatile

詳解關鍵字static,const,volatile

編輯:關於Android編程

static修飾局部變量

static修飾局部變量用於修改變量的存儲位置,從自動變量修改為靜態變量(在靜態區開辟空間,不在棧上開辟),但變量的鏈接屬性和作用域不受影響。static修飾局部變量時該變量在程序執行之前創建,並在程序的整個執行空間一直存在,即使出了作用域也只是被隱藏並不銷毀該變量。請看下面的兩段代碼 代碼一:沒有static修飾的局部變量
int main()
{
	int i=0;
	for(i=0;i<10;i++)
	{
		int j=10;
		j+=1;
		printf("%d ",j);   //沒有static修飾的j每次都是10
	}
	system("pause");
	return 0;
}
\ 代碼二:static修飾的局部變量
int main()
{
	int i=0;
	for(i=0;i<10;i++)
	{
		static int j=10;
		j+=1;
		printf("%d ",j);   //有static修飾的j每次都是上一次+1之後的值
	}
	system("pause");
	return 0;
}
\ 從上面兩段代碼可以看出static修飾局部變量確實改變了變量的存儲位置,存儲在靜態區上,出了作用域也未被銷毀,所以代碼二的j每次都是加1之後的值

static修飾全局變量和函數

static修飾函數和全局變量時用於修改變量的鏈接屬性,由extern變為internal,但是變量的存儲類型和作用域不受影響,且static修飾的全局變量只能在他們的源文件中訪問,即使外部文件使用extern也無法訪問 好了static的基礎介紹就到這裡了,下面讓我們來看一道關於static的例題吧
int count=3;
int main()
{
	int i=0,sum=0,count=2;
	for(i=0,sum=0;i

剛一看到這道題是不是有點暈呢?確實剛開始的時候我也覺得有點害怕,因為裡面存在三種不同存儲方式的變量count:全局的,局部的,靜態的,關鍵是它還時不時的使用一下count這就容易讓人搞不清楚到底每次使用的時候調用的是哪一個count,不過不用怕,讓我們來慢慢分析 \

注意:

1).當局部變量和全局變量沖突的時候,局部變量優先,當全局的count和局部的count同時出現時優先考慮局部的變量count 2).extern聲明變量使該變量具有外部鏈接屬性 3).static修飾局部變量(不銷毀該變量出作用域被隱藏)

const

為什仫要存在const關鍵字?以及const可以修飾什仫?用const修飾有什仫與眾不同的地方?下文主要就這三個問題予以討論。 要解決第一個問題就得了解define定義的宏和標識符了   大概了解了define定義的標識符和宏之後,我們就會發現由define定義的宏的很多缺點:宏不可以調試;宏是直接替換的,當替換較多時浪費空間;宏雖然可以傳類型但宏本身是無類型的;宏是帶有副作用的;...而這些缺點正好可以由const來解決。從下面一段代碼中就可以看出
#define MAX 5     //define定義的標識符
const int max=10  //此時未將Max放入內存中而是放到符號表中
int main()
{
	int i=MAX;  //預編譯期間進行標識符的替換
	int j=max;  //此時為j分配內存,以後不再分配
	int m=MAX;  //再進行一次宏的替換,再分配內存
	int n=max;  //不再分內存配
因為編譯器通常不為普通const只讀變量分配存儲空間,而是將他們保存在符號表中,這就使該變量成為一個編譯期間的值,沒有了存儲與讀內存的操作,從而使得效率較高。這就解決了為什仫在C++中以const來代替define定義的標識符和宏了吧

const修飾變量

const修飾變量時const可以在類型的左邊也可以在類型的右邊,比如
const int a=10;
int const a=10;
在C語言中const修飾變量使得該變量具有常性但依然是個變量(在C中const修飾的變量是常變量) 但是在C++中為了消除宏的缺點同時也需要定義常量,此時const修飾的變量去除了它在C中的變量的屬性,完全升級為一個具有常性的量(在C++中const修飾的變量是常量)比如下列代碼:
	const int a=10;
	int arr[a]={0};
數組的長度必須是一個代表常量的值,如果在.cpp下可以運行就可以說明在C++中const修飾的變量是否具有常性了;上述代碼在.c文件中是不可運行的,在.cpp下可以運行的,這就說明在C++中const修飾的變量已經不具有變量的性質了,完全是一個常量

const修飾指針

const修飾一級指針 1).const在*的左邊
	int a=10;
	int b=20;
	const int *pa=&a;
	*pa=20;  //錯誤
	a=20;
	pa=&b;


  const修飾的是*pa,說明指針pa所指向的內容不可以修改,但可以通過pa指針所指向的變量修改也可以改變指針變量本身; 2).const在*的右邊
	int a=10;
	int b=20;
	int *const pa=&a;
	pa=&b;//(錯誤)
	*pa=b;
const修飾的是pa,說明指針變量本身是不可以被修改的,但可以修改指針所指向的內容; 3).const即在*的左邊也在*的右邊
	int a=10;
	int b=20;
	const int *const pa=&a;
	pa=&b;//(錯誤)
	*pa=b;//(錯誤)
此時const即修飾*pa也修飾pa,說明指針所指向的內容是不可以修改的,指針變量本身也是不能被修改的 幫助記憶的小竅門: 如果我們把pa和a看作男女朋友關系,女生a可以換男朋友看作是可以修改變量本身的地址,女生a可以花男朋友的錢類似可以修改變量的內容;const在*的左邊就類似這個女生a是可以換男朋友的但是不可以花男朋友的錢,const在*的右邊就類似這個女生a是可以花男朋友錢的但是不可以換男朋友,const如果即在*的左邊也在*的右邊那這個女生可就慘了,即不可以換男朋友也不可以花男朋友的錢,是不是感覺很有意思呢?

const修飾二級指針

1).const在第一個*的左邊
	int a=10;
	int b=20;
	int *pa=&a;
	int *pb=&b;
	const int **ppa=&pa;
	**ppa=b;//(錯誤)
	ppa=&pb;
	*ppa=&b;
	a=40;


指向關系如下圖: \ const修飾在第一個*的左邊,去掉類型我們發現它修飾的是**pa,說明我們此時是不可以通過指向a這塊空間的二級指針ppa來修改a的值的,但是可以通過a來改變這塊空間的內容,也可以修改ppa指針變量本身 2).const放在兩個*的中間
	int a=10;
	int b=20;
	int *pa=&a;
	int *pb=&b;
	int *const *ppa=&pa;
	ppa=&pb;
	*ppa=&b; //(錯誤)
	**ppa=b;
const修飾在兩個*的中間,根據就近原則,我們知道const修飾的是*ppa,說明此時我們不可以改變ppa所指向的空間pa的內容的,但是我們可以修改ppa指針變量的本身,也可以修改二級指針ppa所指向空間a的值 3).const 放在第二個*的右邊
	int a=10;
	int b=20;
	int *pa=&a;
	int *pb=&b;
	int **const ppa=&pa;
	ppa=&pb;   //(錯誤)
	*ppa=&b;
	**ppa=b;
const放在第二個*的右邊,根據就近原則,我們知道const修飾的是ppa,說明此時我們是不可以修改二級指針ppa指針變量本身的地址,我們可以修改二級指針ppa所指向空間pa和pa所指向空間a的內容 const修飾二級指針還有很多情況,上述只討論了只有一個const修飾的二級指針,只要把握要點,清楚const修飾的是什仫?二級指針本身?二級指針指向一級指針的內容?二級指針指向一級指針的地址?二級指針間接指向變量的內容?只要清楚了這些就可以很好的駕馭const修飾指針的問題了。

const修飾引用

1).const修飾引用即變量的別名,該別名是沒有權限修改該變量的內容的,只能通過該變量修改內容
	int a=10;
	const int &refa=a;
	refa=20;  //(錯誤)
	a=20;
  2).const修飾變量的權限是可以縮小的但不可以擴大
	const int a=10;
	int &refa=a;  //(錯誤)
	int b=20;
	const int &refb=b;
3).const修飾全局變量,該全局變量存放在只讀數據區,即使使用指針也無法修改該變量;定義時不一定分配空間在使用時才分配空間
const int n=10;   //const修飾全局變量
int main()
{

	int arr[n];   //只要說明n為常量也未分配空間
	const int *p=&n;  //此時才為n分配空間
	system("pause");
	return 0;
}
\ 將const修飾的全局變量的地址給指針也就是使用時才分配地址 \ 4).常量具有常性,只有常引用可以引用常量
	int &refa=5;   //(錯誤)
	const int &refb=5;
  5).引用的類型不匹配
	double d1=3.1;
	const int &refd1=d1;  //3
	d1=6.95;

注意: 1).在內存中為變量分配空間時是存在一個臨時變量的,而這個臨時變量是具有常性的(默認類型為const int) 2).當變量本身的名字和別名的類型不符合時,引用的就不是d1了而是這個臨時的變量 3).既然是個臨時的變量使用完後就會銷毀,所以當再修改變量d1的值也不會影響refd1的值   6).const修飾函數的參數,修飾函數的返回值:   當希望在函數內部不可以隨意修改該變量的值時可以給函數的參數加上const修飾 const也可以修飾函數的返回值,此時函數的返回值是不可被修改的或者當確實需要返回一個常性的值時可以用const修飾函數的返回值,比如類的六個默認的成員函數的拷貝構造函數就是傳常引用,以日期類為例的拷貝構造函數
	Date(const Date& d)  
		:_year(d._year)
		,_month(d._month)
		,_day(d._day)
	{}
 

const修飾成員函數

const修飾成員函數,在成員函數後面加const,const修飾this指針所指向的對象,也就是保證在調用這個成員函數的對象在函數內不會被改變   以日期類為例觀察const修飾成員函數時的具體傳值過程 \ 日期類
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;

class Date
{
public:
	Date(int year,int month,int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
	void Display()const
	{
		cout<<_year<<"-"<<_month<<"-"<<_day<

  此時也就存在了下面幾個問題,這也是我們之前提到的const修飾變量的權限問題(權限可以縮小但不可以擴大) 1).const對象不可以調用非const成員函數,可以調用const成員函數 2).非const對象可以調用非const的成員函數,也可以調用const成員函數 3).const成員函數可以調用其他的const成員函數,不可以調用非const的成員函數 4).非const成員函數內可以調用其他的成員函數,也可以調用非const成員函數 這是我個人的一點小理解,如果有讀者知道有更多的用法請聯系我,本人郵箱[email protected]  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved