1.C和C++區別,以及const分析(底層const/頂層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再次聲明

 

CC++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 constdefine區別

是不是感覺C++中的constdefine宏定義一樣?其實不一樣!

  • const常量:     由編譯器處理,它會對const常量進行類型檢查和作用域檢查
  • define宏定義: 由預處理器處理,直接進行文本替換,不會進行各種檢查

(預處理器是執行編譯器之前運行的程序,用來刪除注釋,宏變量轉換等)

接下來,我們以一個例子來分析constdefine

代碼如下:

#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類型,三目運算符,引用

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM