1、C語言中的const
:
-
const
修飾的變量是只讀的,本質(zhì)還是變量 -
const
修飾的局部變量在棧上分配空間 -
const
修飾的全局變量在只讀存儲區(qū)分配空間 -
const
只在編譯期有用,在運行期無效 -
const
不能定義真正意義上的常量
const
修飾的變量不是真的常量,它只是告訴編譯器該變量不能出現(xiàn)在賦值符號的左邊。const
局部變量是在棧上分配空間强品,可以通過指針改變這個空間里面的值。過了編譯期屈糊,const
變量的常量特性的榛,只讀特性就沒有了,只讀特性只在編譯期有效逻锐,運行期根本無效夫晌。const
修飾的全局變量在只讀存儲區(qū)分配空間雕薪,因此如果用指針去修改了const
修飾的全局變量,程序就會崩潰晓淀,因為修改了程序只讀存儲區(qū)中內(nèi)容所袁,大部分程序都會發(fā)生崩潰。
2凶掰、C++中的const
:
C++在C的基礎(chǔ)上對const
進行了進化處理燥爷,具體表現(xiàn)在:
const
聲明時,在符號表中放入常量編譯過程中發(fā)現(xiàn)常量直接以符號表中的值替換(常量折疊)
-
編譯過程中也可能為對應(yīng)的常量分配存儲空間:
-
const
用在全局或者使用了static
關(guān)鍵字說明锄俄,存放在只讀數(shù)據(jù)區(qū)extern const int i = 10; static const int i = 10; // 或者修飾全局變量 const int a =10; int main() {}
局部變量中對
const
常量使用了&
操作符局劲,在棧區(qū)分配空間
-
注意:C++編譯器雖然可能為
const
常量分配空間勺拣,但不會使用其存儲空間中的值符號表是編譯過程中產(chǎn)生的一種數(shù)據(jù)結(jié)構(gòu)
#include <iostream>
#include <string>
using namespace std;
const int i = 10; // 如果通過指針去改變i奶赠,就會出現(xiàn)段錯誤:嘗試修改只讀數(shù)據(jù)區(qū)數(shù)據(jù)
int main()
{
const int a = 5;
int *p = (int *)&a; // &a, 給a標識符分配空間了药有,并用p指向了該空間毅戈,
// 可以通過*p訪問這個地址,但是不能通過a來訪問
*p = 10; // 不能通過指針去改變a的值
cout << a << endl;
cout << *p << endl;
return 0;
}
3愤惰、 與宏定義對比
C++ 中的const
常量類似于宏定義
const int c = 5;
// 類似于
#define c 5
但是cosnt
與宏定義的區(qū)別在于:
-
const
常量是有編譯器處理 - 編譯器對
cosnt
常量進行類型檢查和作用域檢查 - 宏定義由預(yù)處理器處理苇经,只是進行單純的文本替換
#include <stdio.h>
void f()
{
#define a 3
const int b = 4;
}
void g()
{
printf("a = %d\n", a);
// 在g函數(shù)中訪問f函數(shù)中的宏定義,完全沒有問題
// 在預(yù)處理的時候就進行了宏替換宦言,對編譯器來說扇单,就是printf("a = %d\n", 3);
// 宏是沒有作用域的概念
// const 定義的常量,被編譯器處理奠旺,是有作用域的蜘澜,不能訪問b
printf("b = %d\n", b);
}
int main()
{
const int A = 1;
const int B = 2;
int array[A + B] = {0};
/* C編譯
const修飾得到的只是具有只讀特性的變量,數(shù)組的大小是由兩個變量的大小決定的响疚,
兩個變量相加的結(jié)果需要在運行的時候才能直到鄙信,因此編譯器編譯的時候不知道這個數(shù)組長度,直接報錯
*/
/* C++編譯
const是定義的真正意義上的常量忿晕,直接從符號表中取值装诡,編譯的時候就知道A和B的值,
可以得到數(shù)組的長度践盼,不會報錯
*/
int i = 0;
for(i=0; i<(A + B); i++)
{
printf("array[%d] = %d\n", i, array[i]);
}
f();
g();
return 0;
}