1.C和C++區別,以及const分析
從本章起開始從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
", 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
", 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
", 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本質都一樣)
底層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
",*p);p=&b; //正確,可以更改指針指向的地址printf("%d
",*p);
輸出結果:
2
3
頂層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 volatile const
大家都知道volatile是指對該變數操作時,不能進行優化
1)在c++中,使用volatile const時,編譯器不會將其放入常數表,而是以只讀變數的形式來定義
例如:
volatile const int x=1; int *p= (int *)&x; *p=2;printf("x=%d
",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
",y);輸出結果:y=2
推薦閱讀:
※Kong-Microservice & API Management Layer
※nginx為什麼性能這麼優越?
※把nginx改為一個普通的tcp伺服器,應用層協議自己定義,有可行性嗎?
※nginx 子域名多埠配置