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

C 與 C++ 深度解析:從標準演進到工程避坑指南

     編輯:關於C語言

1. 兄弟關係,而非父子關係

C++ 起源於 C,但不是 C 的超集,更非「升級版」。兩者由獨立標準委員會維護(C99 vs C++98),語法有交集也有分歧。無需先學 C 再學 C++,可根據項目需求直接切入。

2. 識別微軟方言

C++/CLI、C# 屬於微軟生態,與標準 C/C++ 無本質關聯。切勿混淆「編譯器擴展」與「標準語法」。

3. 編譯器選擇決定生死

  • 學習階段:唯一推薦 GCC/MinGW(如 Dev-C++ 內置)。嚴格遵循標準,暴露潛在錯誤。
  • 生產環境:MSVC、Clang 等各有優勢,但需開啟高警告等級(/W4、-Wall -Wextra -pedantic)。
  • 禁用:TC/BC/VC6 等遠古產物,不支持現代標準,語法陷阱極多。

4. 頭文件包含規範

// ✅ 標準頭文件用尖括號
#include <stdio.h>
#include <iostream>

// ❌ 雙引號包含系統頭文件(雖能通過編譯,但違背慣例)
#include "stdio.h"

5. main 函數簽名鐵律

// ✅ 標準寫法
int main(void) { ... }
int main(int argc, char *argv[]) { ... }

// ❌ 非標準
void main() { ... }
main() { ... }  // 隱式 int 在 C++ 中非法,C99 要求至少警告

6. 預編譯頭文件別外洩

#include "stdafx.h" 是 MSVC 專用預編譯產物,切勿貼在公開代碼或跨平台項目中。

7. C++ 標準頭文件現代化

舊式 (已棄用)現代標準規則
<iostream.h><iostream>C++ 專有:去 .h,進 std 命名空間
<string.h><cstring>C 兼容頭:去 .h,加 c 前綴
<stdio.h><cstdio>同上

注意:<string> (C++ string 類)、<cstring> (C 字符串函數)、<string.h> (舊式) 三者完全不同,勿混淆。

8. 字符串字面值的 const 正確性

// ❌ C++ 中非法(僅為兼容舊碼保留)
char *p = "hello";

// ✅ 正確:字符串字面值不可修改
const char *p = "hello";

const char *p 與 char const *p 等價,均指向常量字符的指針。

9. 副作用陷阱:一語句多增減

// ❌ 未定義行為:i 被修改多次且無序列點
a[i] = i++;
x = ++i + i++;

標準未規定求值順序,結果完全取決於編譯器實現。

10. 平台無關性本質

標準庫不包含 GUI、進程管理、網絡等系統相關功能。graphics.h、windows.h 均屬編譯器/平台擴展,非標準 C/C++。

11. 破除「C=DOS, C++=Windows」謬論

Linux 內核、驅動、嵌入式固件大量使用 C;高性能服務端、遊戲引擎多用 C++。語言選擇取決於領域需求,而非操作系統。

12. C++:多範式語言

除面向對象,C++ 還原生支持:

  • 過程式編程
  • 基於對象
  • 泛型編程
  • 元編程

13. 語法 ≠ 能力

掌握語法只是入場券。數據結構、演算法、工具鏈、平台 API 才是解決實際問題的關鍵。

14. 裁剪屬於你的子集

C/C++ 語法龐大復雜,建議根據項目定制「Better C」或「ADT 風格」等子集,降低認知負荷。

15. 構建領域庫生態

標準庫僅提供通用設施。汽車、航空、金融等領域均有成熟的 C/C++ 領域庫(AUTOSAR、ARINC 653 等),善用而非重造輪子。


附錄:malloc 返回值強轉爭議終結篇

C 語言:不需要、不建議、有害

// ✅ 推薦:無強轉,類型自動匹配
double *p = malloc(sizeof *p);  // sizeof 運算元可為表達式,無需類型名

// ❌ 畫蛇添足:維護噩夢
double *p = (double *)malloc(sizeof(double));

歷史緣由:C89 前無 void*,malloc 返回 char* 需強轉。C89 引入 void* 可隱式轉換為任意對象指針,強轉自此多余。

維護陷阱:若後將 double* 改為 int*,所有強轉處均需同步修改,漏改即埋 Bug。無強轉寫法 malloc(sizeof *p) 完全免疫此類問題。

C++:必須強轉

// C++ 無隱式 void* → T* 轉換
double *p = static_cast<double*>(malloc(sizeof *p));

這也是 C++ 推薦用 new/delete 或智能指針、容器的原因之一。

同理類函數

calloc、realloc、aligned_alloc 等返回 void* 的函數同理。

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