| この記事の要点 |
|
概要
C 言語は、Dennis Ritchie が 1972 年に AT&T Bell 研究所で UNIX オペレーティングシステムを実装するために設計した、静的型付きの構造化プログラミング言語です。1989 年に ANSI C(C89)として標準化され、その後 C99 / C11 / C17 / C23 と改訂されています。ソースの拡張子は .c、宣言を分離するヘッダは .h。「ハードウェアに薄い抽象を被せただけ」と評されるほど低レベルで、ポインタ・手動メモリ管理・直接的なビット演算を備えます。OS カーネル・組み込み・デバイスドライバ・他言語のランタイムが今も C で書かれています。
C++ は、Bjarne Stroustrup が 1979 年に「C with Classes」として Bell 研で開発を開始し、1985 年に「C++」と命名、1998 年に ISO 標準化(C++98)された C 言語のスーパーセットです。C との互換性を保ちつつ、クラス・オブジェクト指向・テンプレート・例外処理・RAII(Resource Acquisition Is Initialization)を追加しました。拡張子は .cpp / .cc / .cxx、ヘッダは .hpp / .h / .hxx。C++11(2011 年)が「モダン C++」の起点で、auto・ラムダ式・スマートポインタ・ムーブセマンティクスが導入されました。以降 C++14 / 17 / 20 / 23 と 3 年周期で改訂されています。
両者ともコンパイラは GCC(GNU Compiler Collection)・Clang(LLVM)・MSVC(Microsoft Visual C++)が主要 3 種。ビルド管理には伝統的な make と Makefile、現代的には CMake(クロスプラットフォーム) + Ninja(高速ビルドツール)の組み合わせが主流です。パッケージマネージャは vcpkg(Microsoft)と Conan(コミュニティ)が二大ですが、Rust の cargo や Go の go modules ほど統一されていません。
C++ で特に強力なのがテンプレート(コンパイル時ジェネリクス)です。std::vector<int> と std::vector<double> はコンパイル時にそれぞれ別の型として具象化(インスタンス化)され、Java の型消去とは対照的に実行時オーバーヘッドがゼロです。これがゼロコスト抽象の典型例です。
ファイル種類とビルド成果物
| 拡張子 | 役割 | 変換 |
|---|---|---|
.c | C ソース | 入力 |
.h | C / C++ 共用ヘッダ(宣言) | #include で展開 |
.cpp / .cc / .cxx | C++ ソース | 入力 |
.hpp / .hxx | C++ 専用ヘッダ | #include で展開 |
.o / .obj | オブジェクトファイル(中間) | コンパイル結果 |
.a / .lib | 静的ライブラリ | リンク時に取り込まれる |
.so / .dll / .dylib | 動的ライブラリ | 実行時にロード |
実行バイナリ(拡張子なし / .exe) | リンク後の最終成果物 | gcc / clang / link.exe の出力 |
ビルドフロー: main.cpp → プリプロセッサ(#include 展開)→ コンパイル → main.o → リンク(標準ライブラリ・他オブジェクトと結合)→ 実行バイナリ。複数ファイルでは各 .cpp を独立にコンパイルし、最後にリンカが結合します。
「Hello, World」
// hello.c
#include <stdio.h>
int main(void) {
printf("Hello, World\n");
return 0;
}
// hello.cpp
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> words = {"Hello", "World"};
for (const auto& w : words) {
std::cout << w << " ";
}
std::cout << "\n";
return 0;
}
$ gcc hello.c -o hello && ./hello
Hello, World
$ g++ -std=c++17 hello.cpp -o hello && ./hello
Hello World
パッケージ管理・ビルドツール
C / C++ には Rust の cargo や Go の go modules のような公式パッケージマネージャが存在しないのが弱点です。代わりに以下が広く使われます。
- CMake: クロスプラットフォームのビルド構成記述。
CMakeLists.txtから Makefile や Visual Studio プロジェクトを生成。 - Make / Ninja: 実際にビルドを走らせる実行エンジン。Ninja は CMake と組み合わせて高速化。
- vcpkg: Microsoft 製パッケージマネージャ。
vcpkg install fmtで取得。 - Conan: Python ベースのパッケージマネージャ。
conanfile.txtで依存記述。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(myapp CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(myapp main.cpp)
cmake -B build -G Ninja
cmake --build build
./build/myapp
関連言語との比較
| 項目 | C | C++ | Rust | Go |
|---|---|---|---|---|
| メモリ管理 | 完全手動 malloc/free | RAII + スマートポインタ | 所有権(コンパイル時) | GC |
| オブジェクト指向 | なし | あり(多重継承可) | trait ベース | 埋め込み + interface |
| ジェネリクス | なし(マクロで代用) | テンプレート(具象化) | ジェネリクス + trait bound | 1.18+ 型パラメータ |
| パッケージマネージャ | なし(OS パッケージ) | vcpkg / Conan(非統一) | cargo(公式統一) | go modules(公式統一) |
| 主用途 | OS / 組み込み / ドライバ | ゲーム / ブラウザ / 高性能 | システム / WASM | クラウド / サーバー |
注意点・落とし穴
- 未定義動作(Undefined Behavior, UB):配列範囲外アクセス・未初期化変数の使用・整数オーバーフロー(C++ では signed のみ)など、コンパイラが想定外の最適化を行う原因になる。
- メモリリーク・use-after-free・二重解放:手動管理ゆえの古典的バグ。C++ では
std::unique_ptr/std::shared_ptrで大幅に軽減できる。 - ヘッダの循環インクルード:
#pragma onceまたはインクルードガード(#ifndef FOO_H)が必須。 - テンプレートエラーが超長文:C++ のテンプレート展開エラーは数百行になることがある。
concept(C++20)で改善。 - ABI 非互換:コンパイラやバージョン違いで生成されたライブラリが互いにリンクできないことがある(特に C++)。C ABI は比較的安定。
- クロスプラットフォーム差異:エンディアン・整数サイズ(
longは LP64 / LLP64 で違う)・パスセパレータなど、移植時の罠が多い。
関連リンク
子ページはありません
- Python(.py / .pyc)
- JavaScript(.js / .mjs / .cjs)
- TypeScript(.ts / .tsx)
- Go(.go)
- Rust(.rs)
- Java(.java / .class / .jar)
- C / C++(.c / .h / .cpp / .hpp)
- Ruby(.rb)
- Swift(.swift)
- Kotlin(.kt / .kts)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Git pushした変更の取消し|revert・履歴変更と保護の注意点 2026-10-15 23:49:01
- Gitでローカルを戻す前に|reset・restoreの違いと退避範囲 2026-10-15 23:49:01
- Git rebaseの使い方|対象範囲・競合解決・pushの判断 2026-10-15 22:50:59
- Git pullの使い方|取込み先・ff-only・競合とstashの注意点 2026-10-15 22:50:59
- Git pushの使い方|送信先・タグ・force-with-leaseの条件 2026-10-15 22:12:47
- Git remoteの設定・確認・削除|SSH URLとfetch/pushの違い 2026-10-15 22:12:47
- Gitリモートリポジトリの作成|初回push・既存履歴・mirrorの注意 2026-10-15 15:48:16
- Gitのuser.name・user.email設定|local/global・確認と過去履歴の注意 2026-10-15 15:30:07
- LinuxにGitをインストール|配布元・初期設定・TLSと認証の確認 2026-10-15 15:30:06
- Git導入と初回push|Linuxサーバー・Windows/macOS・SSH設定 2026-10-15 14:51:54
- Db2のCREATE INDEX|索引定義・INCLUDEと実行計画の確認 2026-10-15 14:10:22
- Db2の自動採番|IDENTITY・ID取得とRESTARTの注意点 2026-10-15 14:10:22
- 【DB2】特定スキーマの全テーブルの全カラム情報を取得する方法 2026-10-15 13:53:15
- Db2のシーケンスとIDENTITYの違い|採番とカタログの確認SQL 2026-10-15 13:53:15
- Db2で複数カラムをUPDATEする方法|SET・WHEREと更新前の値 2026-10-15 13:53:15