首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C/C++ 語言學習總結(一):控制流、常量、記憶體操作、sizeof 實戰

     編輯:關於C++

基礎決定上限。本文系統整理 if/for/switch/goto 最佳實踐、#define vs const、檔案拷貝/動態記憶體/strcpy/memcpy/sizeof 實戰代碼、復合表達式陷阱——這些是寫出正確、高效、可維護 C/C++ 代碼的肌肉記憶。

一、控制流黃金法則

if 判斷各類型變數的標準寫法

bool b;       if (b) / if (!b)
int i;        if (i == 0) / if (i != 0)
float f;      if (fabs(f) <= EPS)  // 絕不直接 == 0
int* p;       if (p == nullptr) / if (p)
char c;       if (c == '\0') / if (c)

if/else/return 三元簡化

if (cond) return x; else return y;  // 等價於
return cond ? x : y;

for 迴圈效能優化

  • 行優先存取:for(r) for(c) sum += a[r][c] 比列優先快(空間局部性)。
  • 提取循環不變量:if (cond) for() Do(); else for() DoOther(); 比迴圈內 if 快。
  • 寫 i < N 而非 i <= N-1:直觀且避免無符號溢位。

switch 類型限制

僅支援整數類型(int, char, long, enum),不可用 float/double/指標/字串。

goto 唯一正當用途

多層巢狀迴圈/條件的統一錯誤出口:

if (err) goto cleanup;
// ...
cleanup: release(); return err;

二、#define vs const 深度對比

維度#defineconst
類型安全無編譯器檢查
除錯可見性不可見符號表可見
作用域檔案級(無作用域)區塊/類別/命名空間
記憶體不佔存儲(純替換)可能佔存儲(可優化為立即數)

現代建議:constexpr(C++11)取代所有編譯期常量;const 修飾參數/回傳值/成員函數。

三、const 指標/引用參數完全指南


const int* p;     // 指向常數的指標,*p 不可改
int* const p;     // 常數指標,p 不可改
const int& r;     // 常數引用,綁定後不可修改被引用物件

參數傳遞決策樹:

  • 內建型別輸入:void f(int x)(值傳遞最快,無建構/解構)
  • 類別型別輸入:void f(const T& x)(避免拷貝,不可修改)
  • 輸出參數:void f(T& out) 或 void f(T* out)
  • 回傳值:const T f() 防止 f() = x 這類無意義賦值。

四、實戰代碼模板庫

動態記憶體正確/錯誤模式


// 正確:雙重指標或回傳指標
void GetMem(char** p, int n) { *p = (char*)malloc(n); }
char* GetMem2(int n) { return (char*)malloc(n); }

// 錯誤:單指標傳值,修改的是副本
void GetMem3(char* p, int n) { p = (char*)malloc(n); } // 呼叫端 p 仍為 NULL

strcpy / memcpy 手寫實現(面試必背)


char* strcpy(char* dst, const char* src) {
    if (!dst || !src) return nullptr;
    char* ret = dst;
    while ((*dst++ = *src++) != '\0');
    return ret;
}
void* memcpy(void* dst, const void* src, size_t n) {
    if (!dst || !src || n == 0) return nullptr;
    char* d = (char*)dst; const char* s = (const char*)src;
    while (n--) *d++ = *s++;
    return dst;
}

sizeof 實戰速查表(32 位系統)

運算式結果原因
sizeof(char[100])100陣列完整大小
sizeof(char*)4指標大小
char a[]="hello"; sizeof(a)6含結束符
void f(char a[100]) { sizeof(a); }4參數退化為指標
#pragma pack(1) struct {int i; char j;};5無對齊填充

五、復合表達式陷阱

  • d = (a = b + c) + r → 拆分為兩句,提升可讀性與除錯性。
  • if (a < b < c) **不是**數學連鎖比較,實為 ((a < b) < c)(布林值 0/1 再比較 c),極易出錯。

將這些模式刻入指尖,代碼評審時你就能一眼看出「這裡會越界」「那裡參數退化」「這個宏會副作用」——這就是資深工程師的直覺來源。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved