標籤:

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 子域名多埠配置

TAG:C | Nginx | MySQL |