命名空間+缺省參數+const總結+引用總結+內聯函數+auto關鍵字 C++初階( 三 )

const全局/局部變量C在C語言中const修改全局變量是存儲在全局區(即靜態存儲區),修飾局部變量時存儲在棧區
//const修飾的常量const int a = 10;//全局const常量,放在常量區,受到常量區的保護void test01(){ //直接修改失敗 a = 100; //間接修改失敗 int *p = &a; *p = 100;}

  • 全局的const修飾的變量本質就是常量,全局const修飾的變量放在常量區中,不能通過變量名直接修改也不可以通過地址來間接修改
//局部conts修飾常量void test02(){ conts int b = 10;//數據放在棧區,是個偽常量 //直接修改失敗 b = 100; //間接修改成功 int *p = &b; *p = 100;}
  • 局部const修飾的變量是個偽常量,不是真正意義上的常量,數據存放在棧區而不是常量區,可以間接修改但是不能直接修改 。
總結:
  • C語言的const修飾的全局變量和局部變量都有空間
  • C語言的const修飾的全局變量具有外部鏈接屬性 , 可以采用extern聲明在別的文件中使用
C++在C++中編譯器會自動優化,會將常量的數值直接替換(類似于宏定義),這導致了const局部變量與真實值產生了不一致 。(常量折疊現象),而C語言會先去內存中尋找,然后替換
舉個例子:
const int aa = 10;//沒有內存void test01(){ cout << aa << endl;//在編譯階段,編譯器會自動優化,將aa直接替換成常量10 const int bb = 20;//棧區 int *p = (int *)&bb; *p = 200; cout << bb << endl;//輸出的還是20,還是那句話,在編譯階段代碼中的bb就已經全部被替換成20,此時其實輸出的是這樣的cout << 20 << endl;但是變量bb此時的值已經被改變了,變成了200,但是由于編譯器優化,造成了常量折疊現象}總結:
  • C++語言的const修飾的變量有時有空間,有時沒有空間(發生常量折疊,且沒有對變量進行取地址操作)
  • C++中,const修飾的全局變量具有內部鏈接屬性,也就是說,無法使用別的文件的const修飾的變量,但是這種規則依舊可以打破
  • const修飾的全局變量永遠都沒有內存 , 永遠無法修改它的值 , 但是const修飾的局部變量可以有空間,可以修改它的值
編譯器不能優化的情況
  • 不能優化自定義數據類型
  • 如果用變量給const修飾的局部變量賦值,那么編譯器也不能優化
  • 使用extern和voaltile關鍵字來阻止優化
例子一:用變量給const修飾的局部變量賦值
void test03(){ int a =10; const int b = a; int *p = (int *)&b; *p = 100; cout << b << endl;//輸出100}例子二:利用關鍵字阻止優化
void test04(){ const volatile int a = 7; int *p = (int *)(&a); *p = 8; cout << "a=" << a << endl;//輸出8 cout << "*p=" << *p; system("pause"); return 0;}例子三:自定義數據類型不能優化
struct Maker{ Maker() {a = 100; } int a;};void test05(){ const Maker ma; cout << ma.a <<endl; Maker *p = (Maker*)&ma; p->a = 200;//可以修改ma中的值 cout << ma.a << endl;}const修飾指針和引用const修飾指針涉及到兩個很重要的概念 , 頂層const和底層const
從 const 指針開始說起 。const int* pInt;int *const pInt = &someInt; , 前者是 *pInt 不能改變,而后者是 pInt 不能改變 。因此指針本身是不是常量和指針所指向的對象是不是常量就是兩個互相獨立的問題 。用頂層表示指針本身是個常量,底層表示指針所指向的對象是個常量 。更一般的,頂層 const 可以表示任意的對象是常量,這一點對任何數據類型都適用;底層 const 則與指針和引用等復合類型有關,比較特殊的是,指針類型既可以是頂層 const 也可以是底層 const 或者二者兼備 。
int a = 1;int b = 2;const int* p1 = &a;//指針常量(頂層const)int* const p2 = &a;//常量指針(底層const)1.指針常量(指針不可改 , 指針指向的對象可改)int a = 10;int b = 5;int * const p1 = &a;p1 = &b; //指針不可改,不合法*p1 = b; //指針指向的對象可改,合法2.常量指針(指針可改,指針指向的對象不可改)int a = 10;int b = 5;const int* p2 = &a;p2 = &b; //指針可改, 合法*p2 = b; //不合法

推薦閱讀