C++筆記(3)

1.C/C++編譯器默認的類型轉換:
   
//1.
unsigned int a=1;
int b=-1;//int b——>unsigned int b=一個很大的數
char c=a>b?'a':'b';
printf("%c\n",c);//打印出'b'
//2.
unsigned short a=1;//——>int a=1;
int b=-1;
char c=a>b?'a':'b';
printf("%c\n",c);//打印出'a'
2.const在C99中和C++是一樣的;而在C89中和C++有以下的區別:
   const定義:const修飾一個變量,表示該變量從此以後,不能再作爲賦值的左值。
   在C語言中的const:
       1)不一定非得初始化。
const int a=10;
const int a;
//以上兩種編譯皆可以通過
       2)const修飾的量爲常變量,不能爲常量。
       3)不能當作常量使用,如定義數組大小。
const int a=10;
int array[a]={0};//編譯不通過
       4)常變量的編譯方式和普通變量沒有區別。
const int a=10;
int *p=(int *)&a;//*p訪問a的值
*p=20;
printf("%d%d\n",a,*p);//20,20
//a和*p的值都是從內存裏面取的
   在C++中的const:
       1)一定要初始化。
       2)const修飾的量叫常量。
       3)完全可以當作常量數字使用,比如定義數組長度。
       4)常量的編譯方式爲:在編譯過程中,把常量的名字替換成常量的值。
const int a=10;
int *p=(int *)&a;
*p=20;
printf("%d%d\n",a,*p);//10,20
       注意:以上情況都是初始值爲常量的情況
       5)如果初始值爲變量,此時C++的常量就變成C的常變量了(即等於C中的const)
int b=10;
const int a=b;//此時相當於C中的const
3.const和一級指針的結合
   (1)const修飾的是離它最近的類型(const 和多個*結合使用時,查看const右邊有幾個* ,const 修飾的是const右邊的內容。而const只有修飾*纔會參與類型)
         
            
   (2)編譯器所做的事:保證const的安全,代碼上不能有直接間接修改常量值的可能
            直接:讓常量作爲左值
const int a=10;
a=20;//錯誤,因爲常量作爲左值
            間接:泄露了常量內存的地址或引用,千萬不能泄露給一個普通的指針或普通的引用變量
const int a=10;
const int a=10;
int *p=&a;//左:int *  右:const int *//false
int *const p=&a;//錯誤,左邊是int *,右邊是const int *,即泄露給一個普通的指針
const int *p=&a;//正確,左邊是const int *,右邊是const int *,即泄露給一個const的指針
    (3)類型轉換問題:
             const與一級指針結合時,類型轉換具體如下
             const int *-->int *  c  錯誤的類型轉換
const int a=10;
int *p=&a;//左:int *  右:const int *//false
             int *-->const int *  正確的類型轉換
int a=10;//左:int  右:int
const int *p=&a;//左:const int *  右:int *//true
             const修飾一個指針時,表示所指向的那塊內存不可改,如果將它賦值給一個普通的指針,相當於給const修飾的那塊內存修改了值,這就違背了const的屬性,所以錯誤;反之,一個普通指針的內存地址是可以修改的,將它賦值給一塊固定的內存地址是正確的。
             const與二級指針結合時,類型轉換具體如下
             const int **-->int **  錯誤的類型轉換
int a=10;//int   int
const int *p=&a;//const int *     int *
int **q=&p;//int **      const int **//false
// == int *-->const int *&
            int **-->const int **  錯誤的類型轉換
int a=10;//int   int
int *p=&a;//int *     int *
const int **q=&p;//const int **      int **//false//因爲p是變量地址,不可以直接賦值
//  ==  const int *-->int *&
            以下的例子,我們可以把其看作爲一級指針的結合:
int a=10;
int *const p=&a;//int *    int *
int **q=&p;//int **     int *const *p-->*     const *//false
int a=10;
int *p=&a;//int *     int *
int *const *p=&p;//int *const *     int **-->const *    *//true
4.添加這個頭文件可以通過這個方法查看變量類型:
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
     int a = 10;
     const int b = 10;
     cout << typeid(a).name() << endl;
     cout << typeid(b).name() << endl;
     return 0;
}

5.valatile:
   對於重載來說,和const的情況是一樣的;
void func(int *a){}
void func(const int *a){}
//兩者類型不同可以重載
void func(int *a){}
void func(int *const a){}
//兩者類型相同不能重載
void func(int *a){}
void func(volatile int *a){}
//兩者類型不同可以重載
void func(int *a){}
void func(int *valatile a){}
//兩者類型相同不能重載
     但是在多線程(必須滿足三個條件:內存的可見性,原子性和一致性,以下只確保了了內存的可見性和一致性問題)中,它還有其他的含義:
   (1)保證多線程執行過程中,對線程共享變量不進行線程緩存,優點就是實時改變物理內存的值,缺點便是降低效率。
bool isThreadRunning=false;
void *threadProc(void *args)
{
    while(!isThreadRunnning){}
}
void main()
{   
    pthread_create(&tid,NULL,threadProc,(void *)args);
    isThreadRunning=true;
}
            如果在全局變量isThreadRunning前加上volatile的話,就會直接從物理內存中取得isThreadRunning的值,具有實時性。
   (2)編譯器不能對valatile修飾的變量進行指令順序的調整。
volatile bool isConfigOver=false;
//main thread
loadConfig();//加載配置
isConfigOver=true;
if(isConfigOver)
{
}
//child thread
while(!isConfigOver);//檢查系統配置已經加載完成,開始做事情
            在單線程中,指令順序的調整【發生之時:可能是代碼優化時造成指令順序的調整】不影響程序最終結果;而在多線程中,如上例,若將主線程中的isConfigOver=true;放在加載配置之前,就會影響子線程的判斷,可能就在加載配置之前就進行操作,從而沒有達到程序的要求。
   所以在多線程中,它解決了多線程緩存內存可見性問題和指令順序調整的問題。
6.引用與取地址:
int a=10;
int &b=a;//引用
&b=a;//取地址
//左邊有類型叫引用,沒類型,就叫取地址
7.引用和指針:
int a=10;
int &b=a;//引用
int *p=&a;//指針
//a,b,*p表示同一塊內存。
   指針和引用的區別:
  •    變量定義時,名字左邊有&,就是定義了一個引用變量;
  •    引用必須初始化;
  •    引用定義時,引用了哪塊內存,就永不再變,就不能再引用其他內存了;
  •    引用只能定義一級引用,不能出現二級引用,指針可以多級指針;
  •    使用引用變量,永遠訪問的是它所引用的內存(不能訪問4字節的指針內存)。
   所以,引用是更安全的指針,從彙編語言上來看,指針和引用的意義是相同的(先將引用/指針的地址取出,在該地址上進行賦值操作)。

8.指針數組,數組指針和函數指針:
                         

  


             









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章