易被遺忘的C/C++要點總結

C C++知識要點總結.png

一、 數據類型及運算


求補碼

  • 原碼的基礎上, 符號位不變, 其余各位取反, 最后+1
  • 原碼轉補碼不考慮符號位
  • 補碼轉原碼,符號位不參與運算
  • 取反后 + 1 == 取反前 - 1

科學計數法表示

  • 1.8 * 10^11 --> 1.8E11
  • 9.34 * 10^-3 --> 9.34E-3

相關細節

  • sizeof()是一個運算,而非函數
  • ++運算不能用在實數上
  • 判斷一個整數是否是2^n(2,4,6,8,16...)
    • !(x & (x - 1))
  • 三目條件運算符代碼更優
    • 編譯器能產生比if...else...更優的代碼

運算符優先級、結合方向規則

  • 單目 > 雙目
  • 算術 > 關系 > 位 > 邏輯 > 條件(三目)> 賦值 > 逗號
    • 算術: + - * /
    • 關系: > < >= <=
    • 位: & | ^
    • 單目: ~
    • 邏輯: && ||
    • 單目: !
  • 自右向左的三種運算符
    • 單目
    • 賦值
    • 條件

數據輸入與輸出

  • printf()語句從右向左計算輸出表達式的值
    i = 1;
    printf("%d, %d\\\\n", i++, i--);
    //res: 0,1
    //先執行i--,再執行i++

常用輸出函數

  • printf()
  • putchar()
    • 輸出一個字符
    • 必須是字符型變量或常量
  • puts()
    • 輸出一個字符串
    • 必須是字符串或常量

常用輸入函數

  • scanf()

  • gets()

    • 每次讀取一個字符串
  • getche()

    • conio.h中
    • 讀取字符不用按回車
  • getchar()

    • stdio.h中
    • 完成后須按回車
  • getche() & getchar():
    每次讀取一個字符

  • scanf() & gets()區別:
    scanf不能輸入含空格字符串,gets可以

二、選擇語句和循環語句


switch:case 常量表達式

  • 常量表達式只能為整型、字符型
  • 不允許浮點型

三、數組


定義

  • 定義數組未賦初值
    • Turbo C會給數組置0
    • VC則取隨機值
  • 定義靜態數組,則系統自動賦0

比較字符串數組中的值

  • C:     strcmp(str1,str2)
  • C++:    str1 == str2
  • JAVA:   str1.equals(str2)
    • java中,str1 == str2 比較的是地址

四、指針


指針運算

  • 指針相減:   表示兩指針所指地址之間的數據個數
  • 指針相加:   沒有意義,錯誤

數組與指針

1、一維數組首地址

    int a[10], *p;
    p = &a[0];
    p = a
    //等價,將數組首元素的首地址賦給指針p
  • 表示:

    &a[0], a:  數組首元素的首地址
    &a:      數組首地址

  • 對比:

    a == &a[0]
    a != &a    //地址值相同,含義不同

2、二維數組首地址

int a[10][10];

地址值相同,含義不同:

a:

  • 二維數組首元素首地址
  • 代表一維數組元素的首地址

&a:

  • 數組首地址

&a[0]:

  • 二維數組首元素首地址

&a[0][0]:

  • &a[0][0] != a
  • a[0] == &a[0][0]

3、二維數組指針

  • int (*p)[3]:

    • 指向含3個元素的二維數組的行指針
    • 數組每列有3個元素
  • int \p[3] & int \(p[3]):

    • 指針數組,每個元素均是一個指針

指針與引用的區別

  • 非空區別
    • 引用必須總是指向某些對象
      • 不能使用指向空值的引用
      • 不存在指向空值的引用
      • 效率比使用指針高
    • 指針可以指向空值
  • 合法性區別
    • 使用引用前,無需測試其合法性
    • 使用指針總是需要判空
  • 可修改區別
    • 指針可被重新賦值,以指向另一對象
    • 引用
      •   總指向初始化時被指定的對象
        
      •   以后都不能改變
        
      •   但指定對象的內容可以改變
        
  • 應用區別
    • 指針場景
      •   存在不指向任何對象的情況
        
      •   不同的時刻指向不同對象的情況
        
    • 引用場景
      •   指向一個對象后就不會改變指向的情況
        

ps:聲明引用 / const常量 的同時,必須初始化

函數指針

  • float(**def)[10];

    • 二級指針

    • 指向一個一維數組的指針

    • 數組元素都是float

  • double\(\gh)[10];

    • 指針gh,指向一個一維數組

    • 該數組元素的類型均為double *

  • double(*f[10])();

    • f是一個數組,含10個元素

      • 元素都是函數指針
    • 指向的函數

      •   沒有參數
        
      •   返回double類型的值
        
  • int \( (\b)[10] );

    • 和int \(\b)[10]一樣
  • Long (* fun)(int)

    • 函數指針

五、類型轉換


(int &)相關

  • float a = 1.0f;

  • (int)a實際上是以浮點數a為參數構造了一個整型數,該整數的值是1。

  • (int&)a則是告訴編譯器將a當作整數看(并沒有做任何實質上的轉換)。

unsigned int

  • unsigned int a = 0xFFFFFFF7;

  • unsigned char i = (unsigned char)a;

    •   i:  000000f7
      
  • char \*b = (char *)&a;

    •   *b: fffffff7
      

隱式類型轉換

  • 算術運算式中,低類型能夠轉換為高類型

  • 賦值運算式

    • 右邊表達式的值自動隱式轉換為左邊變量的類型,并賦值給他
  • 函數調用中參數傳遞時,系統隱式地將實參轉換為形參的類型后,賦給形參

  • 函數有返回值時,系統將隱式地將返回表達式類型轉換為返回值類型,賦值給調用函數

六、位運算相關


取兩數的平均值:

(x & y) + [(x ^ y) >> 1]

另類取兩數較大值:

  max = [(a + b) + abs(a - b)] / 2

三數取中間數:

    t1 = max(a, b);
    t2 = max(b, c);
    t3 = max(a, c);
    min( t1, min(t2, t3) )

七、函數


靜態函數:   不可被其他文件調用的函數

函數重載:

  • 參數類型不同

  • 參數個數不同

  • 對返回類型沒有要求

八、#define & const & sizeof


#define實例

* #define SEC (60 * 60 * 24 * 365)UL
* #define MIIN(A, B)    ( (A) <= (B) ? (A) : (B) )

const,#define的區別

  • const

    • 有數據類型

    • 可進行類型安全檢查

    • 可對其進行調試

  • \#define

    • 沒有數據類型

    • 僅進行字符替換,沒有類型安全檢查

    • 無法調試

  • c中const

    • 被當做一個不能被改變的普通變量
  • error

    const bufsize = 100;
    char buf[bufsize];

字節對齊

  • 數據對齊規則

    • 結構的首地址必須是結構內最寬類型的整數倍地址

    • 結構體的每一個成員起始地址必須是自身類型大小的整數倍

  • 結構體的整體大小必須可被對齊值整除

  • 結構體的整體大小必須可被本結構內的最寬類型整除

sizeof

  • 結構體或類內的靜態變量
    struct s{
        int a;
        static int b;
    };
    s ss;
    sizeof(ss)

結果:4

  • 靜態變量存放在全局數據區

  • sizeof計算棧中分配的大小

  • 任何類型指針大小相同:4(32位)

  • 對函數使用sizeof

  • 在編譯階段會被函數返回值的類型取代

  • 空類大小

    • 單繼承:1
    • 多繼承:1
    • 虛繼承:4
    • 涉及虛表(虛指針)

內聯函數 vs. 宏

  • 內聯
    • 相比普通函數: 加快程序運行速度
    • 直接嵌入目標代碼
    • 要做參數類型檢查
    • 簡單的替換
    • 不做參數類型檢查

九、 C++面向對象


1、類和對象

類對象的存儲空間

  • 只為每個對象的數據成員和函數地址分配內存空間
  • 類中所有成員函數只生成一個副本
  • 該類每個對象執行相同的函數成員

拷貝構造函數

  • 功能
    • 用一個已知的對象來初始化一個被創建的同類的對象
  • 特點
    • 函數只有一個參數,并且是對某個對象的引用
    • 每個類都必須有一個拷貝初始化構造函數
  • 格式
    • 類名::拷貝初始化構造函數名(const 類名 &引用名)

靜態成員

  • 靜態數據成員
    • 特點
      • 類的所有對象共享
      • 必須初始化,且要在類外初始化
    • 引用格式
      • 類名::靜態數據成員名
  • 靜態成員函數
    • 特點
      • 類的所有對象共享
      • 只能使用類的靜態成員和非數據成員
    • 引用格式
      • 類名::靜態成員函數名

類成員指針
const成員函數

定義: 任何不修改成員數據的函數都應聲明為const函數

原型: int GetY() const;

細節:

  • const函數想修改成員變量
    • 在相應變量定義處加上mutable
    • mutable int m_Count;

2、友元函數

定義

  • 需在類體內聲明
  • 可訪問類的私有成員
  • 不是類的成員函數

優點:    提高程序運行效率

缺點:   破壞類的封裝性和隱藏性

特點:    可以是多個類的友元

3、繼承和派生

公有繼承

  • 派生類成員函數可訪問基類中的公有成員和保護成員
  • 派生類的對象僅可訪問基類中的公有成員

派生類

  • 構造函數執行順序

    • 基類構造函數
    • 子對象類的構造函數(如果有的話)
    • 派生類構造函數
  • 析構函數執行順序

    • 派生類的析構函數
    • 基類的析構函數

虛基類

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,541評論 1 51
  • 1.面向對象的程序設計思想是什么? 答:把數據結構和對數據結構進行操作的方法封裝形成一個個的對象。 2.什么是類?...
    少帥yangjie閱讀 5,051評論 0 14
  • 題目類型 a.C++與C差異(1-18) 1.C和C++中struct有什么區別? C沒有Protection行為...
    阿面a閱讀 7,717評論 0 10
  • 一個外部依賴項是系統中的一個對象,被測試代碼與這個對象發生交互,但不能控制這個對象(不能控制這個對象返回值;不能控...
    桃子媽咪閱讀 5,807評論 2 5
  • Hello World! by Miss ? 李 學習參考 http://Dely.vip 人生沒有夢想,不就成...
    木子同學閱讀 206評論 1 1