您好,登錄后才能下訂單哦!
const是C語言中總結
1.修飾的變量,使其具有常屬性,使變量的值不能直接被改變。但是可以通過指針來間接的修改變量的值。
2.便于進行類型檢查(在編譯時進行類型檢查),使編譯對處理內容有更多的了解,保護被修飾的東西,防止被意外修改,增強程序的健壯性。
3.方便的進行參數的調整和修改(類似于宏定義)
作用1說明:
修飾的變量,使其具有常屬性,使變量的值不能直接被改變。但是可以通過指針來間接的修改變量的值
例如:
const int t=10;
//在以后的代碼中,程序不可直接對i進行修改
//但是可通過指針來間接的修改i變量中存的值
t=2; //會報錯
int *p=(int *)&t;
*p=2; //在此處就將i中的值存成2了
const修飾指針變量:
int main()
{
int a = 10;
const int *p = &a; //const修飾int *,即p的指向,因而p指向的內容即通過pa解引用后不能被修改,但是p中存的內容可以改變,即p的指向可以改變
int * const q=&a; //const修飾*,即q變量,因而q里存的內容不能變,即q的指向不能改變,但是q指向的內容即a中的內容可以修改。
p++;//正確
(*p)++;//錯誤
q++;//錯誤
(*q)++;//正確
return 0;
}
所以看const修飾誰,要看const右面有什么
比如:
int **const* p; 則通過*p來修改對應的內容則報錯
int **const** p; 則通過**p來修改內容則會報錯
通過const的特性,const可以在很多地方派上用場
比如在傳參時,不想通過函數來改變實參值,在傳實參地址時,形參接收在前可加const修飾,這樣就不會在函數里通過解引用來修改實參值了
在c++中:
1.const修飾變量的用法和作用與c語言一樣,但是有一點不同
#include <iostream>
using namespace std;
int main()
{
const int a = 1;
int* p = (int *)(&a);
*p = 2;
cout << "value of p: " << *p << endl;
cout << "value of a: " << a << endl;
cout << "address of p: " << p << endl;
cout << "address of a: " << &a << endl;
return 0;
}
輸出
/*value of p: 2
value of a: 1
address of p: 0x7fbffff7fc
address of a: 0x7fbffff7fc
由答案可知,a并沒有像c語言中一樣,被p修改為2,這是為什么呢?
原因: const int a其實是保存在符號表中,無內存地址,但自己對a進行&a,那么編譯器會為a分配一個地址,但取a的值依然是從符號表中取值,而用指針int *p=&a;
*p=4這個值是改變a的內存所表示值,不會改變符號表中a的值。
#include <iostream>
using namespace std;
const int a = 3; //此時a是全局變量
int main()
{
//const int a = 3;
int* p = const_cast<int*>(&a);
*p = 4;
cout << "value of p: " << *p << endl;
cout << "value of a: " << a << endl;
cout << "address of p: " << p << endl;
cout << "address of a: " << &a << endl;
return 0;
}
輸出結果
會發生如此運行時錯誤
由此可見,在c++中全局const變量和局部const變量的編譯器處理的方法是不一樣的。因為全局const變量是不分配內存地址的,它編譯器放置在符號表中作為編譯期常量,全局const變量放在只讀數據段中,受到只讀數據段的權限保護,當你修改一個只讀數據段中的內容時,會得到一個運行時錯誤。而局部const變量是放在堆棧之中,因為在內存中有地址,通過修改地址中的值可以達到修改const所指內存中值的目的。
2.此外,在c++中,const還可用來修飾成員函數,其用法是放在形參列表之后,
用來修飾隱式傳入構造函數中的this指針,表明在函數調用的過程中,不可對this指向的內容進行修改,即不可修改調用這個構造函數對象中的內容。
被const修飾的成員函數,稱作為const類型的成員函數
例如:
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
cout << "Date(int,int,int):" << this << endl;
}
// 在const成員函數中,不能修改類的任何成員變量
void PrintDate()const
{
//_year++;
//即this->_year++; 會報錯
// 在函數被修飾后,this的類型為 const Date* const (因為this指針本來就是const型的this不可修改指向,后面的const表明this指向里的內容也不可修改)
_day++; //√
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
mutable int _day; //在成員變量名前加mutable關鍵字后,成員函數即使加const也可修改_day的值
};
int main()
{
Date d1;
d1. PrintDate();
}
用const修飾成員函數有以下注意事項:
1>const不可修飾其他類外函數(對有this的函數才有用)。不可調用構造函數,因為構造函數目的就是要修改成員變量。
2>const對象不可以調用非const成員函數。因為普通成員函數是可以修改成員變量的,如果允許修改,拿不可修改的const對象就會被修改了,不安全。
3>非const對象可以調用const成員函數。因為普通變量可讀可寫,const函數只允許對調用對象進行讀,因此沒有什么不可。
4>const成員函數不可以調用非const成員函數。普通函數可對對象進行修改,在調用普通函數時可能會修改對象,因此const成員函數不能調用非const成員函數。
5>非const成員函數可以調用const成員函數
(1) 編譯器處理方式不同
define宏是在預處理階段展開。
const常量是編譯運行階段使用。
(2) 類型和安全檢查不同
define宏沒有類型,不做任何類型檢查,僅僅是展開。
const常量有具體的類型,在編譯階段會執行類型檢查。
(3) 存儲方式不同
define宏僅僅是展開,有多少地方使用,就展開多少次,不會分配內存。
const常量會在內存中分配(可以是堆中也可以是棧中)
const修飾可以節省空間,避免不必要的內存分配(與宏定義的本質區別)
宏的優點:
1.增強代碼的復用性。
2.提高性能。
缺點:
1.不方便調試宏。(因為預編譯階段進行了替換)
2.導致代碼可讀性差,可維護性差,容易誤用。
3.沒有類型安全的檢查
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。