C++ の基礎 Day 1¶
1. 最小のプログラム¶
- C++ の最小のプログラムは次のようになる。
int main()
(イント・メイン)関数は、C++ プログラムのエントリーポイント。- ここでの
int
はmain
関数がint
型の値を戻り値として返すことを示す。- 正常終了時に
0
を返すのが慣例。
- 正常終了時に
main
関数に限り、戻り値を返すreturn 0;
(リターン・ゼロ)を省略してよい。省略した場合はreturn 0;
を書いたものとみなされる。- 波括弧
{}
で囲まれた部分が、main
関数の本体。
2. 字下げスタイル¶
- C++ における字下げスタイルは次の 2 つがメジャー。
- どちらのスタイルを使ってもよいが、一貫性を持たせるべき。
オールマンスタイル¶
K&R(ケーアンドアール)スタイル¶
3. コマンドライン引数が必要な場合¶
main
関数には、コマンドライン引数を受け取るための引数を追加できる。- プログラムの中でコマンドライン引数を活用したい場合は次のように書く。
argc
(アーグシー)は、コマンドライン引数の個数を表す整数。argv
(アーグブイ)は、コマンドライン引数の値を表す文字列の配列。
コマンドライン引数を表示するプログラム
4. 標準ライブラリの利用¶
- C++ のコア言語は基本的な文法を提供する。
C++ のコア言語機能の例
int
,double
,char
などの基本的なデータ型- 基本的なデータ型に対する
+
,-
,*
,/
,++
,-=
,==
などの演算子定義 if
やfor
,switch
,int main()
, コメントなどの基本構文0
や"Hello, World!"
などのリテラルclass
,struct
,enum
など、ユーザー定義型を作るための機能[[nodiscard]]
などの属性指定子
- 複雑な処理を行うためには、標準ライブラリが提供する機能を利用する。
C++ の標準ライブラリが提供する機能の例
- 標準入出力
- 文字列操作
- 数学関数
- ファイル操作
- コンテナ(配列、リスト、マップなど)
- アルゴリズム
- スレッド
- C++ の標準ライブラリの機能は、それぞれの機能に対応した標準ライブラリヘッダ
<〇〇〇>
をインクルードすることで利用できる。 - 標準ライブラリのすべての機能は
std
(エスティーディー)名前空間で提供される。サンプルコード内ではstd::
(エスティーディー・コロンコロン)の有無で標準ライブラリの機能であるかどうかを判断できる。
std:: 付きのものが標準ライブラリの機能
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
int main()
{
int a = 42;
double d[] = { 1.0, 2.0, 3.0 };
const int b = a + 20 + sizeof(d);
if (b == 86)
{
std::cout << "Hello, World!\n";
}
std::string str = "C++!";
std::vector<int> v = { 1, 2, 3, 4, 5 };
std::cout << std::sqrt(2.0) << '\n';
}
C++23 での変更点
C++23 からは標準ライブラリがモジュールに対応し、import std;
(インポート・エスティーディー)の一行だけで標準ライブラリのすべての機能を利用できるようになる。
5. 文字列リテラル¶
- ダブルクォーテーション
" "
で囲まれた文字列は文字列リテラル。 - C 言語の文字列リテラルから仕様を引き継ぎ、実体はヌル終端された文字列を格納する
char
(チャー)型の配列である。
std::string とは無関係
文字列リテラルは C++ 標準ライブラリの文字列クラス std::string
(ストリング)とは無関係。"abc".length()
(レングス)のように、文字列リテラルで使えるメンバ関数は存在しない。
- 文字コードは実装依存。UTF-8 が多いが、日本語環境の Visual Studio では CP932(Shift_JIS の派生)がデフォルト。
本講義での設定
本講義では Visual Studio の環境構築の手順で、デフォルトの文字コード設定を UTF-8 にしている。
#include <print>
#include <cstring>
int main()
{
"Hello, World!";
"こんにちは、世界!";
""; // 空文字列(からもじれつ)
std::println("{}", std::strlen("ABC")); // 3: 文字列の長さ
std::println("{}", sizeof("ABC")); // 4: 配列のサイズ
std::println("{}", std::strlen("")); // 0: 空文字列の長さ
std::println("{}", sizeof("")); // 1: 配列のサイズ
std::println("{}", "ABC"[0]); // A
std::println("{}", "ABC"[1]); // B
std::println("{}", "ABC"[2]); // C
}
6. エスケープシーケンス¶
- 文字および文字列リテラル内で特殊な文字を表現するために、バックスラッシュ
\
で始まるエスケープシーケンスを用いる。
エスケープシーケンス | 意味 |
---|---|
\' |
シングルクォーテーション ' |
\" |
ダブルクォーテーション " |
\\ |
バックスラッシュ \ |
\t |
水平タブ |
\n |
改行 (line feed) |
\r |
キャリッジリターン (carriage return) |
\u●●●● |
16 進数 4 桁の Unicode(ユニコード)コードポイント |
\U●●●●●●●● |
16 進数 8 桁の Unicode コードポイント |
7. 文字リテラル¶
- シングルクォーテーション
' '
で囲まれた 1 文字は文字リテラル。 - 文字リテラルは
char
型の値として扱われる。 - 文字が 1 バイトに収まらない場合は不正となる。
8. Unicode 文字・文字列リテラル¶
- シングルクォーテーションやダブルクォーテーションの前にプレフィックスを付けると、Unicode に準拠した文字や文字列リテラルを表現できる。
プレフィックス | 意味 | 要素の型 |
---|---|---|
(なし) | マルチバイト文字・文字列 | char |
L |
ワイド文字・文字列 | wchar_t |
u8 |
UTF-8 文字・文字列 | char8_t |
u |
UTF-16(ユーティーエフじゅうろく)文字・文字列 | char16_t |
U |
UTF-32(ユーティーエフさんじゅうに)文字・文字列 | char32_t |
- ワイド文字列の文字コードは実装依存。Windows 環境では UTF-16, それ以外の環境では UTF-32 が多い。
- 標準入出力を含む C++ 標準ライブラリ機能の多くがマルチバイト文字のみにしか対応しないため、
u8
,u
,U
,L
を使う機会は限られる。 - 文字コードを変換する機能は標準ライブラリには用意されていない。
#include <print>
int main()
{
// マルチバイト文字列リテラル
"Hello, World!";
// ワイド文字列リテラル
L"Hello, World!";
// UTF-8 文字列リテラル
u8"Hello, World!";
// UTF-16 文字列リテラル
u"Hello, World!";
// UTF-32 文字列リテラル
U"Hello, World!";
std::println("こんにちは、世界!");
}
9. 整数リテラル¶
- 10 進数、16 進数、8 進数、2 進数の整数リテラルを表現できる。
#include <print>
int main()
{
42; // 10 進数
0x2A; // 16 進数
052; // 8 進数
0b101010; // 2 進数
std::println("{}", 42);
std::println("{}", 0x2A);
std::println("{}", 052);
std::println("{}", 0b101010);
}
- 整数リテラルは数字の間の任意の位置に
'
(アポストロフィ)を挿入して、桁区切りを表現できる。
#include <print>
int main()
{
1'000'000; // 1,000,000
0x123'456; // 0x123,456
0b1010'1010; // 0b1010,1010
std::println("{}", 1'000'000);
std::println("{}", 0x123'456);
std::println("{}", 0b1010'1010);
}
整数リテラルのサフィックス
- 値の範囲と進数とサフィックスによって、整数リテラルの型が変わる。
- 具体的には、次の各セルで最初にマッチする表現可能な型になる。
サフィックス | 10 進数 | 2/8/16 進数 |
---|---|---|
(なし) | int , long int , long long int |
int , unsigned int , long int , unsigned long int , long long int , unsigned long long int |
u または U |
unsigned int , unsigned long int , unsigned long long int |
unsigned int , unsigned long int , unsigned long long int |
l または L |
long int , long long int |
long int , unsigned long int , long long int , unsigned long long int |
ul , uL , Ul , UL , lu , lU , Lu , LU |
unsigned long int , unsigned long long int |
unsigned long int , unsigned long long int |
ll または LL |
long long int |
long long int , unsigned long long int |
ull , uLL , Ull , ULL , llu , llU , Llu , LLU |
unsigned long long int |
unsigned long long int |
10. 浮動小数点数リテラル¶
3.14
はdouble
(ダブル)型の浮動小数点数リテラル。3.14f
はfloat
(フロート)型の浮動小数点数リテラル。
11. 真偽値リテラル¶
bool
(ブール)型の真偽値リテラルはtrue
(トゥルー)とfalse
(フォルス)。
12. 標準出力¶
- C++20 までの標準出力には
<iostream>
(アイオーストリーム)ヘッダのstd::cout
(シーアウト)を使った。
#include <iostream>
int main()
{
std::cout << "Hello, World!\n";
std::cout << "1 + 1 = " << (1 + 1) << '\n';
std::cout << 3.14 << '\n';
}
- C++23 以降は
<print>
(プリント)ヘッダのstd::print
(プリント)およびstd::println
(プリントエルエヌ)を使う。 std::println
は、最後に改行を自動で付加する。
#include <print>
int main()
{
std::println("Hello, World!");
std::println("1 + 1 = {}", (1 + 1));
std::println("{}", 3.14);
}
13. 標準出力の書式指定¶
std::print
およびstd::println
のフォーマット文字列の中で、書式指定ができる。
13.1 インデックス指定¶
#include <print>
int main()
{
std::println("{2}/{1}/{0}", 2024, 12, 31);
std::println("{0}/{1}/{2}", 2024, 12, 31);
std::println("{0}{0}{0}", 11, 22, 33);
}
13.2 進数指定¶
#include <print>
int main()
{
std::println("{:#x}", 42); // 16 進数
std::println("{:x}", 42); // 16 進数
std::println("{:o}", 42); // 8 進数
std::println("{:b}", 42); // 2 進数
}
13.3 幅指定¶
#include <print>
int main()
{
std::println("{:5}", 42); // 幅 5
std::println("{:05}", 42); // 幅 5、ゼロ埋め
}
13.4 浮動小数点数の精度指定¶
#include <print>
int main()
{
std::println("{}", 123.456789);
std::println("{:.6}", 123.456789); // 6 桁
std::println("{:.4}", 123.456789); // 4 桁
std::println("{:.2}", 123.456789); // 2 桁
}
13.5 小数点以下桁数指定¶
#include <print>
#include <numbers>
int main()
{
std::println("{}", std::numbers::pi);
std::println("{:.4f}", std::numbers::pi); // 小数点以下 4 桁
std::println("{:.2f}", std::numbers::pi); // 小数点以下 2 桁
std::println("{:.0f}", std::numbers::pi); // 小数点以下 0 桁
}
13.6 「{ }」のエスケープ¶
- フォーマット文字列内で
{}
をエスケープするには{{
と}}
を使う。