一、#define和const的區別
(1)就起作用的階段而言: #define是在編譯的預處理階段起作用,而const是在 編譯、運行的時候起作用。
(2)就起作用的方式而言: #define只是簡單的字符串替換,沒有類型檢查。而const有對應的數據類型,是要進行判斷的,可以避免一些低級的錯誤。
(3)就存儲方式而言:#define只是進行展開,有多少地方使用,就替換多少次,它定義的宏常量在內存中有若干個備份;const定義的只讀變量在程序運行過程中只有一份備份。
(4)從代碼調試的方便程度而言: const常量可以進行調試的,define是不能進行調試的,因爲在預編譯階段就已經替換掉了。
二、const的優點
(1)const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查。而對後者只進行字符替換,沒有類型 安全檢查,並且在字符替換可能會產生意料不到的錯誤。
(2)有些集成化的調試工具可以對const常量進行調試,但是不能對宏常量進行調試。
(3)const可節省空間,避免不必要的內存分配,提高效率
三、const int、const int *、int *const、const int *const、const int &的用法
(1)const int ①在定義變量的時候必須初始化,否則報錯 ② 定義後的變量只能讀,不能重新賦值。 頂層 const
/*(1) const int */
const int i = 0; //const int i = 0;這時候的i只能讀,不能賦值了
//i = 9;
printf("i==%d\n", i);
(2)const int * p 這裏const 修飾的是int,而int定義的是一個整值,所以這裏 p爲指向常量的指針。
指向常量的指針變量,只能改變指向,不能改變指向的內容。 非頂層const
/*(2)const char *p */
const char *p = "HelloWord!";
//p[3] = '1'; //指針型 const char *p = "HelloWord!"; 指向的內容不能更改,但可以更改指向。
p = "chenhui";
printf("%s\n", p);
/*(3) int *k 和const int *k的區別*/
int *k = new int[3];
for (int i = 0; i < 3; i++)
k[i] = i;
std::cout << k[0] << " " << k[1] << " " << k[2] << std::endl;
const int *t = new int[3];
//for (int i = 0;i<3;i++) // const int *t 指向的內容不能更改。
//t[i] = i;
cout << t[0] << " " << t[1] << " " << t[2] << endl; // 但是可以訪問; 可以刪除內存 delete []t;
delete[]t;
delete[]k;
t = nullptr;
k = nullptr;
因爲delete只是告訴系統,現在t所指向的這塊內存已還給自由存儲區,不再被使用,可以被其他程序改寫。而此時t依舊指向這塊不可使用的內存,故需要對p進行清零。
(3) int *const a 這裏const修飾的是 a ,a代表的是一個指針地址,a就是常量指針。
常量指針,和上面相反,只能改變指向的內容,不能改變指向。頂層const
// int *const 和 const int * 兩個恰恰相反,int *const,可以更改指向的內容,但不是更改指向;
int *const tt = new int[3];
int *pp = new int[3];
for (int i = 0; i<3; i++)
tt[i] = i;
cout << tt[0] << " " << tt[1] << " " << tt[2] << endl; //可以更改指向的內容
//int a[3]{ 1,2,3 };
int *a = new int[3]{ 1,2,3 }; // 和上一行相同。
//tt = a; // 但不是更改指向
pp = a;
cout << pp[0] << " " << pp[1] << " " << pp[2] << endl;
(4)const int *const 既不能改變指向,又不能改變指向的內容。 第一個const爲非頂層,第二爲頂層
/*const int *const 既不能改變指向的內容,又不能改變指向。*/
const char *const p = "I am Chenhui!";
//p[0] = 'y'; // 既不能改變指向的內容。
//p = "123"; // 又不能改變指向;
cout << p << endl;
總結:頂層const:不可以改變指向,但是可以改變指向的內容的值。 非頂層cosnt:可以改變指向,但是不可以改變指向的內容。
(5)const int &
在引用前面加上const,代表該引用爲常引用,即被引用的對象不可改變。若是在形參中使用,則不可達到在函數裏面修改變量值的目的。
int add(const int &k1, int &k2)
{
//k1 += 10; // 定義爲常引用不能改變。
k2 += 10;
return k1 + k2;
}
int main()
{
int k1 = 4, k2 = 5;
cout << add(k1, k2) << endl;
return 0;
}