從本章起開始從0學習C++,本章主要內容:
- 1)C和C++的基本區別
- 2)C和C++的const區別
1.C++和C區別
1.1 C++更強調語言的實用性,所有變量都可以在需要時再定義
比如:
for(int i=0;i<100;i++);
1.2 C++不允許定義多個同名全局變量,而C卻可以重復定義
1.3 C++的register只是個兼容作用
1.4 C++的所有標識符都必須有聲明類型
比如,在C中:
f(): 表示默認返回值是int,可以接受任意個int型參數的函數
在C++中:
int f() int f(void)表示都一樣,沒有參數,返回值為int型的函數
int f(i): 由於i沒聲明類型,會報錯
1.5 結構體升級
例如,在C中定義一個結構體:
typedef student_type student; //聲明
struct student_type{ char *name; int age; }; struct student_type student1={"Li",20}; /*或者*/ student student2={"Zhang",20};
而在C++中,只需要這么寫:
struct student_type{ char *name; int age; }; student_type student2={"Zhang",20}; //不需要strcut再次聲明
C和C++的const區別
2. C中的const
2.1 介紹
C語言中的const只是讓變量變為只讀屬性,其本質還是變量,不是真正意義上的常量(只有enum枚舉定義的才是常量).
注意:const變量不能被直接賦值,但是可以通過指針來修改const變量.
由於const局部變量會存在棧里,而const全局變量會存在只讀存儲內存上
所以我們可以通過指針來修改const局部變量,但是修改const全局變量,會使程序崩潰.
2.2修改const實例
1)實例1-通過指針來修改const局部變量
代碼如下:
#include <stdio.h> int main() { const int c = 0; //const局部變量 int* p = (int*)&c; *p = 5; //通過指針修改const變量 printf("c = %d\n", c); return 0; }
輸出結果:

2)實例2-通過指針來修改const全局變量
代碼如下:
#include <stdio.h> const int c = 0; //const全局變量 int main() { int* p = (int*)&c; *p = 5; //修改const變量 printf("c = %d\n", c); return 0; }
輸出結果:

由於指針修改只讀存儲區的數據,所以導致程序崩潰
3. C++中的const
3.1 介紹
在C++中,const變量則是真正的常量了,定義時會將其放入符號表中.
所以編譯途中遇到使用const變量時,則直接從符號表中取出常量.
只要當該const變量為全局(使用extern聲明過),或者被使用&操作符時,才會被分配存儲空間.
接下來,我們以一個例子來分析存儲空間
代碼如下:
#include <stdio.h> int main() { const int c = 0; //const局部變量 int* p = (int*)&c; //使用&操作符,會分配空間 *p = 5; printf("c = %d,*p=%d\n", c,*p); return 0; }
輸出結果:

為什么輸出結果會有兩個不同的值?
這是因為使用&c時,會從符號表中取出c的值,並將0存在一個新的分配空間地址里,所以*p修改的只是分配出來的空間地址內容,而c還是常量.
3.2 const和define區別
是不是感覺C++中的const和 define宏定義一樣?其實不一樣!
- const常量: 由編譯器處理,它會對const常量進行類型檢查和作用域檢查
- define宏定義: 由預處理器處理,直接進行文本替換,不會進行各種檢查
(預處理器是執行編譯器之前運行的程序,用來刪除注釋,宏變量轉換等)
接下來,我們以一個例子來分析const和define
代碼如下:
#include <stdio.h> void f() { #define a 3 //定義宏 const int b = 4; //定義局部變量 } int main() { f(); printf("a=%d",a); //printf("b=%d",b); return 0; }
輸出結果:

這是因為執行預處理器時,會將遇見到的所有a變為3,所以編譯器看到的是printf("a=%d",3);
而取消//printf("b=%d",b); 屏蔽后,程序則會報錯,是因為b的作用域只在f()函數里有效.
3.3 指針const
指針const分為兩種: 底層const, 頂層const
(普通變量的const(或引用)永遠是頂層const,也就是說,const int 和int const本質都一樣)
1)底層const(位於*左側)
常量指針,表示指向的對象是個常量,不能修改其內容,只能更改指針指向的地址.
其實很好理解,比如 const int *p, 修飾*p是個const常量.而*p是指向對象的內容.所以表示指向對象的內容是常量
但是可以通過其它方式修改內容,例如:
int a=1,b=3; const int *p=&a; //底層const //*p=2; //錯誤,無法修改*p指向的a里面內容 a=2; //正確,通過其它方法來修改*p的內容 printf("%d\n",*p); p=&b; //正確,可以更改指針指向的地址 printf("%d\n",*p);
輸出結果:
2 3
2)頂層const(位於*右側)
指針常量,表示不能更改指針指向的地址,只能修改其內容(定義時必須被初始化)
其實很好理解,比如 int * const p, 修飾 p是個const常量.而 p是指向對象的地址.所以表示指向對象的地址是個常量
和引用非常相似,例如:
int a=1; int b=3; //int *const p; //錯誤,沒有被初始化 int *const p=&a; //頂層const //p=&b; //錯誤,不能更改指針指向的地址 *p=2; //正確,修改a的值等於2
3.4 頂層const變量可以替代mutable變量
1) mutable介紹
mutable 是為了突破 const 的限制而設置的。被 mutable 修飾的變量,將永遠處於可變的狀態,即使在一個 const 函數中,甚至結構體變量或者類對象為 const,其 mutable 成員也可以被修改。
示例1:
class Test{ mutable int mval; public: Test():mval(0) { } void setVal(int num) const { mval=num; cout<<mval<<endl; //打印10,能在const函數中對mutable變量賦值 } }; int main() { const Test t; t.setVal(10); }
2)通過const替代后:
class Test{ int * const mval; public: Test():mval(new int(0)) { } void setVal(int num) const { *mval=num; //由於mval是const類型,所以修改時不會報錯 cout<<*mval<<endl; //打印20 } }; int main() { const Test t; t.setVal(20); }
3.5 volatile const
大家都知道volatile是指對該變量操作時,不能進行優化
1)在c++中,使用volatile const時,編譯器不會將其放入常數表,而是以只讀變量的形式來定義
例如:
volatile const int x=1; int *p= (int *)&x; *p=2; printf("x=%d\r\n",x);
輸出結果:
x=2
2) 當使用const時,賦予的值是volatile類型時,也是以只讀變量形式,因為編譯器不能將該volatile類型的變量優化為一個常量
實例:
volatile int x=1; const int y=x; //y的值是個volatile型 int *p= (int *)&y; *p=2; printf("y=%d\r\n",y);
輸出結果:
y=2
本章結束,下章來學習: C++中的bool類型,三目運算符,引用
