c.
「c.」の意味・「c.」とは
「c.」は、英語の略語であり、"circa"の頭文字を取ったものである。"circa"はラテン語で、「おおよそ」や「約」を意味する。したがって、「c.」は、日時や数量などを示す際に、「おおよそ」や「約」という意味を持つ。「c.」の発音・読み方
「c.」の発音は、その原語である"circa"の頭文字を取ったものであるため、「シー」と発音する。IPA表記では「si:」、日本人が発音するカタカナ英語では「シー」となる。発音によって意味や品詞が変わる単語ではないため、特に注意する必要はない。「c.」の定義を英語で解説
「c.」は、"circa"の略であり、英語での定義は"approximately"または"about"となる。これらはいずれも「おおよそ」や「約」という意味を持つ。例えば、「c. 2000」は「約2000年」という意味になる。「c.」の類語
「c.」の類語としては、「approx.」(approximatelyの略)や「abt.」(aboutの略)がある。これらも同様に、「おおよそ」や「約」という意味を持つ。「c.」に関連する用語・表現
「c.」に関連する用語としては、「B.C.」(Before Christの略、紀元前)、「A.D.」(Anno Dominiの略、西暦)などがある。これらは日時を示す際によく用いられる表現である。「c.」の例文
以下に「c.」を用いた例文を10個示す。 1. The building was constructed c. 1900.(その建物は約1900年に建設された。)2. He was born c. 1980.(彼は約1980年に生まれた。)
3. The population of this city is c. 1 million.(この都市の人口は約100万人である。)
4. The company was established c. 2000.(その会社は約2000年に設立された。)
5. The painting was created c. 17th century.(その絵画は約17世紀に描かれた。)
6. The book was published c. 1950.(その本は約1950年に出版された。)
7. The event took place c. 1800.(そのイベントは約1800年に行われた。)
8. The artifact dates back to c. 500 B.C.(その遺物は約紀元前500年にさかのぼる。)
9. The temperature is c. 30 degrees Celsius.(気温は約30度である。)
10. The distance is c. 100 kilometers.(その距離は約100キロメートルである。)
c
「c」の意味・「c」とは
「c」は、英語アルファベットの3番目の文字である。また、ローマ数字では「c」は100を表す。科学的な文脈では、「c」は光速を表す記号として広く認識されている。例えば、アルベルト・アインシュタインの特殊相対性理論では、光速は「c」と表される。「c」の発音・読み方
英語の「c」の発音は、前後の文字により異なる。一般的には、「k」のように硬い音(キー)または「s」のような柔らかい音(シー)として発音される。例えば、「cat」では「k」のように、「city」では「s」のように発音される。「c」の定義を英語で解説
"C" is the third letter in the English alphabet. In Roman numerals, "c" represents 100. In a scientific context, "c" is widely recognized as the symbol for the speed of light. For instance, in Albert Einstein's theory of special relativity, the speed of light is denoted by "c".「c」の類語
「c」の類語としては、アルファベットの他の文字が考えられる。例えば、「b」や「d」などは、「c」と同じく子音を表す文字である。また、「c」が100を表すローマ数字であるのに対し、「x」は10、「m」は1000を表す。「c」に関連する用語・表現
「c」に関連する用語としては、"century"(世紀、100年)や"cent"(セント、100分の1ドル)などがある。これらの単語は、「c」がローマ数字で100を表すことに由来する。また、"speed of light"(光速)や"celsius"(摂氏)など、科学的な文脈でよく使われる「c」を含む表現もある。「c」の例文
以下に、「c」を用いた例文を10個示す。 1. English sentence (Japanese translation): "The speed of light, denoted by 'c', is a fundamental constant in physics." (物理学において、'c'で表される光速は基本的な定数である。) 2. English sentence (Japanese translation): "In Roman numerals, 'c' stands for 100." (ローマ数字では、'c'は100を表す。) 3. English sentence (Japanese translation): "The word 'cat' starts with the letter 'c'." (「cat」は文字 'c'で始まる。) 4. English sentence (Japanese translation): "The temperature is 20 degrees Celsius." (気温は20度摂氏である。) 5. English sentence (Japanese translation): "The symbol 'c' in E=mc^2 represents the speed of light." (E=mc^2の中の 'c'は光速を表す。) 6. English sentence (Japanese translation): "Vitamin C is essential for our health." (ビタミンCは私たちの健康にとって必要不可欠である。) 7. English sentence (Japanese translation): "The 'c' in 'circle' is pronounced as 's'." ('circle'の中の 'c'は 's'のように発音される。) 8. English sentence (Japanese translation): "The Roman numeral 'c' is used in the copyright symbol ©." (著作権記号©にはローマ数字の 'c'が使われている。) 9. English sentence (Japanese translation): "The 'c' in 'ice' is silent." ('ice'の中の 'c'は発音しない。) 10. English sentence (Japanese translation): "The 'c' in 'race' is pronounced as 's'." ('race'の中の 'c'は 's'のように発音される。)シー‐シャープ【C♯】
シー‐プラス‐プラス【C++】
読み方:しーぷらすぷらす
《C++ languageとも》コンピューターのプログラミング言語の一。C言語にオブジェクト指向の拡張を施したもの。米国AT&T社が1992年に策定。C++言語。シープラプラ。
シー【C/c】
読み方:しー
3 〈C〉《(スウェーデン)Celsius》セ氏温度を表す記号。
6 〈C〉音楽の用語。
7 〈c〉《(フランス)centi-》数の単位、センチの記号。
9 〈C〉《(フランス)coulomb》電気量の単位、クーロンの記号。
10 〈©〉⇒丸(まる)シー
12 〈C〉インフルエンザウイルスの型。
13 〈C〉《complement》英文法などで、補語を示す符号。→S →V →O
ツェー【(ドイツ)C/c】
AB(C)ロール 【AB(C)rolls】
炭素(C)
アセチレンブラック
分子式: | C |
その他の名称: | 炭素【動物性,植物性】、カーボンブラックエキストラクト、Carbon black extract、Carbon、C、活性炭、Activated carbon、活性炭素、Graphitized carbon black、Carbon black、Acetylene black、せきぼく、Grapite、カーボンブラック、アセチレンブラック、黒鉛化カーボンブラック、Activeated carbon【powder】、活性炭【粒状】、Activeated carbon【granule】、活性炭【粉末】、AST-120、クレメジン、Kremezin |
体系名: | 炭素 |
ダイアモンド
システイン
英訳・(英)同義/類義語:Cys, cysteine, C , Cys , cysteien, cysteine
タンパク質を構成するアミノ酸の一種で、残基部分にSH基を持つためタンパク質分子中で立体構造の保持や活性部位として働くこともある。また、分泌タンパク質では2つのSH基が結合されてーS-S-結合を作り、タンパク質の立体構造の安定化に働く場合もある。略号はCys , C
シチジン
シトシン
補体
C
補体(Complement、略号=C)
C
C
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/10/11 13:39 UTC 版)
Cc Cc | |||||||||||||||||||||||||||||||
ラテン文字 | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Cは、ラテン文字(アルファベット)の3番目の文字。小文字は c 。ギリシア文字のΓ(ガンマ)に由来し、キリル文字のГは同系である。
キリル文字のСは別字で、ラテン文字のSに相当する文字である。
字形


大文字、小文字とも半円形ないし不完全な円である。
フラクトゥールでは正書法
その他
記号付き文字、多重音字などについて
Cの意味
学術的な記号・単位
その他の記号
商品名・作品名
符号位置
大文字
Unicode
JIS X 0213
文字参照
小文字
Unicode
JIS X 0213
文字参照
備考
C
U+0043
1-3-35
C
C
c
U+0063
1-3-67
c
c
半角
C
U+FF23
1-3-35
C
C
c
U+FF43
1-3-67
c
c
全角
Ⓒ
U+24B8
‐
Ⓒ
Ⓒ
ⓒ
U+24D2
1-12-35
ⓒ
ⓒ
丸囲み
🄒
U+1F112
‐
🄒
🄒
⒞
U+249E
‐
⒞
⒞
括弧付き
𝐂
U+1D402
‐
𝐂
𝐂
𝐜
U+1D41C
‐
𝐜
𝐜
太字
𝐶
U+1D436
‐
𝐶
𝐶
𝑐
U+1D450
‐
𝑐
𝑐
イタリック体
𝑪
U+1D46A
‐
𝑪
𝑪
𝒄
U+1D484
‐
𝒄
𝒄
イタリック体太字
𝒞
U+1D49E
‐
𝒞
𝒞
𝒸
U+1D4B8
‐
𝒸
𝒸
筆記体
𝓒
U+1D4D2
‐
𝓒
𝓒
𝓬
U+1D4EC
‐
𝓬
𝓬
筆記体太字
ℭ
U+212D
‐
ℭ
ℭ
𝔠
U+1D520
‐
𝔠
𝔠
フラクトゥール
ℂ
U+2102
‐
ℂ
ℂ
𝕔
U+1D554
‐
𝕔
𝕔
黒板太字
𝕮
U+1D56E
‐
𝕮
𝕮
𝖈
U+1D588
‐
𝖈
𝖈
フラクトゥール太字
𝖢
U+1D5A2
‐
𝖢
𝖢
𝖼
U+1D5BC
‐
𝖼
𝖼
サンセリフ
𝗖
U+1D5D6
‐
𝗖
𝗖
𝗰
U+1D5F0
‐
𝗰
𝗰
サンセリフ太字
𝘊
U+1D60A
‐
𝘊
𝘊
𝘤
U+1D624
‐
𝘤
𝘤
サンセリフイタリック
𝘾
U+1D63E
‐
𝘾
𝘾
𝙘
U+1D658
‐
𝙘
𝙘
サンセリフイタリック太字
𝙲
U+1D672
‐
𝙲
𝙲
𝚌
U+1D68C
‐
𝚌
𝚌
等幅フォント
Ⅽ
U+216D
1-3-35
Ⅽ
Ⅽ
ⅽ
U+217D
1-3-67
ⅽ
ⅽ
ローマ数字100
記号
Unicode
JIS X 0213
文字参照
名称
ᴄ
U+1D04
‐
ᴄ
ᴄ
LATIN LETTER SMALL CAPITAL C
ᶜ
U+1D9C
‐
ᶜ
ᶜ
MODIFIER LETTER SMALL C
🄲
U+1F132
‐
🄲
🄲
SQUARED LATIN CAPITAL LETTER C
🅒
U+1F152
‐
🅒
🅒
NEGATIVE CIRCLED LATIN CAPITAL LETTER C
🅲
U+1F172
‐
🅲
🅲
NEGATIVE SQUARED LATIN CAPITAL LETTER C
🄫
U+1F12B
‐
🄫
🄫
CIRCLED ITALIC LATIN CAPITAL LETTER C
他の表現法
脚注
関連項目
C Sharp
![]() C#のロゴ | |
パラダイム |
構造化プログラミング、命令型プログラミング、オブジェクト指向プログラミング、イベント駆動型プログラミング、関数型プログラミング、ジェネリックプログラミング、リフレクション、クラスベース、正格プログラミング、マルチパラダイムプログラミング ![]() |
---|---|
登場時期 | 2000年 |
設計者 | マイクロソフト(アンダース・ヘルスバーグ率いるチーム) |
開発者 |
マイクロソフト ![]() |
最新リリース | 13.0/ 2024年11月12日[a 1] |
型付け | 強い静的型付け(4.0から動的型導入) |
主な処理系 | CLR, Mono |
影響を受けた言語 |
C++、C言語、Java、Delphi、Modula-3、Cω、Eiffel、F Sharp、Haskell、Icon、J Sharp、Microsoft Visual J++、Object Pascal、Rust、ML、Visual Basic ![]() |
影響を与えた言語 | D言語, F#, Java, Nemerle, Vala, TypeScript |
プラットフォーム | Windows, macOS, Linuxなど |
ライセンス | Apacheライセンス (Roslyn) |
ウェブサイト |
docs |
拡張子 |
cs、csx ![]() |
C#(シーシャープ)は、マイクロソフトが開発した、汎用のマルチパラダイムプログラミング言語である。C#は、Javaに似た構文を持ち、C++に比べて扱いやすく、プログラムの記述量も少なくて済む。また、C#は、Windowsの.NET Framework上で動作することを前提として開発された言語であるが、2023年現在はクロスプラットフォームな.NETランタイム上で動作する。デスクトップ・モバイルを含むアプリケーション開発や、ASP.NETをはじめとするWebサービスの開発フレームワーク、ゲームエンジンのUnityでの採用事例などもある。
概要
開発にはボーランドのTurbo PascalやDelphiを開発したアンダース・ヘルスバーグを筆頭として多数のDelphi開発陣が参加している。 構文はC系言語(C言語、C++、Javaなど)の影響を受けており、その他の要素には、以前、ヘルスバーグが所属していたボーランド設計のDelphiの影響が見受けられる。また、主要言語へのasync/await構文や、ヘルスバーグが言語設計に関わるTypeScriptでのジェネリクス採用など、他言語への影響も見られる。
C#は共通言語基盤(共通言語ランタイムなど)が解釈する共通中間言語にコンパイルされて実行される。
また、C#はマルチパラダイムをサポートする汎用高レベルプログラミング言語で、静的型付け、タイプセーフ、スコープ、命令型、宣言型、関数型、汎用型、オブジェクト指向(クラスベース)、コンポーネント指向のプログラミング分野を含んでいる。他にも自動ボックス化、デリゲート、 プロパティ、インデクサ、カスタム属性、ポインタ演算操作、構造体(値型オブジェクト)、多次元配列、可変長引数、async/await構文、null安全などの機能を持つ。また、Javaと同様に大規模ライブラリ、プロセッサ・アーキテクチャに依存しない実行形態、ガベージコレクション、JITコンパイルによる実行の高速化、AOTコンパイラによる高速実行、などが実現されている(もっともこれらはC#の機能というより.NET によるものである)。
共通言語基盤 (CLI) といった周辺技術も含め、マイクロソフトのフレームワークである「.NET」の一部である。また、以前のVisual J++で「非互換なJava」をJavaに持ち込もうとしたマイクロソフトとは異なり、その多くの[注釈 1]仕様を積極的に公開し、標準化機構に託して自由な利用を許す[注釈 2]など、同社の姿勢の変化があらわれている。
.NET構想における中心的な開発言語であり、XML WebサービスやASP.NETの記述にも使用される。他の.NET系の言語でも記述可能だが、.NET APIはC#からの利用を第一に想定されており、他の.NET系言語(特に2023年以降新構文の追加なしと宣言されたVB.NET[a 2])では利用できない、あるいは将来的に利用できなくなる機能が存在する。
マイクロソフトの統合開発環境(Microsoft Visual Studio)では、Microsoft Visual C#がC#に対応している。また、Visual Studio Codeに専用のC#向け拡張(C# DevKit)を導入することでクロスプラットフォームで開発することが可能[a 3]。
共通言語仕様のCLSによって、他のCLS準拠の言語(F#やVisual Basic .NETやVisual C++ (C++/CLI) など)と相互に連携することができる。
バージョンおよびリリース時期
バージョン | 言語仕様 | リリース時期 | .NET | Visual Studio | ||
---|---|---|---|---|---|---|
ECMA[2][3] | ISO/IEC | マイクロソフト | ||||
1.0 |
ECMA-334:2003 (2002年12月) |
ISO/IEC 23270:2003 (2003年4月) |
2002年1月 | 2002年1月 | .NET Framework 1.0 | .NET (2002)[a 4] |
2003年10月 | 2003年4月 | .NET Framework 1.1[b 1] | .NET 2003[a 4][b 1] | |||
2.0 |
ECMA-334:2006 (2006年6月) |
ISO/IEC 23270:2006 (2006年9月) |
2005年9月 | 2005年11月 |
|
2005[a 4] |
3.0 | N/A | N/A | 2007年8月 | 2007年11月 | 2008[a 4] | |
4.0 | N/A | N/A | 2010年4月 | 2010年4月 | .NET Framework 4[b 3] | 2010[a 4] |
5.0 |
ECMA-334:2017 (2017年12月) |
ISO/IEC 23270:2018 (2018年12月) |
2013年6月 | 2012年8月 | .NET Framework 4.5[b 4] |
|
6.0 |
ECMA-334:2022 (2022年6月) |
N/A | Draft | 2015年7月 |
|
2015[a 4] |
7.0 |
ECMA-334:2023 (2023年12月) |
ISO/IEC 20619:2023 (2023年9月) |
N/A | 2017年3月 | .NET Framework 4.7[6] | 2017 version 15.0[a 5] |
7.1 | N/A | N/A | N/A | 2017年8月 | .NET Core 2.0[a 4] | 2017 version 15.3[a 6] |
7.2 | N/A | N/A | N/A | 2017年11月 | .NET Core 2.0[a 4] | 2017 version 15.5[a 7] |
7.3 | N/A | N/A | N/A | 2018年5月 |
|
2017 version 15.7[a 8] |
8.0 | N/A | N/A | N/A | 2019年9月 |
|
2019 version 16.3[a 9] |
9.0 | N/A | N/A | N/A | 2020年11月 | .NET 5.0[a 10] | 2019 version 16.8[a 11] |
10.0[a 12] | N/A | N/A | Proposal | 2021年12月 |
|
2022 version 17.0[a 13] |
11.0[a 14][b 6] | N/A | N/A | C# feature specifications | 2022年11月[a 15][b 6] | .NET 7.0[a 15][b 6] | 2022 version 17.4[a 15][a 16][b 6] |
12.0[a 17][a 18][b 7] | N/A | N/A | C# feature specifications | 2023年11月[a 19][b 7] | .NET 8.0[a 19][b 7] | 2022 version 17.8[a 19][a 20] |
13.0[a 21][b 8] | N/A | N/A | N/A | 2024年11月[a 1][b 8] | .NET 9.0[a 1][b 8] | 2022 version 17.12[a 1][a 22][b 8] |
言語仕様
さまざまな意味において、基盤であるCLIの機能をもっとも反映している言語であるといえる。C#にある組み込み型のほとんどは、CLIフレームワークに実装されている値型と対応している。
しかし、C#の言語仕様はコンパイラのコード生成については何も言及していないため、CLRに対応しなければならないとか、共通中間言語 (CIL) などの特定のフォーマットのコードを生成しなければならないとかいうことは述べられていない。
そのため、理論的にはC++やFORTRANのように環境依存のマシン語を生成することも可能である。しかし、現在存在するすべてのC#コンパイラはCLIをターゲットにしている。
.NET 7.0以降で可能になった事前コンパイルの一種である「Native AOT」でデプロイすることで実行可能な環境依存のバイナリを出力することが可能である。しかしながらこの手法もCLIとランタイムを事前に各アーキテクチャ向けのバイナリに変換しているだけであり、CLIを経由することに変わりはない。[a 23]
特殊な例としては、UnityのScripting Backendである「IL2CPP」[8]や「Burst」[9]がある。 IL2CPPはC#をコンパイルしたCILをさらにC++コードへと変換後、ネイティブバイナリへC++コンパイラによってコンパイルされる。BurstはC#をコンパイルしたCILをLLVMコンパイラによってネイティブバイナリへコンパイルするものである。
Hello World
最新のC#ではHello Worldを下記の通りに1行で記述できる[a 24]。
Console.WriteLine("Hello World!");
上記のコードは、コンパイラによって下記の様なコードに展開される。
using System;
namespace Wikipedia
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
次の言語機能によって実現されている。ただし、未対応の古いコンパイラを用いる場合は、省略できない。
CやC++からの改良点
C#では、CやC++と比較してさまざまな制限や改良が加えられている。また、仕様の多くはC#言語というよりは、基盤である .NET そのものに依拠している。Javaで導入された制限および改良をC#でも同様に採用しているものが多いが、C#で新たに導入された改良がのちにJavaにも同様に採用されたものもある。その例を次に挙げる。
構文や構文以外の改良点
- 外のブロックで宣言した変数と同じ名前の変数を、内のブロックで再宣言(シャドウ)してはいけない。再宣言は便利なこともあれば、混乱や曖昧のもとと主張されることもあるが、C#では禁止されている。
- C#にはブール型
bool
が存在し、while
文やif
文のように条件をとるステートメントには、bool
型の式を与えなければならない。C言語では、ブール型が無くint
型(0を偽とし、非0を真とする)に兼用させた上、(ヌルポインタを偽とみなすこととするといろいろと便利だった、ということもあり)ポインタでもwhile
文やif
文に与える式にできる、という仕様としていた。これは便利なこともあったが、本来比較式を記述すべきところで誤って代入式を記述してもコンパイル適合となってしまうなど、ミスが見逃されることもあった。C#ではミスを防止するため[要出典]に、そのような仕様ではなくブール型を独立させ、またブール型を厳密に要求する場所を多くしている。 switch
文に整数型あるいは整数型に準ずる型のみならず、文字列型string
を使用できる。case
ラベルには、整数型あるいは整数型に準ずる型の定数のみならず、文字列リテラル(文字列定数)を使用できる。- 組み込み型のサイズおよび内部表現が仕様で定められており、プラットフォームや処理系に依存しない。浮動小数点数はIEEE 754に準拠する[a 27]。文字および文字列はUTF-16エンコーディングを採用する[a 28]。
ポインタとメモリ管理
- ポインタをサポートする。ポインタは
unsafe
スコープ内のみで使用することができ、適切な権限をもつプログラムのみがunsafe
とマークされたコードを実行することができる。オブジェクトへのアクセスの大部分は管理された安全な参照によってなされ、大部分の算術演算はオーバフローのチェックがなされる。unsafe
ポインタは値型や文字列を指すことができる。セーフコードでは、必ずしもそうする必要はないものの、IntPtr
型を通してポインタをやりとりすることができる。 - マネージドなメモリを明示的に解放する方法は存在せず、参照されなくなったメモリはガベージコレクタによって自動的に解放される。ガベージコレクタは、メモリの解放忘れによって起こるメモリリークを解消する。C#は、データベース接続のようなアンマネージドなリソースに対しても明示的に制御する方法を提供している。これは
IDisposable
インタフェースとusing
ステートメントまたはusing
宣言によってなされる。
名前空間とオブジェクト指向な型システム
- 名前空間は階層構造をもつ。つまり、名前空間は他の名前空間の中に宣言することができる。
- 組み込みの値型を含めたすべての型は、
object
クラス (System.Object
) の派生型である。つまりobject
クラスのもつすべてのプロパティやメソッドを継承する。例えば、すべての型はToString()
メソッドをもつ。 - クラス (
class
) は参照型であり、構造体 (struct
) および列挙型 (enum
) は値型である。構造体はクラスよりも軽量で、C/C++との相互運用性に優れるが、派生型を定義することができない。 - クラスおよび構造体は複数のインタフェースを実装することができるが、多重継承はサポートされない。
- C#はC++に比べて型安全である。既定の暗黙変換は、整数の範囲を広げる変換や、派生クラスから基底クラスへの変換といった、安全な変換のみに限定される。これは、コンパイル時、JITコンパイル時、そして一部の動的なケースでは実行時に強制される。ブール型と整数型、列挙型と整数型、の間は暗黙変換はできない。暗黙変換をユーザー定義する際は、明示的にそのように指定しなければならない。これはC++のコンストラクタとは違った仕様である。
- C#は「Null安全」である。Null許容型、Null許容参照型を持ち、Null合体演算子などの構文・演算子を持つ。
- 列挙型のメンバーは、列挙型のスコープの中に置かれる。また、列挙型の定数名を取得することができる。さらに、列挙型の定数名から動的に定数値を得ることができる。
- アクセサの定義と利用を簡略化するためにプロパティ構文を利用できる。C++およびJavaにおけるカプセル化では、通例getter/setterアクセサとなるメンバー関数あるいはメソッドを定義して利用するが、C#ではプロパティ機能により、カプセル化を維持しつつ、あたかもフィールドを直接読み書きするような直感的な構文でオブジェクトの状態にアクセスすることができる。プロパティによってメンバーのアクセス制御やデータの正当性チェックを実行することができる。なお、イベントハンドラーに利用するデリゲートのカプセル化にはイベント構文 (
event
) が用意されている。 - ジェネリクス(総称型)の採用(C# 2.0以降)。C++のテンプレート、Javaのジェネリックスと異なりコンパイル後も型情報が保持される。また、Javaのジェネリクスと異なりプリミティブ型も型変数として使うことができる。
C# 2.0からの仕様
部分型
部分型 (Partial Type) が導入された[a 4]。以下のようにクラスや構造体の宣言にpartial
修飾子をつけることで、その宣言を分割することができる。
partial class MyClass { int a; }
partial class MyClass { int b; }
これは以下と同義である:
class MyClass { int a; int b; }
これによって、巨大なクラスを分割したり、自動生成されたコードを分離したりすることができる。partial
修飾子はすべての宣言につける必要がある。
ジェネリクス
ジェネリクスが導入された[a 4]。これは.NET Framework 2.0の機能である。クラス、構造体、インタフェース、デリゲート、メソッドに対して適用することができる。
.NETのGenericsはC++のテンプレート、あるいはJavaにおけるそれとも異なるもので、コンパイルによってではなく実行時にランタイムによって特殊化される。これによって異なる言語間の運用を可能にし、リフレクションによって型パラメーターに関する情報を取得することができる。また、where
節によって型パラメーターに制約を与えることができる。一方、C++のように型パラメーターとして式を指定することはできない。なお、ジェネリックメソッドの呼び出し時に引数によって型パラメーターが推論できる場合、型パラメーターの指定は省略できる。
[11]
静的クラス
静的クラスが導入された[a 4]。static
属性をクラスの宣言につけることで、クラスはインスタンス化できなくなり、静的なメンバーしか持つことができなくなる。
イテレータ
イテレータ#C# 2.0を参照。
yieldキーワード
yield
キーワードによるコルーチンを使うことで、イテレータの生成を楽に実装できるようになった。
匿名デリゲート
プロパティに対する個別のアクセス制御
Property Accessors
プロパティのget
もしくは set
アクセサのどちらかにアクセス修飾子を指定することでアクセス制御が別個にできるようになった[a 4]。次の例では、get
アクセサはpublic
、set
アクセサはprivate
である。
public class MyClass
{
private string status = string.Empty;
public string Status
{
get { return status; }
private set { status = value; }
}
}
Null許容型とnull結合演算子
nullを保持できる値型、Nullable
が導入された[a 4]。
int? i = 512;
i = null;
int? j = i + 500; //jはnullとなる。nullとの演算の結果はnullになる。
int?
はNullable<int>
の糖衣構文である。また、nullを保持しているNull許容型のインスタンスをボックス化しようとすると、単に空参照 (null) に変換される[a 30]。
int? x = null;
object o = x;
System.Console.WriteLine(o == null); //Trueが出力される
また、null結合演算子 (??
)が導入された。これは、null
でない最初の値を返す。
object obj1 = null;
object obj2 = new object();
object obj3 = new object();
return obj1 ?? obj2 ?? obj3; // obj2 を返す
この演算子は主にNullable
型を非Nullable
型に代入するときに使われる。
int? i = null;
int j = i ?? -1; // nullをint型に代入することはできない
その他
- 匿名メソッド[15]
- External Aliases/Namespace Aliases Qualifiers[16]
- プラグマディレクティブ/C言語の様な固定長の配列表記Fix Size Buffers[17]
C# 3.0からの仕様
varキーワード
var
キーワードが導入され、型推論を利用したローカル変数の宣言ができるようになった[a 4]。
var s = "foo";
// 上の文は右辺が string 型であるため、次のように解釈される:
string s = "foo";
// 以下に挙げる文は誤りである(コンパイルエラーとなる):
var v; // 初期化式を欠いている (型を推論する対象が存在しない)
var v = null; // 型が推論できない (曖昧である)
拡張メソッド
拡張メソッド (extension method) が導入された[a 4]。既存のクラスを継承して新たなクラスを定義することなく、新たなインスタンスメソッドを疑似的に追加定義することができる。具体的には、入れ子になっていない、非ジェネリックの静的クラス内に、this
修飾子をつけた、拡張メソッドを追加する対象の型の引数を最初に持つメソッドをまず定義する。これによって、通常の静的メソッドとしての呼び出しの他に、指定した型のインスタンスメソッドとしての呼び出しを行うことができるメソッドを作ることができる。以下に例を挙げる:
public static class StringUtil
{
public static string Repeat(this string str, int count)
{
var array = new string[count];
for (var i = 0; i < count; ++i) array[i] = str;
return string.Concat(array);
}
}
この例は、文字列(string
型のインスタンス)を指定した回数繰り返し連結したものを返すメソッド Repeat
を、既存の string
型に追加している。このメソッドは、以下のように呼び出すことができる:
// 静的メソッドとしての呼び出し
StringUtil.Repeat("foo", 4);
// 拡張メソッドとしての呼び出し
"foo".Repeat(4);
// (どちらの例も "foofoofoofoo" を返す)
また、列挙型やインタフェースなど本来メソッドの実装を持ち得ない型に、見かけ上インスタンスメソッドを追加することも可能である。以下に例を挙げる:
public enum Way
{
None, Left, Right, Up, Down
}
public static class EnumUtil
{
public static Way Reverse(this Way src)
{
switch (src)
{
case Way.Left: return Way.Right;
case Way.Right: return Way.Left;
case Way.Up: return Way.Down;
case Way.Down: return Way.Up;
default: return Way.None;
}
}
}
このメソッドは以下のように呼び出すことができる:
Way l = Way.Left;
Way r = l.Reverse(); // Way.Right
拡張メソッドは糖衣構文の一種であり、カプセル化の原則に違反するものではないが、必要な場合に限り注意して実装することがガイドラインとして推奨されている[a 31]。
部分メソッド
部分メソッドが導入された[a 4]。部分型(partial
型)内で定義された private
で、かつ戻り値が void
のメソッドに partial
修飾子をつけることでメソッドの宣言と定義を分離させることができる。定義されていない部分メソッドは何も行わず、何らエラーを発生させることもない。例えば:
partial class Class
{
partial void DebugOutput(string message);
void Method()
{
DebugOutput("Some message");
Console.WriteLine("Did something.");
}
}
上のコードにおいて Method()
を呼び出すと、Did something. と表示されるだけだが、ここで以下のコード:
partial class Class
{
partial void DebugOutput(string message)
{
Console.Write("[DEBUG: {0}] ", message);
}
}
を追加した上で Method()
を呼び出すと、[DEBUG: Some message] Did something. と表示される。
ラムダ式
ラムダ式が導入された[a 4]。この名前はラムダ計算に由来する。
以下の匿名メソッド
// iを変数としてi+1を返すメソッド
delegate (int i) { return i + 1; }
は、ラムダ式を使って次のように記述できる:
(int i) => i + 1; /* 式形式のラムダ */
//或いは:
(int i) => { return i + 1; }; /* ステートメント形式のラムダ */
ラムダ式は匿名メソッドと同様に扱えるが、式形式のラムダがExpression<TDelegate>
型として扱われた場合のみ匿名メソッドとして扱われず、コンパイラによって式木を構築するコードに変換される。匿名デリゲートが実行前にコンパイルされたCILを保持するのに対し、式木はCILに実行時コンパイル可能であるDOMのような式の木構造そのものを保持する。これはLINQクエリをSQLクエリなどに変換する際に役立つ。
以下は、3つの任意の名前の変数、整数、括弧、及び四則演算子のみで構成された式を逆ポーランド記法に変換する汎用的なコードである:
public static string ToRPN(Expression<Func<int, int, int, int>> expression)
{
return Parse((BinaryExpression) expression.Body).TrimEnd(' ');
}
private static string Parse(BinaryExpression expr)
{
string str = "";
if (expr.Left is BinaryExpression)
{
str += Parse((BinaryExpression) expr.Left);
}
else if (expr.Left is ParameterExpression)
{
str += ((ParameterExpression) expr.Left).Name + " ";
}
else if (expr.Left is ConstantExpression)
{
str += ((ConstantExpression) expr.Left).Value + " ";
}
if (expr.Right is BinaryExpression)
{
str += Parse((BinaryExpression) expr.Right);
}
else if (expr.Right is ParameterExpression)
{
str += ((ParameterExpression) expr.Right).Name + " ";
}
else if (expr.Right is ConstantExpression)
{
str += ((ConstantExpression) expr.Right).Value + " ";
}
return str + expr.NodeType.ToString()
.Replace("Add", "+")
.Replace("Subtract", "-")
.Replace("Multiply", "*")
.Replace("Divide", "/")
+ " ";
}
// 呼び出し例:
ToRPN((x, y, z) => (x + 1) * ((y - 2) / z)); // "x 1 + y 2 - z / *" を返す
オブジェクト初期化の簡略化
オブジェクトの初期化が式として簡潔に記述できるようになった。
var p = new Point { X = 640, Y = 480 };
// 上の文は次のように解釈される:
Point __p = new Point();
__p.X = 640;
__p.Y = 480;
Point p = __p;
また、コレクションの初期化も同様に簡潔に記述できるようになった。
var l = new List<int> {1, 2, 3};
var d = new Dictionary<string, int> {{"a", 1}, {"b", 2}, {"c", 3}};
// 上の文は次のように解釈される:
List<int> __l = new List<int>();
__l.Add(1);
__l.Add(2);
__l.Add(3);
List<int> l = __l;
Dictionary<string, int> __d = new Dictionary<string, int>();
__d.Add("a", 1);
__d.Add("b", 2);
__d.Add("c", 3);
Dictionary<string, int> d = __d;
但し、上のコードでは匿名の変数に便宜的に __p、__l、__d と命名している。実際はプログラマはこの変数にアクセスすることはできない。
自動実装プロパティ
プロパティをより簡潔に記述するための自動実装プロパティが導入された[a 4]。プロパティの定義に get; set;
と記述することで、プロパティの値を保持するための匿名のフィールド(プログラマは直接参照することはできない)と、そのフィールドにアクセスするためのアクセサが暗黙に定義される。また、C# 5.0 までは get;
とset;
のどちらか片方だけを記述することは出来なかったが、C# 6.0 からは get;
のみが可能。以下のコード:
public int Value { get; set; }
は、以下のようなコードに相当する動作をする:
private int __value;
public int Value
{
get { return __value; }
set { __value = value; }
}
但し、上のコードでは匿名のフィールドに便宜的に __value
と命名している。実際はプログラマはこのフィールドにアクセスすることはできない。
匿名型
一時的に使用される型を簡単に定義するための匿名型が導入された[a 4]。以下に例を挙げる:
new { Name = "John Doe", Age = 20 }
上の式は、以下の内容のクラスを暗黙に定義する。定義されたクラスは匿名であるが故にプログラマは参照できない。
public string Name { get; }
public int Age { get; }
同じ型、同じ名前のプロパティを同じ順序で並べた匿名型は同じであることが保証されている。即ち、以下のコード:
var her = new { Name = "Jane Doe", Age = 20 }
var him = new { Name = "John Doe", Age = 20 }
において、her.GetType() == him.GetType()
は true
である。
配列宣言の型省略
new
キーワードを用いた配列の宣言の際、型を省略できるようになった。匿名型の配列を宣言する際に威力を発揮する。
var a = new[] {"foo", "bar", null};
// 上の文は次のように解釈される:
string[] a = new string[] {"foo", "bar", null};
// 以下の文:
var a = new[] {"foo", "bar", 123};
// は次のように解釈されることなく、誤りとなる:
object[] a = new object[] {"foo", "bar", 123};
クエリ式
LINQ をサポートするために、クエリ式が導入された[a 4]。これは SQL の構文に類似しており、最終的に通常のメソッド呼び出しに変換されるものである。以下に例を示す:
var passedStudents =
from s in students
where s.MathScore + s.MusicScore + s.EnglishScore > 200
select s.Name;
上のコードは以下のように変換される:
var passedStudents = students
.Where(s => s.MathScore + s.MusicScore + s.EnglishScore > 200)
.Select(s => s.Name);
C# 3.0で追加された構文の多くは式であるため、より巨大な式(当然クエリ式も含まれる)の一部として組み込むことができる。旧来複数の文に分けたり、作業用の変数を用意して記述していたコードを単独の式としてより簡潔に記述できる可能性がある。
出井秀行著の『実戦で役立つ C#プログラミングのイディオム/定石&パターン』(技術評論社、2017年)という書籍ではクエリ構文よりメソッド構文を推奨しており、クエリ構文ではLINQの全ての機能を使用できるわけではないこと、メソッド呼び出しは処理を連続して読める可読性があること、メソッド呼び出しであればMicrosoft Visual Studioの強力なインテリセンスが利用できることを理由に、著者はクエリ構文をほとんど使用していないと記している。
C# 4.0からの仕様
dynamicキーワード
dynamicキーワードが導入され、動的型付け変数を定義できるようになった[a 4]。dynamic型として宣言されたオブジェクトに対する操作のバインドは実行時まで遅延される。
// xはint型と推論される:
var x = 1;
// yはdynamic型として扱われる:
dynamic y = 2;
public dynamic GetValue(dynamic obj)
{
// objにValueが定義されていなくとも、コンパイルエラーとはならない:
return obj.Value;
}
オプション引数・名前付き引数
VBやC++に実装されているオプション引数・名前付き引数が、C#でも利用できるようになった[a 4]。
public void MethodA()
{
// 第1引数と第2引数を指定、第3引数は未指定:
Console.WriteLine("Ans: " + MethodB(1, 2)); // Ans: 3 … 1 + 2 + 0となっている
// 第1引数と第3引数を指定、第2引数は未指定:
Console.WriteLine("Ans: " + MethodB(A: 1, C: 3)); // Ans: 4 … 1 + 0 + 3となっている
}
// 引数が指定されなかった場合のデフォルト値を等号で結ぶ:
public int MethodB(int A = 0, int B = 0, int C = 0)
{
return A + B + C;
}
ジェネリクスの共変性・反変性
ジェネリクスの型引数に対してin、out修飾子を指定することにより、ジェネリクスの共変性・反変性を指定できるようになった[a 4]。
IEnumerable<string> x = new List<string> { "a", "b", "c" };
// IEnumerable<T>インターフェイスは型引数にout修飾子が指定されているため、共変である。
// したがって、C# 4.0では次の行はコンパイルエラーにならない
IEnumerable<object> y = x;
C# 5.0からの仕様
- 非同期処理 (async/await)[a 4]
- 呼び出し元情報属性[a 4]
- foreach の仕様変更
非同期処理 (async/await)
C# 6.0からの仕様
- 自動実装プロパティの初期化子[a 32]
- get のみの自動実装プロパティおよびコンストラクタ代入[a 32]
- 静的 using ディレクティブ[a 32]
- インデックス初期化子[a 32]
- catch/finally での await[a 32]
- 例外フィルタ[a 32]
- 式形式のメンバー (expression-bodied members)[a 32]
- null条件演算子[a 32]
- 文字列補間(テンプレート文字列)[a 32]
- nameof 演算子[a 32]
- #pragma
- コレクションの初期化子での拡張メソッド[a 32]
- オーバーロード解決の改善[a 32]
静的 using ディレクティブ
静的 using ディレクティブを利用することで、型名の指定無しに他クラスの静的メンバーの呼び出しを行えるようになった。利用するにはusing static
の後に完全修飾なクラス名を指定する。
using static System.Math;
// ↑ソースコードの上部で宣言
class Hogehoge {
// System.Math.Pow() , System.Math.PI を修飾無しで呼び出す
double area = Pow(radius, 2) * PI;
}
例外フィルタ
catch
の後にwhen
キーワードを使用することで、処理する例外を限定することができるようになった。
try {
// ...
}
catch (AggregateException ex) when (ex.InnerException is ArgumentException) {
// ...
}
C# 7.0からの仕様
- 出力変数宣言
- パターンマッチング (is 式/switch 文)
- タプル (タプル記法/分解/値の破棄)
- ローカル関数
- 数値リテラルの改善(桁セパレータ/バイナリリテラル)
- ref戻り値、ref変数
- 非同期戻り値型の汎用化
- Expression-bodied 機能の拡充(コンストラクタ/デストラクタ/get/set/add/remove)
- Throw 式
出力変数宣言
out
引数で値を受け取る場合、その場所で変数宣言可能となった[a 33]。
total += int.TryParse("123", out var num) ? num : 0;
パターンマッチング
is 式の拡張
is
式の構文が拡張され、型の後ろに変数名を宣言できるようになった[a 33]。
拡張されたis
式はマッチした場合に宣言した変数にキャストした値を代入し、さらにtrueと評価される。
マッチしなかった場合はfalseと評価され、宣言した変数は未初期化状態となる。
void CheckAndSquare(object obj) {
// objの型チェックと同時にnumに値を代入する。
if (obj is int num && num >= 0) {
num = num * num;
}
else {
num = 0;
}
// if文の条件セクションは、ifの外側と同じスコープ
Console.WriteLine(num);
}
switch 文の拡張
switch
文のマッチ方法が拡張され、case
ラベルに従来の「定数パターン」に加え、新たに「型パターン」を指定できるようになった。
また、「型パターン」のcase
ラベルでは、when
句に条件を指定することができる。
「型パターン」を含むswitch
文では、必ずしも条件が排他的でなくなったため、最初にマッチしたcase
ラベルの処理が実行される。[a 34]
void Decide(object obj) {
switch (obj) {
case int num when num < 0:
Console.WriteLine($"{num}は負の数です。");
break;
case int num:
Console.WriteLine($"{num}を二乗すると{num * num}です。");
break;
case "B":
Console.WriteLine($"これはBです。");
break;
case string str when str.StartsWith("H"):
Console.WriteLine($"{str}はHから始まる文字列です。");
break;
case string str:
Console.WriteLine($"{str}は文字列です。");
break;
case null:
Console.WriteLine($"nullです");
break;
default:
Console.WriteLine("判別できませんでした");
break;
}
}
タプル
タプルのための軽量な構文が導入された[a 33]。従来のSystem.Tuple
クラスとは別に、System.ValueTuple
構造体が新しく追加された。
タプル記法
2個以上の要素を持つタプルのための記法が導入された。 引数リストと同様の形式で、タプルを記述できる。
// タプル記法
(int, string) tuple = (123, "Apple");
Console.WriteLine($"{tuple.Item1}個の{tuple.Item2}");
分解
多値戻り値を簡単に扱えるように、分解がサポートされた[a 33]。
var tuple = (123, "Apple");
// 分解
(int quantity, string name) = tuple;
Console.WriteLine($"{quantity}個の{name}");
分解はタプルに限らない。Deconstruct()
メソッドが定義されたクラスでも、分解を利用できる[a 33]。
以下に、DateTime
型に分解を導入する例を示す。
static class DateExt {
public static void Deconstruct(this DateTime dateTime, out int year, out int month, out int day) {
year = dateTime.Year;
month = dateTime.Month;
day = dateTime.Day;
}
}
上記のコードでDateTime
型にDeconstruct()
拡張メソッドを定義し、
// 分解
(int year, int month, int day) = DateTime.Now;
のように左辺で3つの変数に値を受け取ることができる。
値の破棄
分解、out引数、パターンマッチングで、値の破棄を明示するために_
が利用できるようになった。
破棄された値は、後で参照することはできない。
// 年と日は使わない
(_, int month, _) = DateTime.Now;
// 解析結果だけ取得し、変換された値は使わない
bool isNumeric = int.TryParse(str, out _);
switch (obj) {
// string型で分岐するが、値は使わない
case string _:
// Do something.
break;
}
ref戻り値、ref変数
ref
キーワードの使用方法が拡張された。これによって、安全な参照の使い道が広がった。
ref戻り値
戻り値の型をref
で修飾することで、オブジェクトの参照を戻り値とすることができる。
// 二つの参照引数の内、値の大きいものの参照戻り値を返す
static ref int Max(ref int left, ref int right) {
if (left >= right) {
return ref left;
}
else {
return ref right;
}
}
変数の寿命は変わらないため、メソッド終了時に破棄されるローカル変数をref戻り値とすることはできない。
static int s_count = 1;
// メンバーの参照はref戻り値になる。
static ref int ReturnMember() {
return ref s_count;
}
// ref引数はもちろんref戻り値になる。
static ref int ReturnRefParam(ref int something) {
return ref something;
}
// ローカル変数をref戻り値とすることはできない。
// static ref int ReturnLocal() {
// int x = 1;
// return ref x;
// }
ref変数
ローカル変数の型をref
で修飾することで、参照を代入することができる。
// 参照戻り値を参照変数で受け取る
ref int max = ref Max(ref x, ref y);
// limitとmaxは同じ値を参照する
ref int limit = ref max;
C# 7.1からの仕様
非同期なMainメソッド
Mainメソッドの戻り値として、Task
型、Task(int)
型が認められた[a 35]。
static Task Main()
static Task<int> Main()
default式
型推論可能な場面では、default
の型指定は省略可能となった[a 35]。
int number = default;
string name = default;
C# 7.2からの仕様
C#7.2で追加された仕様は以下の通り[a 36][a 37]。
値型の参照セマンティクス
値型におけるパフォーマンス向上を意図した複数の機能が追加された。
in参照渡し、ref readonly参照戻り値
引数にin
を指定することで、読み取り専用参照渡しを指定できる。
また、戻り値にref readonly
を指定することで、読み取り専用参照戻り値を指定できる。
これにより、構造体のコピーを避けると共に、意図しない値の変更を抑止できる。
readonly構造体
構造体宣言時にreadonly
を指定することで、真の読み取り専用構造体を定義できる。
readonly構造体の全てのフィールドはreadonly
でなければならず、this
ポインタも読み取り専用となる。
これにより、メンバーアクセス時の意図しない防御的コピーを抑止できる。
ref構造体
構造体宣言時にref
を指定することで、ヒープ領域へのコピーを防ぐ構造体がサポートされる。
ref構造体では、box化できない、配列を作成できない、型引数になることができない、など、ヒープ領域へのコピーを防ぐための厳しい制限がかかる。
この機能は、Span<T>
のような構造体をサポートするために利用され、unsafe文脈以外でのstackalloc
の利用をも可能とする。
末尾以外の場所での名前付き引数
C#4.0で追加された名前付き引数が末尾以外でも利用できるようになった。
Hogehoge(name: "John", 17);
private protected アクセス修飾子
同一アセンブリ内、かつ、継承先からのアクセス許可を表すprivate protected
アクセス修飾子が追加された。
数値リテラルの改善
十六進リテラルの0x
、二進リテラルの0b
の直後のアンダースコアが認められた。
int bin = 0b_01_01;
int hex = 0x_AB_CD;
C# 7.3からの仕様
C#7.3では以下の仕様が追加された[a 38]。
- ジェネリック型制約の種類の追加
System.Enum
,System.Delegate
unmanaged
(文脈キーワード)
unsafe class MyGenericsClass<T1,T2,T3>
where T1 : System.Enum
where T2 : System.Delegate
where T3 : unmanaged {
public MyGenericsClass(T1 enum1, T1 enum2, T2 func, T3 unmanagedValue) {
if (enum1.HasFlag(enum2)) {
func.DynamicInvoke();
}
else {
T3* ptr = &unmanagedValue;
}
}
}
ref
ローカル変数の再割り当てstackalloc
初期化子- Indexing movable fixed buffers
- カスタム
fixed
ステートメント - オーバーロード解決ルールの改善
- 出力変数宣言の利用箇所の追加
class MyOutVar {
// メンバー変数初期化子やコンストラクタ初期化子で出力変数宣言が可能
readonly int x = int.TryParse("123", out var number) ? number : -1;
}
- タプル同士の比較
(long, long) tuple = (1L, 2L);
// タプルのすべての要素間で == が比較可能
if (tuple == (1, 2)) { }
// 要素数が異なるタプル同士は比較できない。
//if (tuple == (1, 2, 3)) { }
- バッキングフィールドに対するAttribute指定
// C#7.2までは無効な指定(コンパイル自体は可能。無視される)
// C#7.3からはバッキングフィールドに対するAttribute指定と見なされる
[field: NonSerialized]
public int MyProperty { get; set; }
C# 8.0からの仕様
C# 8.0で追加された仕様は以下の通り。[a 39][18]
null許容参照型
参照型にnull許容性を指定できるようになった。参照型の型名に?
を付加した場合にnull許容参照型となる。
参照型の型名に?
を付加しない場合、null非許容参照型となる。
フロー解析レベルでのnull許容性チェックが行われる。null許容値型のNullable<T>
のような新しい型は導入されない。
null許容コンテキスト
参照型のnull許容性は、null許容コンテキストによって有効、無効の切り替えが可能である。 C#7.3以前の互換性のために、既定では無効となっている。
- Nullable コンパイルオプション: プロジェクト全体でのnull許容コンテキストを指定する
#nullable
ディレクティブ: ソースコードの部分ごとにnull許容コンテキストを指定するannotations
オプション、warnings
オプションにより、適用範囲を限定できる
null免除演算子
null許容参照型の変数名の後に !
を使用することで、フロー解析時の警告が免除される。
インタフェースの既定メンバー
インタフェースのメンバーに既定の実装を指定できるようになった。また、インタフェースに静的メンバーを持つことができるようになった。
さらに、インタフェースのメンバーにアクセシビリティを指定できるようになった。
- 既定のアクセシビリティは、従来通り
public
となる。 - 実装があるインスタンスメンバーは、既定で
virtual
となりoverride
可能である。 - 実装を
override
させないためにsealed
を指定することができる。
パターンマッチングの拡張
switch
式が追加された。
プロパティパターン、タプルパターン、位置指定パターンの追加により、再帰的なパターンマッチングが可能になった。
- switch式
- 再帰パターン
- プロパティパターン
- タプルパターン
- 位置指定パターン
非同期ストリーム
IAsyncEnumerable<T>
インタフェースを返すことで、イテレータ構文と非同期構文の共存が可能になった。
async IAsyncEnumerable<int> EnumerateAsync() {
await Task.Delay(100);
yield return 1;
await Task.Delay(100);
yield return 2;
}
await foreach
によって非同期ストリームを列挙する。
async void SpendAsync() {
await foreach (var item in EnumerateAsync()) {
Console.WriteLine(item);
}
}
範囲指定
Index
とRange
を指定できる専用構文が追加された。
Index a = 1; // new Index(1, fromEnd: false)
Index b = ^1; // new Index(1, fromEnd: true)
Range range = a..b; // new Range(start: a, end: b)
その他の仕様
- 静的ローカル関数
- null結合代入演算子
- 構造体の読み取り専用メンバー
- using 宣言
- ref構造体のDispose
- ジェネリクスを含むアンマネージ型
- 式中の
stackalloc
- 文字列補間のトークン順序の緩和
C# 9.0からの仕様
C# 9.0で追加された仕様は以下の通り。
- レコード
- プロパティのinitアクセサ
- 最上位レベルステートメント
- パターンマッチングの拡張
- new式の型推論
- 条件演算子の型推論
- 共変戻り値
- GetEnumeratorの拡張メソッド対応
- 静的匿名関数
- ラムダ式引数の破棄
- ローカル関数への属性適用
- パフォーマンスと相互運用
- ネイティブサイズの整数型(
nint
nuint
型) - 関数ポインタ(
delegate*
型) - 変数初期化フラグの抑制
- ネイティブサイズの整数型(
- コードジェネレータのサポート
- モジュール初期化子
- 部分メソッドの拡張
C# 10.0からの仕様
C# 10.0で追加された仕様は以下の通り。
- レコード構造体
- 構造体型の機能強化
- 補間された文字列ハンドラー
- global using ディレクティブ
- ファイル スコープの名前空間の宣言
- 拡張プロパティのパターン
- ラムダ式の機能強化
- const 補間文字列を許可する
- レコードの型で ToString() を封印できる
- 限定代入の機能強化
- 同じ分解で代入と宣言の両方を許可する
- メソッドで AsyncMethodBuilder 属性を許可する
- CallerArgumentExpression 属性
- 拡張 #line pragma
- 警告ウェーブ 6
C# 11.0からの仕様
C# 11.0で追加された仕様は以下の通り[a 14][b 6]。
生文字列リテラル
エスケープなどの加工を施さない文字列を3個の二重引用符で括って表現できる様になった。未加工の文字リテラルとも呼ばれる。
string logMsg = """
原因不明のエラーが発生しました。
詳細はログファイル "C:\Logs\exception.log" を確認してください。
""";
汎用属性
属性の型が型引数を持てる様になった。
// 属性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class ConverterContractAttribute<TFrom, TTo> : Attribute { }
// 使用例
[ConverterContract<byte, string>()]
[ConverterContract<sbyte, string>()]
[ConverterContract<short, string>()]
[ConverterContract<ushort, string>()]
[ConverterContract<int, string>()]
[ConverterContract<uint, string>()]
[ConverterContract<long, string>()]
[ConverterContract<ulong, string>()]
public class IntToStringConverter
{
// ...
}
パターンマッチングの拡張
リストや配列に対するパターンマッチが可能になった[a 42][b 11]。
int[] nums = new[] { 0, 1, 2, 3, 4, 5 };
if (nums is [ 0, 1, 2, .. ]) {
Console.WriteLine("配列は 0, 1, 2 から始まります。");
} else {
Console.WriteLine("配列は 0, 1, 2 から始まりません。");
}
また、Span<char>
やReadOnlySpan<char>
に対して文字列を用いたパターンマッチが可能になった。
bool CheckSignature(ReadOnlySpan<char> sig)
{
return sig is "HOGE";
}
ジェネリック型数値演算
型引数に「数値型または数値型に類似している型」である事を示す制約を付け加える機能が導入された[a 43][b 12]。また、それに呼応して下記の変更が行われた。
- 明示的な論理シフト演算子(
>>>
演算子)が追加された。 - シフト演算子の右側の引数の型に対する制限の撤廃され、
int
型以外の型を指定できる様になった。 checked
演算子のオーバーロードができる様になった。- インターフェースのメソッドに対して
static abstract
キーワード(静的抽象)とstatic virtual
キーワード(静的仮想)を指定できる様になった[a 44][a 45]。 - インターフェース内に演算子を定義できる様になった。
ジェネリック型数値演算を用いた一例を下記に示す[a 46][a 47]。
// 大抵の演算子インターフェイスは System.Numerics 内に実装されている。
using System.Numerics;
// 任意の型に対して加算を行う事ができる関数。
static T MyAdd<T>(T value1, T value2)
where T: IAdditionOperators<T, T, T> // 加算が可能な型のみを受け付ける制約。
=> value1 + value2; // + 演算子を使う事ができる。
// 上記の関数定義のみで、下記の様に加算演算が定義された型であれば、任意の型で呼び出す事ができる。
int a = MyAdd( 123, 456); // 結果:579
ulong b = MyAdd(111UL, 222UL); // 結果:333
double c = MyAdd( 1.5D, 2.1D); // 結果:3.6
その他の仕様
- UTF-8 文字列リテラル
- 文字列補間式の改行
- ファイルローカル型
- 必須メンバー
- auto-default 構造体(構造体の未初期化のフィールド変数が自動的に既定値に初期化される)
nameof
のスコープ拡張IntPtr
に別名nint
、UIntPtr
に別名nuint
が付いたref
フィールドscoped ref
変数- メソッドグループからデリゲートへの変換の改善
- 警告ウェーブ 7
C# 12.0からの仕様
C# 12.0で追加された仕様は以下の通り[a 17][b 7]。
クラスと構造体のプライマリコンストラクター
レコード型(record
)以外のクラス(class
)と構造体(struct
)でプライマリコンストラクターが使えるようになった。
class Example(string message)
{
public string Message { get; } = message;
}
コレクション式
配列、コレクション、Span<T>
などの初期化の記法が共通の記法([]
)で書けるようになった。
// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];
// Create a list:
List<string> b = ["one", "two", "three"];
// Create a span
Span<char> c = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];
スプレッド演算子
コレクション式で複数のコレクションをインライン展開できる新しい演算子(..
)が追加された。
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
// 1, 2, 3, 4, 5, 6, 7, 8, 9,
int[] single = [.. row0, .. row1, .. row2];
その他の仕様
- インライン配列
- 既定のラムダ パラメーター
- 任意の型の別名設定
ref readonly
パラメーター- 試験段階の属性
- インターセプター
C# 13.0からの仕様
C# 13.0で追加された仕様は以下の通り[a 21][b 8]。
新しいエスケープシーケンス
エスケープ文字[注釈 7]を表すエスケープシーケンスとして\e
が追加された。これに従って\x1b
の使用は非推奨となった。
暗黙的なインデックスアクセス
オブジェクト初期化子においても^
演算子を用いたアクセスが可能となった。これにより、初期化子内でも配列やリストなどの末尾から値へアクセスできる。
params
コレクション
コレクション式に対応している型であれば、引数にparams
修飾子を付けられる様になった[b 13]。
// 関数定義
void Print(string format, params IEnumerable<object> args)
{
/* ... 任意の実装 ... */
// 例えば
Console.WriteLine(format, args.ToArray());
}
// 呼び出し
int a = 2, b = 3;
Print("{0} + {1} = {2}", a, b, a + b);
その他の仕様
- メソッド グループでの自然型
- 部分プロパティ
ref
構造体のインターフェイス実装OverloadResolutionPriority
属性(オーバーロードの解決優先度を変更できる)Lock
クラスに対するlock
- イテレーター・非同期メソッド内の
ref
/unsafe
- インターセプター
- コレクション式の改善
実装
C#の言語仕様は標準化団体Ecma Internationalを通じて公開・標準化されており、第三者がマイクロソフトとは無関係にコンパイラや実行環境を実装することができる[1][19]。
コンパイラの実装
現段階で、C#コンパイラの実装は次の5つが知られている。
- マイクロソフト製
- Visual Studio 2015 以降で使用されている、.NETコンパイラプラットフォーム (コードネーム Roslyn)。ApacheライセンスのオープンソースプロジェクトでGitHubで公開されている[a 48]。Windows、macOS、Linuxで動作する。C#のコンパイラはC#、VB.NETのコンパイラはVB.NETで実装されている。以前のコンパイラと比べて、リファクタリングやIDE、スクリプティングなどへの利用が可能なAPIが公開されており、コンパイラ以外への様々な応用が可能。
- Visual Studio 2013 まで使われていた、マイクロソフトによるVisual C# コンパイラ。
- 2006年のC# 2.0当時の、マイクロソフトによるShared Source Common Language Infrastructure。共通言語基盤 (CLI) とC#コンパイラがソースコードで公開されている。
- Mono ProjectによるMono内の Mono Compiler Suite (mcs)。
- 2012年まで開発されていた、DotGNU ProjectによるPortable.NET内の the C-Sharp code compiler (cscc)。
実行環境の実装
名称
- ECMA-334 3rd/4th/5th edition によると、C# は「C Sharp」(シーシャープ)と発音し、LATIN CAPITAL LETTER C (U+0043) の後に NUMBER SIGN # (U+0023) と書く[21]。 音楽のシャープ (♯, MUSIC SHARP SIGN (U+266F)) ではなくナンバーサイン (#) を採用したのは、フォントやブラウザなどの技術的な制約に加え、ASCIIコードおよび標準的キーボードには前者の記号が存在しないためである。
- "#"接尾辞は、他の.NET言語にも使用されており、J#(Javaのマイクロソフトによる実装)、A#(Adaから)、F#(System Fなどから[22])が含まれる。また"#"接尾辞はGtk#(GTKなどのGNOMEライブラリの.NETラッパ)、Cocoa#(Cocoa (API)のラッパ)などのライブラリにも使用されている。そのほか、SharpDevelopなどの"Sharp"を冠する関連ソフトウェアも存在する。
- C#という名称の解釈として、「(A-Gで表された)直前の音を半音上げる」という音楽記号の役割に着目し、「C言語を改良したもの」を意味したのではないか、というものがある[要出典]。これは、C++の名称が「C言語を1つ進めたもの」という意味でつけられたことにも似ている。
- アンダース・ヘルスバーグは、「C#」が「C++++」(すなわち「C++をさらに進めたもの」)にみえるのが由来である、と語っている[23][24]。
脚注
注釈
出典
公式発表
- ^ a b c d “Announcing .NET 9” (英語). .NET Blog. 2024年11月30日閲覧。
- ^ “Visual Basic 言語の戦略 - Visual Basic”. Microsoft (2023年5月10日). 2023年12月23日閲覧。
- ^ “Visual Studio Code 用の C# 開発キット - Visual Studio Subscription”. Microsoft (2023年10月13日). 2023年12月23日閲覧。
- ^ a b c d e f g h i j k l m n o p q r s t u v w x y z aa “C# の歴史”. Microsoft Docs. 2019年12月12日閲覧。
- ^ “Visual Studio 2017 バージョン 15.0 リリース ノート”. Microsoft Docs. 2021年1月23日閲覧。
- ^ “Visual Studio 2017 15.3 Release Notes”. Microsoft Docs. 2018年11月12日閲覧。
- ^ “Visual Studio 2017 15.5 Release Notes”. Microsoft Docs. 2018年11月12日閲覧。
- ^ “Visual Studio 2017 15.7 Release Notes”. Microsoft Docs. 2018年8月24閲覧。
- ^ “Visual Studio 2019 Release Notes”. Microsoft Docs. 2019年9月30日閲覧。
- ^ Richard Lander (2020年11月10日). “Announcing .NET 5.0” (英語). .NET Blog. Microsoft. 2020年11月11日閲覧。
- ^ “Visual Studio 2019 Release Notes”. Microsoft Docs. 2020年11月10日閲覧。
- ^ “What's new in C# 10” (英語). docs.microsoft.com. 2022年6月28日閲覧。
- ^ “Visual Studio 2022 version 17.0 Release Notes”. docs.microsoft.com. 2022年6月28日閲覧。
- ^ a b “C# 11 の新機能”. Microsoft Learn. 2023年8月15日閲覧。
- ^ a b c “.NET 7 is Available Today” (英語). .NET Blog. 2023年8月15日閲覧。
- ^ “Visual Studio 2022 バージョン 17.4 リリース ノート”. Microsoft Learn. 2023年8月15日閲覧。
- ^ a b “C# 12 の新機能”. Microsoft Learn. 2023年12月19日閲覧。
- ^ “Announcing C# 12”. Microsoft (2023年11月14日). 2024年11月30日閲覧。
- ^ a b c “Announcing .NET 8” (英語). .NET Blog. 2023年12月19日閲覧。
- ^ “Visual Studio 2022 バージョン 17.8 リリース ノート”. Microsoft Learn. 2023年12月19日閲覧。
- ^ a b “C# 13 の新機能”. Microsoft Learn. 2024年11月30日閲覧。
- ^ “Visual Studio 2022 バージョン 17.12 リリース ノート”. Microsoft Learn. 2024年11月30日閲覧。
- ^ “Native AOT deployment overview - .NET”. Microsoft (2023年9月12日). 2023年12月23日閲覧。
- ^ “Hello World - C# の概要に関する対話型チュートリアル”. Microsoft. 2023年12月23日閲覧。
- ^ “チュートリアル: 学習しながらコードをビルドするために最上位レベルのステートメントを使用してアイデアを探索する”. Microsoft (2023年11月15日). 2024年11月30日閲覧。
- ^ “.NET プロジェクト SDK”. Microsoft (2024年10月22日). 2024年11月30日閲覧。
- ^ “2-2 変数と定数”. Microsoft Docs. 2018年11月11日閲覧。
- ^ “.NET での文字エンコード”. Microsoft Docs. 2018年11月11日閲覧。
- ^ “組み込みの参照型 - C# リファレンス - C#”. Microsoft (2023年5月10日). 2023年12月23日閲覧。
- ^ “null 許容型のボックス化 (C# プログラミング ガイド)” (pdf). Microsoft. 2008年6月2日閲覧。
- ^ “拡張メソッド (C# プログラミング ガイド)”. Microsoft Docs. 2018年11月10日閲覧。
- ^ a b c d e f g h i j k l “C# 6 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
- ^ a b c d e “C# 7.0 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
- ^ “switch (C# リファレンス)”. Microsoft Docs. 2017年9月10日閲覧。
- ^ a b “C# 7.1 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
- ^ “C# 7.2 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
- ^ Mads Torgersen (2017年11月15日). “Welcome to C# 7.2 and Span” (英語). .NET Blog. Microsoft. 2017年11月23日閲覧。
- ^ “C# 7.3 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
- ^ “C# 8.0 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
- ^ “What's new in C# 9.0”. Microsoft Docs. 2021年10月17日閲覧。
- ^ “What's new in C# 10.0”. Microsoft Docs. 2022年11月3日閲覧。
- ^ “リスト パターン”. Microsoft Learn. 2023年8月15日閲覧。
- ^ “ジェネリック型数値演算”. Microsoft Learn. 2024年5月30日閲覧。
- ^ “静的抽象および仮想メンバー”. Microsoft Learn. 2024年5月30日閲覧。
- ^ “チュートリアル: C# 11 の機能を調べる - インターフェイスの静的仮想メンバー”. Microsoft Learn. 2024年5月30日閲覧。
- ^ “IAdditionOperators<TSelf,TOther,TResult> インターフェイス”. Microsoft Learn. 2024年5月30日閲覧。
- ^ “runtime/src/libraries/System.Private.CoreLib/src/System/Numerics/IAdditionOperators.cs at 69dc5ec395749dc17434140881eb1414fc989c28 · dotnet/runtime” (英語). GitHub. Microsoft (2022年8月18日). 2024年10月16日閲覧。
- ^ “dotnet/roslyn: The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.” (英語). GitHub. Microsoft (2022年11月29日). 2024年11月30日閲覧。
個人サイト
- ^ a b c d “C# 1.0 - C# によるプログラミング入門”. 2021年1月23日閲覧。
- ^ “C# 2.0 の新機能 - C# によるプログラミング入門”. 2021年1月23日閲覧。
- ^ “C# 4.0 の新機能 - C# によるプログラミング入門”. 2021年1月23日閲覧。
- ^ “C# 5.0 の新機能 - C# によるプログラミング入門”. 2021年1月23日閲覧。
- ^ “C# 7.3 の新機能 - C# によるプログラミング入門”. 2021年1月23日閲覧。
- ^ a b c d e “C# 11.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2023年8月15日閲覧。
- ^ a b c d “C# 12.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2023年12月19日閲覧。
- ^ a b c d e “C# 13.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2024年11月30日閲覧。
- ^ “パターン マッチング - C# によるプログラミング入門”. 2023年12月23日閲覧。
- ^ “C# 9.0 の新機能 - C# によるプログラミング入門” (2020年5月9日). 2023年12月23日閲覧。
- ^ “リスト パターン”. ++C++; // 未確認飛行 C. 2023年8月15日閲覧。
- ^ “【Generic Math】 C# 11 での演算子の新機能”. ++C++; // 未確認飛行 C. 2024年5月30日閲覧。
- ^ “可変長引数 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2025年1月9日閲覧。
その他
- ^ a b Abel Avram (2009年7月29日). “誰でもC#とCLIの正式な実装が可能に”. InfoQ. 2019年12月2日閲覧。
- ^ “Standard ECMA-334”. ECMA. 2023年12月23日閲覧。
- ^ “Standard ECMA-334-archive”. 2018年11月13日時点のオリジナルよりアーカイブ。2018年11月13日閲覧。
- ^ “Using C# 3.0 from .NET 2.0”. Danielmoth.com (May 13, 2007). October 4, 2012閲覧。
- ^ “Microsoft、「.NET Framework 4.6」を正式公開”. 窓の杜 2021年1月23日閲覧。
- ^ “.NET Framework 4.7が一般公開される”. InfoQ 2021年1月23日閲覧。
- ^ “Micorsoftが.NET Core 3.0をリリース”. InfoQ 2021年1月23日閲覧。
- ^ “IL2CPP の概要 - Unity マニュアル”. Unity. 2023年12月23日閲覧。
- ^ “Burst の概要”. Unity. 2023年12月23日閲覧。
- ^ a b 高橋 2005, p. 70.
- ^ 高橋 2005, pp. 63–64.
- ^ 高橋 2005, pp. 68–70.
- ^ 高橋 2005, pp. 70, 71.
- ^ 高橋 2005, p. 68.
- ^ 高橋 2005, pp. 66, 67.
- ^ 高橋 2005, p. 71.
- ^ 高橋 2005, p. 72.
- ^ “MicrosoftがC# 8.0をリリース”. InfoQ (2019年12月10日). 2019年12月12日閲覧。
- ^ Tim Smith (2010年10月4日). “Javaと.NETの特許問題への短い紹介”. InfoQ. 2019年12月2日閲覧。
- ^ “ゲームプログラムのC#8.0/.NET対応とその未来”. CAPCOM. 2024年6月29日閲覧。
- ^ Standard ECMA-334 C# Language Specification
- ^ The A-Z of programming languages: F# | Network World
- ^ レポート:コミュニティスペシャルセッション with Anders Hejlsberg in Microsoft Developers Conference 2006
- ^ C#への期待。アンダースからの返答
参考文献
- 高橋 忍「C# 2.0の新しい言語仕様」『C MAGAZINE(2005年2月号)』第17巻第2号、ソフトバンク パブリッシング。
- 山田祥寛『独習C#』(第5版)翔泳社〈独習〉、2022年7月21日。ISBN 978-4-7981-7556-0。
関連項目
- 言語仕様
- C#の文法
- C#のデータ型
- キーワード (C#)
- 実行環境
- 開発環境
- Visual Studio
- Visual Studio Code
- JetBrains Rider - ジェットブレインズ社の.NET向け統合開発環境
- MonoDevelop - OSSの統合開発環境
- SharpDevelop - フリーの統合開発環境
- 比較
外部リンク
- C# 関連のドキュメント - はじめに、チュートリアル、リファレンス。 | Microsoft Docs - 公式ウェブサイト(日本語)
- 言語仕様
- Introduction - C# language specification | Microsoft Learn - C# 言語仕様、Microsoft Docs
- ECMA-334 - Ecma International ECMA-334 C# 言語仕様
- JIS X 3015:2008「プログラム言語C#」(日本産業標準調査会、経済産業省)
- C# Compiler | Mono Mono C# コンパイラ
C++
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/11/14 13:53 UTC 版)
![]() C++のロゴ | |
パラダイム | 手続き型プログラミング、データ抽象化、オブジェクト指向プログラミング、ジェネリックプログラミング[1] |
---|---|
登場時期 | 1983年 |
開発者 |
ビャーネ・ストロヴストルップ ![]() |
最新リリース | ISO/IEC 14882:2024/ 2024年10月19日 |
評価版リリース | ISO/IEC 14882:2026 (予定) / 2024年10月16日 |
型付け | nominative, 安全でない強い静的型付け |
主な処理系 | GCC、Clang、Microsoft Visual C++、Intel C++ Compiler、C++ Builder |
影響を受けた言語 |
C言語、Simula、ALGOL 68、CLU、ML、Ada ![]() |
影響を与えた言語 | Java、Rust、C#、C++/CLI、D言語、PHP |
ウェブサイト |
isocpp |
拡張子 | .C、 .cc、 .cpp、 .cxx、 .c++、 .h |
C++(シープラスプラス)は、汎用プログラミング言語のひとつである。派生元であるC言語の機能や特徴を継承しつつ、表現力と効率性の向上のために、手続き型プログラミング・データ抽象・オブジェクト指向プログラミング・ジェネリックプログラミングといった複数のプログラミングパラダイムが組み合わされている[1]。C言語のようにハードウェアを直接扱うような下位層向けの低水準言語としても、複雑なアプリケーションソフトウェアを開発するための上位層向け高水準言語としても使用可能である。アセンブリ言語以外の低水準言語を必要としないこと、使わない機能に時間的・空間的コストを必要としないことが、言語設計の重要な原則となっている[2][3]。
C++は、1983年にAT&Tベル研究所の計算機科学者ビャーネ・ストロヴストルップによって公開された。また様々なプラットフォームでその開発環境が導入された。1998年からISOとIECの共同で言語仕様とテンプレートライブラリの標準化が行われるようになり、その後2003年、2011年、2014年、2017年、2020年に標準規格が改訂されている。2021年時点での最新規格は「ISO/IEC 14882:2020」通称「C++20」である。
歴史
ストロヴストルップはプログラミング言語C with Classes(クラス付きのC言語)の開発を1979年に開始した。彼は大規模なソフトウェアの開発に有用な特徴をSimulaが備えていることに気がついたが、Simulaは実行速度が遅く実用的ではなかった。一方でBCPLは実行速度こそ速かったものの、大規模なソフトウェア開発を念頭に置いた場合にあまりにも低級だった。
これらの事情を鑑みて、ストロヴストルップは当時既に汎用的な言語だったC言語にSimulaの特徴を取り入れることを試みた。この取り組みにあたってはALGOL68やAda、CLU、ML等の言語の影響も受けている。最初はクラスと派生クラス、型検査機構の強化、インライン関数、デフォルト引数の機能を、Cfrontを介してC言語に追加した。1985年10月に最初の商用リリースがなされた[4]。
1983年にはC with ClassesからC++に名称を変更した。この際に、仮想関数と、関数と演算子の多重定義、参照型、const
型、ユーザー制御可能な自由領域メモリ制御、型検査機構の改良、BCPL形式の(「//
」による)行単位のコメントなどの機能が追加された。1985年には『The C++ Programming Language』の初版が出版された(邦訳『プログラミング言語C++』1988年))。この時点では公式な標準が策定されていなかったために、この本が事実上のリファレンスとなった。1989年C++のバージョン2.0として、多重継承と抽象クラス、静的メンバ関数、const
メンバ関数、protected
メンバ等の機能が追加されたものがリリースされた。1990年に『The Annotated C++ Reference Manual (ARM)』[5](邦訳『注解C++リファレンスマニュアル』[6])が出版され、将来の標準化の土台となるものを提供した。後に追加された機能にはテンプレートと例外処理、名前空間、新形式のキャスト、ブール型が含まれた。
ARMが事実上の標準として使われた時代が続いたが、標準化が進んだ。C++言語の最初の標準は1998年にISO/IEC 14882:1998として承認された。2003年の改訂版を経て、2011年にメジャーアップデートとして制定されたのがISO/IEC 14882:2011、通称「C++11」である。このバージョンは、元々、非公式に「C++0x」と呼ばれていた。2000年代中に制定され、正式に「C++09」と呼称されることを見越した仮称だったが、2000年代中には実現しなかった。2011年8月10日まで続いた最終国際投票で C++0x は全会一致で承認された。これにより C++0x と呼ばれてきた C++ の次期改正案はついに国際標準になり、C++11と呼べるようになった。また、2014年にはISO/IEC 14882:2014、通称「C++14」が策定された。2017年にはISO/IEC 14882:2017、通称「C++17」が策定された。2020年にはISO/IEC 14882:2020、通称「C++20」が策定された。
C++言語の進化に伴い、標準ライブラリもまた進化していった。C++標準ライブラリに最初に追加されたのは、従来のC言語の printf()
や scanf()
といった関数を置き換えるストリームI/Oライブラリである。また、C++98における標準ライブラリへの追加で最も重要なものはStandard Template Library (STL) である。C++11では、正規表現による検索・置換や複数スレッドでの同時実行、ハッシュテーブル・ハッシュセットの追加などさらなる拡充が続いている。
国際規格
規格出版日 | C++ 国際規格 | 非公式名称 | 対応する日本工業規格 |
---|---|---|---|
1998年9月1日 | ISO/IEC 14882:1998[7] | C++98 | ― |
2003年10月16日 | ISO/IEC 14882:2003[8] | C++03 | JIS X 3014:2003 |
2007年11月15日 | ISO/IEC TR 19768:2007[9] | C++TR1 | ― |
2011年9月1日 | ISO/IEC 14882:2011[10] | C++11 | ― |
2014年12月15日 | ISO/IEC 14882:2014[11] | C++14 | ― |
2017年12月 | ISO/IEC 14882:2017[12] | C++17 | ― |
2020年12月15日 | ISO/IEC 14882:2020[13] | C++20 | ― |
長年にわたる作業の後、ANSIとISOの合同委員会はプログラミング言語C++を1998年に標準化した (ISO/IEC 14882:1998)。1998年の標準の公式なリリースから数年間にわたって委員会は不具合の報告を続け、2003年に改訂版を出版した。2003年12月に制定された日本工業規格(現:日本産業規格)JIS X 3014:2003「プログラム言語C++」(日本産業標準調査会、経済産業省)は、ISO/IEC 14882:2003 (E) の日本語訳である。
2007年11月15日、C++ Technical Report 1 (TR1) という技術報告書(テクニカルレポート)がリリースされた。これは規格の公式な一部ではなかったが、次の版のC++に含まれると期待される、標準ライブラリへの数多くの拡張を与えた。TR1の内容は、多少の修正を加えてC++11に取り込まれている。
2011年9月1日、C++98以来初の大きな改訂となるISO/IEC 14882:2011が発行された。
2014年8月18日、ISO/IEC 14882:2014 (C++14) が投票で承認され[14]、同年12月15日に公式に出版された。
2017年12月1日、ISO/IEC 14882:2017 (C++17) が公式に発行された。
2020年9月4日、ISO/IEC 14882:2020 (C++20) が投票で承認され[15][16]、同年12月15日、ISO/IEC 14882:2020 (C++20)に公式に出版された[17]。
C++20に続いて次期改訂版となるべきISO/IEC 14882:2023 (C++23) [18]の仕様策定については、2019年末から始まったCovid-19の世界的流行により開発者同士の対面によるミーティングの開催を図ることが大変難しくなったことから[19][20][21]、仕様策定が非常に難航している状況である。
将来
C++に対しては、今もなお要望が絶えない。特にBoost C++ライブラリを開発しているBoostコミュニティはC++の方向性の決定に大きく貢献し、さらにC++標準化委員会へ改良すべき点などを意見している。現在はマルチパラダイムプログラミングをより自然に行えるようにすることに力が注がれており、たとえばBoostでは、C++の関数型プログラミングやメタプログラミングの可能性を模索している。
C++11と呼ばれている新しいバージョンのC++標準ではこれらの一部が取り込まれ、今後のC++でもさらなる追加が行われると見られている。
C++という名称
この名称はRick Mascittiの功績で、最初に使用されたのは1983年の12月である。初期の研究期間では、開発中の言語は「C with Classes」と呼ばれていた。最終名は、変数の値を一つ加算する、C言語の++
(インクリメント)演算子からの派生である。また一般的な命名規則での「+」の使用は、機能強化されたコンピュータプログラムを意味する。ストロヴストルップによれば「この名前は、C言語からの変更の革新的な本質を示している」ということである。C+は、より初期の無関係なプログラミング言語の名前である。
ストロヴストルップは著書『The C++ Programming Language』の前文で名前の起源を語り、ジョージ・オーウェルの小説『1984年』の付録から「C++」が連想されるかもしれないと付け加えている。ニュースピークという架空の言語の解説に宛てられた3つの章の中に、科学技術に関する専門用語とジャーゴンの解説に宛てられた「C vocabulary」という章がある。ニュースピークで「ダブルプラス」は最上級の修飾語である。ゆえにニュースピークで「C++」は「最も極端な専門用語またはジャーゴン」という意味になるだろう。
1992年、Rick Mascittiは名前について非公式に質問されると、彼はおふざけのつもりで命名したという旨の回答をした。彼はこの言語の正式な名称になるとは夢にも思っていなかった。
哲学
ビャーネ・ストロヴストルップは著書『C++の設計と進化(1994)』でC++を設計する際に用いたルールを述べている。
- C++はCと同等の実行効率と移植性を持つ静的に型付けされた汎用言語である。
- C++は直接的かつ包括的に複数のプログラミングスタイル(手続き型プログラミング、抽象化、オブジェクト指向、ジェネリックプログラミング)をサポートする。
- C++はもしプログラマが間違っている可能性があったとしてもプログラマに選択の余地を与える。
- C++は可能な限りC言語との互換性を持ち、C言語からスムーズに移行できる。
- C++はプラットフォームに固有な機能や汎用的でない機能の実装を避ける。
- C++は利用しない機能についてはオーバーヘッドが生じない(ゼロオーバーヘッドの原則)。
- C++は高級な実行環境を必要としない。
C++のコンパイラがどのようにコードを出力しメモリのレイアウトを決めるのかということについては『Inside the C++ Object Model』(Lippman, 1996)に記載されている。ただしコンパイラが出力するコードの仕様はコンパイラ制作者の裁量に任されている。
標準ライブラリ
1998年に施行されたANSI/ISO C++ 規格は言語仕様とライブラリの2つのパートで構成される。ライブラリ規格の大半はStandard Template Library (STL) とC言語の標準ライブラリの改良版についての内容である。標準規格以外にも様々なライブラリが数多く存在し、リンカを使用することにより、C言語/FORTRAN/Pascal/BASICのような言語を用いて作成されたライブラリを利用できる。規格外のライブラリが利用できるかどうかはコンパイラに依存する。
C++標準ライブラリはC++向けに若干の最適化が施されたC言語標準ライブラリを含んでいる。C++標準ライブラリの大部分はSTLである。 コンテナ(可変長配列やリストなど)、コンテナを配列のように扱えるようにするイテレータ、検索やソートを行うアルゴリズムといった有用なツールが提供されている。さらにmap
やmultimap
のような連想配列や、set
やmultiset
のようなソート済みコンテナも提供され、これらは全てインターフェイスに互換性がある。テンプレートを用いることにより、あらゆるコンテナ(またはイテレータで定義したシーケンス)に適用できる汎用的なアルゴリズムを記述できる。C言語と同様にライブラリの機能には#include
ディレクティブを使ってヘッダファイルを読み込むことによってアクセスする。C++には69本の標準ヘッダファイルがあるが、このうち19本については非推奨となっている。
STLは標準規格に採用される前は、ヒューレット・パッカードの(一時はシリコングラフィックスの)商用ライブラリだった。STLは標準規格の単なる一部分に過ぎず規格書にSTLという表記は見られないが、入出力ストリーム、国際化、デバッグ機能、およびC言語標準ライブラリ等の、STL以外の部分と区別するために、今でも多くの人がSTLという用語を使っている。
大半のC++コンパイラはSTLを含むC++標準ライブラリの実装を提供している。STLPortのようなコンパイラ非依存のSTLも存在する。様々な目的でC++標準ライブラリを独自に実装しているプロジェクトは他にもある。
C++の標準ライブラリは大きく次のように分けられる。多種多様な実行環境が存在することを考慮して、GUIに関するライブラリは標準に含まれていない。
- 言語サポート(実行時型情報や例外処理など)
- 診断(アサートやエラー情報[要説明])
- 汎用ユーティリティ(タプル、動的メモリ確保、スマートポインタ、メタプログラミングなど)
- 文字列および正規表現
- ロケール(国際化と地域化)
- コンテナ(データ構造)、イテレータ、アルゴリズム(いわゆるSTL)
- 数値演算
- 入出力
- アトミック演算(不可分操作) - C++11以降
- スレッド - C++11以降
- 疑似乱数エンジン - C++11以降
外部ライブラリ
以下に、C++で広く使われていると思われる[独自研究?]ライブラリを挙げる。
- Boost C++ライブラリ
- 様々なC++汎用ライブラリの集合。正規表現を扱うBoost.Regexや無名関数(ラムダ計算)を簡潔に記述できるBoost Lambda Libraryなどがある。C++11やC++14などでも、Boostに存在するライブラリが標準ライブラリに採用されたり、標準ライブラリとして提案された項目がBoostで先行して実装されたりしている。これにより、実際に実装・使用することでの知見が得られ、標準ライブラリとして採用される際に活かされている。
- Apache Xerces
- C++での主要XMLパーサの一つ。Java版も存在する。
- CppUnit
- C++でのユニットテストフレームワーク。 クラス毎の動作確認に威力を発揮する。
特徴
C言語に、オブジェクト指向プログラミングをはじめとする様々なプログラミングパラダイムをサポートするための改良が加えられたものといえる。ただし、他のプログラミング言語と違い、旧来のCと同様に手続き型言語としても扱えるという特徴がある。また、C言語と比べて型チェックが厳しくなっており、型安全性が向上している。このことから、C++をbetter Cというふうに呼ぶことがある。すなわち、基本的にC言語に対して上位互換性がある。初期のC++はCへのトランスレータとして実装され、C++プログラムを一旦Cプログラムに変換してからコンパイルしていた。
ただし、C++という名称が定まった当初の時期から、C言語とC++との間には厳密な互換性はない[22][23]。当時、Cとの互換性について議論の末、「C++とANSI Cの間には不正当な非互換性はない」という合意が形成されることとなった。そのため、正当な非互換性を巡って多くの議論が発生した[24]。ただし、まだANSIによるC言語の標準規格も策定途中の時期である。
その後、先祖であるC言語のANSIによる標準規格制定時には、関数のプロトタイプ宣言やconst
修飾など、C++の機能がC言語に取り入れられることにもなった。C99の出現により、//
コメントなどのC++で使われていた便利な機能が加わってCとC++の互換性が高まる一方、別々に審議し、別の時期に発行していることと、開発対象が必ずしも同じでないために利害関係者が異なることによる違いもある[要出典]。
C++はCにクラスのサポートを追加しただけでなく、さらに次のような多種多様な機能を持っており、言語仕様は大変複雑である。言語処理系すなわちコンパイラの実装も、Cなどと比べて難易度が非常に高い。
ここから、よりオブジェクト指向を強化し、「なんでもあり」ではない代わりにシンプルで分かりやすくスマートな設計を目指した新たな言語(JavaやD言語など)が作られることとなった。
Hello, World!
![]() | この節のサンプルは編集しないでください。詳細は編集コメントを参照してください。 |
C++はC言語およびそのプリプロセッサの構文をほぼ継承している。以下のサンプルはビャーネ・ストロヴストルップの書籍「The C++ Programming Language, 4th Edition」(ISBN 978-0321563842) の「2.2.1 Hello, World!」に記載されている標準C++ライブラリのストリーム機能を用いて標準出力に出力するHello worldプログラムである[25][※ 1]。
#include <iostream>
int main()
{
std::cout << "Hello, World!\n";
}
書籍でも明記されているが、main()
関数で意図的に返り値を返さない手法が使用されている。
演算子と演算子のオーバーロード
C++には、四則演算、ビット演算、論理演算、比較演算、メンバーアクセスなどの30を超える演算子がある[26]。メンバーアクセス演算子 (.
と.*
) のような一部の例外はあるが、大半の演算子はユーザー定義によるオーバーロードが可能である。オーバーロード可能な演算子が豊富に揃えられているため、C++を一種のドメイン固有言語として利用できる。またオーバーロード可能な演算子はスマートポインタや関数オブジェクトのような組み込み型の機能を模倣したユーザー定義クラスの実装や、テンプレートメタプログラミングのような先進的な実装テクニックに欠かせないものとなっている。演算子をオーバーロードしても演算の優先順位は変化せず、また演算子のオペランドの数も変化しない。ただし指定したオペランドが無視される可能性はある。
テンプレート
C++には、ジェネリックプログラミングを実現する機能としてテンプレートが存在する。テンプレートにできる対象は、関数とクラスである。C++14以降では変数もテンプレートの対象となった。テンプレートはコード中の型および定数をパラメータ化できる。テンプレートのパラメータ(テンプレート仮引数)に、型、コンパイル時定数またはその他のテンプレート(テンプレート実引数)を与えることで、テンプレートはコンパイル時にインスタンス化(実体化・具現化などとも)される。コンパイラは関数やクラスをインスタンス化するために、テンプレート仮引数をテンプレート実引数に置き換える。テンプレートはジェネリックプログラミング、テンプレートメタプログラミング、コード最適化などのために利用される強力なツールであるが、一定のコストを伴う。各テンプレートのインスタンスはテンプレート仮引数毎にテンプレートコードのコピーを生成するためコードサイズが肥大化する。これはコンパイル時に実型引数の情報を削除することで単一の型インスタンスを生成するランタイム型のジェネリクスを実装したJavaなどの言語とは対照的である。なお、C# (.NET Framework) は実行時コンパイラにより実型引数の情報を削除することなく複数の型インスタンスを生成する方式を採用しており、C++とJavaの中間的なアプローチとなっている。
テンプレートとプリプロセッサマクロはいずれもコンパイル時に処理される言語機能であり、静的な条件に基づいたコンパイルが行われるが、テンプレートは字句の置き換えに限定されない。テンプレートはC++の構文と型を解析し、厳密な型チェックに基づいた高度なプログラムの流れの制御ができる。マクロは条件コンパイルに利用できるが、新しい型の生成、再帰的定義、型の評価などは行えないため、コンパイル前のテキストの置き換えや追加・削除といった用途に限定される。つまりマクロは事前に定義されたシンボルに基づいてコンパイルの流れを制御できるものの、テンプレートとは異なり独立して新しいシンボルを生成することはできない。テンプレートは静的な多態(下記参照)とジェネリックプログラミングのためのツールである。
C++のテンプレートはコンパイル時におけるチューリング完全なメカニズムである。これはテンプレートメタプログラミングを用いて実行する前にコンピュータが計算可能なあらゆる処理を表現できることを意味している。
概略すれば、テンプレートはコードの記述に本来必要な型や定数を明確にすることなく抽象的な記述ができる、パラメータ化された関数またはクラスである。テンプレート仮引数に実引数を与えてインスタンス化した結果は、テンプレート仮引数に指定した型に特化した形で記述されたコードと全く等価になる。これによりテンプレートは、汎用的かつおおまかに記述された関数およびクラス(テンプレート)と、特定の型に特化した実装(インスタンス化されたテンプレート)の依存関係を解消し、パフォーマンスを犠牲にすることなく抽象化できる手段を提供する。
オブジェクト
C++はC言語にオブジェクト指向プログラミングをサポートするための改良を加えたものといえる。C++のクラスには、オブジェクト指向言語で一般的な抽象化、カプセル化、継承、多態の4つの機能がある。オブジェクトは実行時に生成されるクラスの実体である。クラスは実行時に生成される様々なオブジェクトのひな形と考えることができる。
なお、C++はSmalltalkなどに見られるメッセージ転送の概念によるオブジェクト指向を採用していない。
カプセル化
カプセル化とは、データ構造を保証し、演算子が意図したとおりに動作し、クラスの利用者が直感的に使い方を理解できるようにするためにデータを隠蔽することである。クラスや関数はC++の基礎的なカプセル化のメカニズムである。クラスのメンバはpublic
、protected
、private
のいずれかとして宣言され明示的にカプセル化できる。publicなメンバはどの関数からでもアクセスできる。privateなメンバはクラスのメンバ関数から、またはクラスが明示的にアクセス権を与えたフレンド関数からアクセスできる。protectedなメンバはクラスのメンバおよびフレンド関数に加えてその派生クラスのメンバからもアクセスできる。
オブジェクト指向では原則としてクラスのメンバ変数にアクセスする全ての関数はクラスの中にカプセル化されなければならない。C++ではメンバ関数およびフレンド関数によりこれをサポートするが、強制はされない。プログラマはメンバ変数の一部または全体をpublicとして定義でき、型とは無関係な変数をpublicな要素として定義できる。このことからC++はオブジェクト指向だけでなく、モジュール化のような機能分割のパラダイムもサポートしているといえる。
一般的には、全てのデータをprivateまたはprotectedにして、クラスのユーザに必要最小限の関数のみをpublicとして公開することがよい習慣であると考えられている。このようにしてデータの実装の詳細を隠蔽することにより、設計者はインターフェイスを変更することなく後日実装を根本から変更できる[27] [28]。
継承
継承を使うと他のクラスの資産を流用できる。基底クラスからの継承はpublic
、protected
、private
のいずれかとして宣言する。このアクセス指定子により、派生クラスや全く無関係なクラスが基底クラスのpublicおよびprotectedメンバにアクセスできるかどうかを決定できる。普通はpublic継承のみがいわゆる派生に対応する。残りの二つの継承方法はあまり利用されない。アクセス指定子を省略した場合、構造体はpublic継承になるのに対し、クラスではprivate継承になる。基底クラスをvirtual
として宣言することもできる。これは仮想継承と呼ばれる。仮想継承は基底クラスのオブジェクトが一つだけ存在することを保証するものであり、多重継承の曖昧さの問題を避けることができる。
多重継承はC++の中でもしばしば問題になる機能である。多重継承では複数の基底クラスから一つのクラスを派生できる。これにより継承関係が複雑になる。例えばFlyingCat
クラスはCat
クラスとFlyingMammal
クラスから派生できる。JavaやC#では、基底クラスの数を一つに制限する一方で、複数のインターフェイスを実装でき、これにより制約はあるものの多重継承に近い機能を実現できる(実装の多重継承ではなく型の多重継承)。インターフェイスはクラスと異なり抽象メソッド(純粋仮想関数)を宣言できるのみであり、関数の実装やフィールド(メンバ変数)は定義できない。JavaとC#のインターフェイスは、C++の抽象基底クラスと呼ばれる純粋仮想関数宣言のみを持つクラスに相当する。JavaやC#の継承モデルを好むプログラマは、C++において実装の多重継承は使わず、実装の継承は単一継承に絞り、抽象基底クラスによる型の多重継承のみを使うポリシーを採用することもできる。
多態
多態 (ポリモーフィズム) は様々な場面で多用されている機能である。多態により、状況や文脈に応じてオブジェクトに異なる振る舞いをさせることができる。逆に言うと、オブジェクト自身が振る舞いを決定することができる。
C++は静的な多態と動的な多態の両方をサポートする。コンパイル時に解決される静的な多態は柔軟性に劣るもののパフォーマンス面で有利である。一方、実行時に解決される動的な多態は柔軟性に優れているもののパフォーマンス面で不利である。
静的な多態
関数のオーバーロードは名称が同じ複数の関数を宣言できる機能である。ただし引数は異なっていなければならない。個々の関数は引数の数や型の順序で区別される。同名の関数はコードの文脈によってどの関数が呼ばれるのかが決まる。関数の戻り値の型で区別することはできない。
関数を宣言する際にプログラマはデフォルト引数を指定できる。関数を呼び出すときに引数を省略した場合はデフォルト引数が適用される。関数を呼び出すときに宣言よりも引数の数が少ない場合は、左から右の順で引数の型が比較され、後半部分にデフォルト引数が適用される。たいていの場合は一つの関数にデフォルト引数を指定するよりも、引数の数が異なる関数をオーバーロードする方が望ましい。
C++のテンプレートでは、より洗練された汎用的な多態を実現できる。特にCuriously Recurring Template Patternにより仮想関数のオーバーライドをシミュレートした静的な多態を実装できる。C++のテンプレートは型安全かつチューリング完全であるため、テンプレートメタプログラミングによりコンパイラに条件文を再帰的に解決させて実行コードを生成させることにも利用できる。
動的な多態
派生
基底クラスへのポインタおよび参照は、正確に型が一致するオブジェクトだけでなく、その派生クラスのオブジェクトを指すことができる(リスコフの置換原則)。これにより、複数の異なる派生型を、同一の基底型で統一的に扱うことが可能となる。また、基底型へのポインタの配列やコンテナは、複数の異なる派生型へのポインタを保持できる。派生オブジェクトから基底オブジェクトへの変換(アップキャスト)では、リスコフの置換原則により、明示的なキャストは必要ない。
dynamic_cast
は基底オブジェクトから派生オブジェクトへの変換(ダウンキャスト)を実行時に安全に行うための演算子である。この機能は実行時型情報 (RTTI) に依存している。あるオブジェクトが特定の派生型のオブジェクトであることがあらかじめ分かっている場合はstatic_cast
演算子でキャストすることもできる。static_cast
は純粋にコンパイル時に解決されるため動作が速く、またRTTIを必要としない。また、static_cast
は従来のC言語形式のキャスト構文と違い継承階層のナビゲーションをサポートするため、多重継承した場合もメモリレイアウトを考慮したダウンキャストを実行することができる。ただし、static_cast
では多重継承において継承関係を持たない基底型同士のキャスト(クロスキャスト)を実行することはできず、dynamic_cast
を用いる必要がある。とはいえ、ダウンキャストやクロスキャストが必要となる場合、通例そのプログラムの設計に問題があることが多く、本来は仮想関数のオーバーライドによる多態を用いるべきである。
仮想関数
クラスのメンバー関数をvirtual
キーワードで修飾することにより、派生クラスでオーバーライド(再定義)することが可能な仮想関数 (virtual function) となる。仮想関数は「メソッド」と呼ばれることもある[29]。派生クラスにて、基底クラスの仮想関数と名前および引数の数や型の順序が同じ関数を定義することでオーバーライドする(C++11以降では、override
キーワードにより修飾することでオーバーライドを明示することもできる)。基底クラスの仮想関数を派生クラスでオーバーライドした場合、実際に呼び出される関数はオブジェクトの型によって決定される。基底クラスのポインタのみが与えられた場合、コンパイラはオブジェクトの型をコンパイル時に特定できず正しい関数を呼び出せないため、実行時にこれを特定する。これをダイナミックディスパッチと呼ぶ。仮想関数により、オブジェクトに割り当てられた実際の型に従って、最上位の派生クラスで実装した関数が呼び出される。一般的なC++コンパイラは仮想関数テーブルを用いる。オブジェクトの型が判明している場合はスコープ解決演算子を利用して仮想関数テーブルを使わないようにバイパスすることもできるが、一般的には実行時に仮想関数の呼び出しを解決するのが普通である。
通常のメンバー関数に加え、オーバーロードした演算子やデストラクタも仮想関数にできる。原則的にはクラスが仮想関数を持つ場合はデストラクタも仮想関数にすべきである。コンストラクタやその延長線上にあるコピーコンストラクタはコンパイルされた時点でオブジェクトの型が確定しないため仮想関数にできない。しかし、派生オブジェクトへのポインタが基底オブジェクトへのポインタとして渡された場合に、そのオブジェクトのコピーを作らなければならない場合は問題が生じる。このような場合はclone()
関数(またはそれに準じる物)を仮想関数として作成するのが一般的な解決方法である。clone()
は派生クラスのコピーを生成して返す。
= 0
をメンバー関数宣言の末尾セミコロンの直前に挿入することにより、メンバー関数を純粋仮想関数 (pure virtual function) にできる。純粋仮想関数を持つクラスは純粋仮想クラスと呼ばれ、このクラスからオブジェクトを生成することはできない。このような純粋仮想クラスは基底クラスとしてのみ利用できる。派生クラスは純粋仮称関数を継承するため、派生クラスのオブジェクトを生成したい場合は全ての純粋仮想関数をオーバーライドして実装しなければならない。純粋仮想関数を持つクラスのオブジェクトを生成しようと試みるようなプログラムは行儀が悪い。
テンプレート
型消去 (type erasure) と呼ばれる、テンプレートを活用して動的な(プログラム実行時の)多態性を実現する手法が存在する。この手法はC++の標準ライブラリでもstd::function
やstd::shared_ptr
の削除子で採用されている。いずれも、コンストラクタや代入演算子で(一定の条件を満たす)任意のオブジェクトを実引数として渡せるようにすることから多態性を実現している。
単一行コメント
C99の制定前、C言語とC++との分かりやすい差異として、//
で始まり改行で終わる、単一行コメントの有無があった。
単一行コメントはもともと、C言語の祖先にあたるBCPLに含まれていた仕様である。現在のC++のコンパイラの多くがC言語のコンパイラとしても使えるようになっているのと同様に、C言語が生まれて間もない頃は、C言語に加えB言語やBCPLのコンパイルができるコンパイラが用いられていた。それらコンパイラは、C言語のソースであってもBCPLと同様に単一行コメントが使用できるよう独自の拡張がなされていたため、BCPLの単一行コメントに慣れ親しんでいたプログラマ達は、C言語でも単一行コメントを使い続けた。その慣習がC++の誕生時まで生き残っていたため、C++では単一行コメントを「復活」させることになった。[独自研究?]
そのためもあって、C言語での仕様外の単一行コメントの使用は半ば常習と化し、[独自研究?]C99によって単一行コメントが正式に規格として組み入れられた。
C++ソースコードの処理とパーサ
LALR(1)のような旧式のパースアルゴリズムを用いてC++のパーサを記述することは比較的難しい[30]。その理由の一つはC++の文法がLALRではないことである。このため、コード分析ツールや、高度な修正を行うツール(リファクタリングツールなど)は非常に少ない。この問題を取り扱う方法としてLALR(1)でパースできるように改良されたC++の亜種(SPECS)を利用する方法がある。GLRパーサのようにより強力でシンプルなパーサもあるが処理が遅い。
パースはC++を処理するツールを作成する際の最も難しい問題ではない。このようなツールはコンパイラと同じように識別子の意味を理解しなければならない。従ってC++を処理する実用的なシステムはソースコードをパースするだけでなく、各識別子の定義を正確に適用し(つまりC++の複雑なスコープのルールを正確に取り扱い)、型を正しく特定できなければならない。
いずれにせよC++ソースコード処理ツールが実用的であるためには、GNU GCCやVisual C++で使われているような、様々なC++の方言を取り扱えなければならず、適切な分析処理やソース変換やソース出力などが実装できなければならない。GLRのような先進的なパースアルゴリズムとシンボルテーブルを組み合わせてソースコードを変換する方法を利用すればあらゆるC++ツールを開発できる。
互換性
その言語文法の複雑さゆえ、C++規格に準拠したコンパイラを開発するのは一般的に難しい。20世紀末から何年にも渡りC++に部分的に準拠した様々なコンパイラが作られ、テンプレートの部分特殊化などの部分で実装にばらつきがあった。中でも、テンプレートの宣言と実装を分離できるようにするためのexport
は問題のキーワードの一つだった。exportを定義したC++98規格がリリースされてから5年後の2003年前半にComeau C/C++が初めてexportを実装した。2004年にBorland C++ Builder Xがexportを実装した。これらのコンパイラはいずれもEDGのフロントエンドをベースにしていた。大半のコンパイラで実装されていないexportは多くのC++関連書籍(例えば"Beginning ANSI C++", Ivor Horton著)にサンプルが記されているが、exportが記載されていることによる問題は特に指摘されていない。GCCをはじめとするその他のコンパイラでは全くサポートしていない。Herb SutterはC++の標準規格からexportを削除することを推奨していたが[31]、C++98では最終的にこれを残す決定がなされた[32]。結局、C++11では実装の少なさ・困難さを理由に削除された。
コンパイラ開発者の裁量で決められる範囲を確保するため、C++標準化委員会は名前修飾や例外処理などの実装に依存する機能の実装方法を決定しないことに決めた。この決定の問題は、コンパイラが異なるとオブジェクトファイルの互換性が保証されない点である。特定の機種やOSでコンパイラの互換性を持たせ、バイナリレベルでのコード再利用性を高めようとするABI[33]のような非標準の規格もあり、一部のコンパイラではこうした準規格を採用している。
2019年現在のメジャーなC++コンパイラ(gcc, Clang, Intel C++ Compiler, Microsoft Visual C++など)の最新版はC++11およびC++14規格にほぼ準拠しており、特にClangは2013年4月時点でC++11の全機能を実装完了した[34][35]。ただしマイナーアップデートとなるC++17を含めると、処理系間でのばらつきは依然として存在する。
C言語との互換性
C++は基本的にC言語の上位互換であるが、厳密には異なる[36]。C言語で記述された大半のプログラムはC++でコンパイルできるように簡単に修正できるが、C言語では正当でもC++では不正になる部分や、C++とは動作が異なる部分が若干存在する。
例えば、C言語では汎用ポインタvoid*
は他の型へのポインタに暗黙的に変換できるが、C++ではキャスト演算子によって変換を明示する必要がある。またC++ではnew
やclass
といった数多くの新しいキーワードが追加されたが、移植の際に元のC言語のプログラムでそれらが識別子(例えば変数名)として使われていると、問題になる。
C言語の標準規格であるC99やその後継C11ではこうした非互換性の一部が解決されており、//
形式のコメントや宣言とコードの混在といったC++の機能がC言語でサポートされている。その一方でC99では、可変長配列、複素数型の組み込み変数、指示初期化子、複合リテラルといった、C++でサポートしていない数多くの新機能が追加された[37]。C99で追加された新機能の一部はC++11に反映され、C++14に対してもC99やC11との互換性を向上される提案が行われた。また、可変長配列や複素数型などのC99に追加された機能の一部はC11でオプションとなった[38][39]。
C++で書かれた関数をC言語で書かれたプログラムから呼び出す、あるいはその逆を行なう場合など、C言語のコードとC++のコードを混在させるためにはCリンケージを利用する必要があり、関数をextern "C"
で個別に修飾するか、extern "C" { ... }
のブロックの中で宣言しなければならない。また、関数引数や戻り値などのインターフェイスはC言語互換形式に合わせる必要がある。Cリンケージを利用した関数については、C++名前修飾がされず、名前修飾に依存している関数オーバーロード機能は利用できない。
C/C++の相互運用性が確保されていることで、慣れ親しんだC言語標準ライブラリ関数の大半をC++でもそのまま利用し続けることができるということはC++の大きなメリットのひとつである。
主なC++処理系
- Microsoft Visual C++ (MSVC)
- C++ Builder (Borland C++ Compiler, BCC)
- g++
- Intel C++ Compiler (ICC/ICL)
- Clang
注釈
- ^ Open issues for The C++ Programming Language (3rd Edition) - このコードはストロヴストルップ自身による訂正文からの引用(633ページ)。
std::endl
を'\n'
に改めている。またmain
関数がデフォルトで0を返す件についてはwww.research.att.com及びwww.delorie.com/djgpp/ を参照されたし。このデフォルト仕様はmain
関数のみであり他の関数にはない。
出典
- ^ a b 『プログラミング言語C++』第4版、pp.12-13。
- ^ 『C++の設計と進化』、pp.152-153。
- ^ 『プログラミング言語C++』第4版、p.11。
- ^ “Bjarne Stroustrup's FAQ - When was C++ invented?” (English). 2006年5月30日閲覧。
- ^ Bjarne Stroustrup; Margaret A. Ellis (1990). The Annotated C++ Reference Manual. Addison-Wesley Professional. ISBN 978-0201514599
- ^ Bjarne Stroustrup; Margaret A. Ellis『The Annotated C++ Reference Manual』足立高徳、小山裕司、シイエム・シイ、2001年。ISBN 978-4901280396。
- ^ ISO/IEC 14882:1998
- ^ ISO/IEC 14882:2003
- ^ ISO/IEC TR 19768:2007
- ^ ISO/IEC 14882:2011
- ^ ISO/IEC 14882:2014
- ^ https://www.iso.org/standard/68564.html
- ^ https://www.iso.org/standard/79358.html
- ^ We have C++14! : Standard C++
- ^ “Current Status”. isocpp.org. 7 September 2020閲覧。
- ^ “C++20 Approved -- Herb Sutter”. isocpp.org. 8 September 2020閲覧。
- ^ “ISO/IEC 14882:2020”. 2021年3月16日閲覧。
- ^ “Working Draft, Standard for Programming Language C ++” (2020年12月15日). 2021年3月16日閲覧。
- ^ Sutter, Herb (29 July 2020). “Business Plan and Convener's Report: ISO/IEC JTC1/SC22/WG21 (C++)”. 2021年3月16日閲覧。
- ^ “Upcoming Meetings, Past Meetings”. 2021年3月16日閲覧。
- ^ Ranns, Nina (2020年11月19日). “WG21 2020-11 Virtual Meeting: Minutes of Meeting”. 2021年3月16日閲覧。
- ^ Koenig, Andrew; Bjarne Stroustrup (1989年5月11日). “C++: as close as possible to C – but no closer” (PDF) (英語). 2016年11月19日閲覧。
- ^ Stroustrup, Bjarne. “Stroustrup: FAQ Is C a subset of C++?” (英語). 2016年11月19日閲覧。
- ^ 『C++の設計と進化』、pp.124-125。
- ^ Bjarne Stroustrup (2000年). The C++ Programming Language (Special Edition ed.). Addison-Wesley. pp. 46. ISBN 0-201-70073-5
- ^ 式 - cppreference.com
- ^ Sutter, Herb; Alexandrescu, Andrei (2004). C++ Coding Standards: 101 Rules, Guidelines, and Best Practices. Addison-Wesley
- ^ Henricson, Mats; Nyquist, Erik (1997). Industrial Strength C++. Prentice Hall. ISBN 0-13-120965-5
- ^ Stroustrup, Bjarne (2000). The C++ Programming Language (Special Edition ed.). Addison-Wesley. p. 310. ISBN 0-201-70073-5. "A virtual member function is sometimes called a method."
- ^ Andrew Birkett. “Parsing C++ at nobugs.org”. Nobugs.org. 2009年7月3日閲覧。
- ^ Why We Can’t Afford Export (PDF, 266 KB)
- ^ “Minutes of J16 Meeting No. 36/WG21 Meeting No. 31, April 7-11, 2003” (2003年4月25日). 2006年9月4日閲覧。
- ^ “C++ ABI”. 2006年5月30日閲覧。
- ^ 後藤大地 (2013年4月22日). “LLVM Clang、C++11にフル対応”. マイナビニュース. 2013年9月7日閲覧。
- ^ “GCC 4.8 Release Series — Changes, New Features, and Fixes - GNU Project”. gcc.gnu.org. 2022年11月7日閲覧。
- ^ “Bjarne Stroustrup's FAQ - Is C a subset of C++?”. 2008年1月18日閲覧。
- ^ “C9X -- The New C Standard”. 2008年12月27日閲覧。
- ^ 可変長配列: §6.7.6.2
- ^ C言語の最新事情を知る: C99の仕様 - Build Insider
参考文献
- Stroustrup, Bjarne 著、ロングテール、長尾高弘 訳『プログラミング言語C++』(第3版)アジソン・ウェスレイ・パブリッシャーズ・ジャパン , アスキー (発売)〈アスキーアジソンウェスレイシリーズ〉、1998年(原著1997年)。ISBN 475611895X。 NCID BA39336320。
- Stroustrup, Bjarne 著、柴田望洋 訳『プログラミング言語C++』(第4版)SB Creative、2015年(原著2013年)。ISBN 978-4-7973-7595-4。
- Stroustrup, Bjarne 著、岩谷宏 訳、επιστημη監修 編『C++の設計と進化』ソフトバンククリエイティブ、2005年(原著1994年)。ISBN 4797328541。 NCID BA70383225。
関連項目
- C++/CLI
- Embedded C++
- プログラミング言語の比較
- SystemC - C++言語ベースのハードウェア記述言語
- テンプレートメタプログラミング
- キーワード (C++)
- CとC++の演算子
外部リンク
C--
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/06/23 04:24 UTC 版)
ナビゲーションに移動 検索に移動パラダイム |
命令型プログラミング ![]() |
---|---|
登場時期 | |
開発者 |
サイモン・ペイトン・ジョーンズ ![]() |
最新リリース | 2.0 / 2005年2月23日[1] |
影響を受けた言語 |
C言語 ![]() |
ウェブサイト | |
拡張子 |
c-- ![]() |
C--(シーマイナスマイナス)は、人間ではなくコンパイラが生成することを想定したC言語風のプログラミング言語(中間言語)である。Haskell処理系のデファクトスタンダードであるGlasgow Haskell Compilerが、複数ある中間言語の一つとして採用している。
歴史
1990年代、マルチプラットフォームのプログラミング言語は、元言語ソースコードをC言語ソースコードへトランスパイルして、C言語ソースコードを対象プラットフォームマシンコードへコンパイルしていた[2]。C言語コンパイラは多様なプラットフォームのマシンコード出力をサポートしていたため、C言語を中間言語として採用することは現実的に利にかなった手法である。しかし、C言語は人間が読み書きするプログラミング言語として設計されているため、機械が処理してトランスパイルして生成する中間言語としては最適設計ではなかった。例えば、C言語ではガベージコレクションや例外処理は意図的に言語仕様に組み込んでおらず、それらの機能を利用したプログラミング言語からC言語へのトランスパイルは一部機能が利用不可となる制限がありえた。
1997年、それらの課題を解決するため、ノーマン・ラムゼーはC--をImplementing Functional LanguagesワークショップでC--: A Portable Assembly Languageのタイトルで、コンパイラが扱うC言語に代わる中間言語として発表した[3]。C--は人間が読み書きするプログラミング言語としての特性より機械が処理する中間言語としての特性を重視し、多種プログラミング言語をフロントエンドに置きうるバックエンド仕様、マルチプラットフォームのマシンコード値型、ガベージコレクション・例外処理などのランタイムインターフェースを提供した。
1999年5月23日、C--バージョン1の言語仕様リファレンスがリリースされた[4]。
2005年2月23日、C--バージョン2の言語仕様リファレンスがリリースされた[5]。
2003年10月6日から2006年10月31日までの間、C--およびQuick C--の開発はアメリカ国立科学財団の支援を受けていた[6]。
設計
C--は、人間が読み書きするためのプログラミング言語としてではなく、マシンが解釈するアセンブリ言語として設計されている。C--コードは極力プラットフォームアーキテクチャに依存せず、直交性・最小性より性能・利便性を重要視した言語仕様である。C--の文法は、C言語の言語仕様に似たプログラミング言語の特徴を持っている[7]。
- データ
- プリミティブ型・参照型で定義される。プリミティブ型には16bit正数値のint型、 8bit文字のchar型、真偽値のboolean型がある。参照型にはプリミティブ型配列の配列型、複数型から成る構造体型がある。文字列はchar配列で表される。
- 変数
- スタック型・ヒープ型で定義される。関数内のローカル変数はスタック変数、関数外のグローバル変数はヒープ変数として扱われる。
- 関数
- 関数名・返り値型・ブロック文で定義される。返り値は無を返す場合でも省略することは出来ず、キーワードvoidの返却を明記する。
- 演算子
- C言語演算子を踏襲した比較演算・四則演算・ビット演算などが定義される。
- 文
- 空文・式文・ブロック文・if文・while文・do-while文・for文・return文・break文・continue文で定義される。
処理系
C--コードをマシンコードにコンパイルする処理系は複数存在する[8]。2018年現在、大半の処理系がソースコードの公開を含めメンテナンスされていない。
- Quick C--
- Quick C--は、The Quick C-- Teamが開発するコンパイラである[9]。C--バージョン2のC--コードをIntel x86のLinuxマシンコードへコンパイルする。他プラットフォームのマシンコードへのコンパイルは試験版機能として実装されている。従来はC--言語仕様の開発と平行してQuick C--が開発されていたが、2018年現在はgithubにソースコードが保管されているのみで開発は継続していない[10]。
- cmmc
- cmmcは、Fermin ReigがML言語で実装したC--コンパイラである。Alpha・Sparc・X86のマシンコードを出力する。
- Trampoline C-- Compiler
- Trampoline C-- Compilerは、1999年5月にSergei Egorovが開発したC--からC言語へのトランスパイラである。
- Oregons Graduate Institutes C-- compiler
- Oregons Graduate Institutes C-- compiler(OGI C-- Compiler)は、1997年にML言語で実装された最初期のプロトタイプのC--コンパイラである[11]。Quick C--の開発が始まってからはメンテナンスは継続していない。
類似言語
- Universal Computer Oriented Language
- Universal Computer Oriented Language(UNCOL)は、1958年にメルヴィン・コンウェイが提唱した中間言語である[12]。言語仕様として完全なものは存在しておらず、プログラミング言語とコンパイラの在り方に対する新しいコンセプトとして提案された。
- GNU Assembler
- GNU Assembler(GAS)は、1986年代に発表されたGCCのアセンブリ言語である[13]。GCCはC/C++ソースコードからGASソースコードへトランスパイルして、GASソースコードで処理最適化を実施してから、対象プラットフォームのマシンコードへコンパイルする。GCCはC/C++以外のプログラミング言語にも対応しており、他プログラミング言語のコンパイルでも同様の処理を経てマシンコードを出力する。
- LLVM Assembly
- LLVM Assembly(LLVM IR)は、2000年代以降に開発されているLLVMの中間言語である[14]。LLVMはコンパイルのバックエンド処理を主に担うコンパイラコンポーネントである。フロントエンド処理を担うのはclang・rustc・swiftcなどのプログラミング言語毎の異なるコンポーネントである。LLVMはLLVM IRソースコードで処理最適化を実施してから、対象プラットフォームのマシンコードへコンパイルする。
脚注
- ^ 出典URL: https://www.cs.tufts.edu/~nr/c--/extern/man2.pdf
- ^ Christopher Heng (30 August, 2017). “Free Modula-3 Compilers and Development Environment”. 2018年4月22日閲覧。 “It uses the GNU C Compiler as a backend to generate binaries.”
- ^ Norman Ramsey (2007年2月5日). “C--: A Portable Assembly Language”. 2018年4月22日閲覧。
- ^ Norman Ramsey (1999年5月23日). “The C-- Language Specification Version 2.0”. 2018年4月22日閲覧。
- ^ Norman Ramsey (2007年2月5日). “C-- Manual Version 1 (pdf)”. 2018年4月22日閲覧。
- ^ “NSF Award Search: Award#0325460 - ITR Collaborative Research: A Reusable, Extensible, Optimizing Back End”. National Science Foundation. 2018年4月22日閲覧。
- ^ 柳 洋輔 (2015年9月15日). “C--言語からC言語への変換系の実用化”. 2018年4月22日閲覧。
- ^ Norman Ramsey (2007年2月5日). “C-- Downloads - Other C-- compilers”. 2018年4月22日閲覧。
- ^ The Quick C-- Team (2014年1月24日). “Release notes for the Quick C-- compiler Release 20140124 (pdf)”. 2018年4月22日閲覧。
- ^ Norman Ramsey (2014年1月25日). “The Quick C-- Compiler”. 2018年4月22日閲覧。
- ^ “Pacsoft Research C-- Compiler”. Pacific Software Research Center. (1998年3月4日). 2007年8月16日時点のオリジナル[リンク切れ]よりアーカイブ。
- ^ Melvin E. Conway. “Proposal for an UNCOL”. Communications of the ACM. 2018年4月22日閲覧。
- ^ Dean Elsner. “Using as The gnu Assembler (pdf)”. The Regents of the University of Michigan. 2018年4月22日閲覧。
- ^ “LLVM IR and Transform Pipeline (pdf)”. 2018年4月22日閲覧。
外部リンク
- C-- Home - 公式ウェブサイトのミラーサイト(公式ウェブサイトは消滅)
- GitHub nrnrnr/qc-- - Quick C--コンパイラ(メンテナンス終了)
|
C言語
![]() C言語のロゴ | |
パラダイム |
命令型プログラミング、構造化プログラミング、手続き型プログラミング ![]() |
---|---|
登場時期 | 1972年 . |
開発者 |
ベル研究所、デニス・リッチー、米国国家規格協会、国際標準化機構、ケン・トンプソン ![]() |
最新リリース | ISO/IEC 9899:2024/ 2024年10月31日 |
型付け | 弱い静的型付け |
主な処理系 | GCC, Clang, Visual C++, Intel C++ Compiler |
影響を受けた言語 |
ALGOL 68、B言語、アセンブリ言語、FORTRAN、PL/I、CPL、BCPL、ALGOL 60、ALGOL ![]() |
影響を与えた言語 | awk、csh、C++、Objective-C、Rust、D言語、Java、JavaScript、Limbo |
プラットフォーム |
Microsoft Windows、Unix系 ![]() |
ウェブサイト | |
拡張子 |
.c , .h |
C言語(シーげんご、英: C programming language)は、1972年にAT&Tベル研究所のデニス・リッチーが主体となって開発した汎用プログラミング言語である。英語圏では「C language」または単に「C」と呼ばれることが多い。日本でも文書や文脈によっては同様に「C」と呼ぶことがある。制御構文などに高水準言語の特徴を持ちながら、ハードウェア寄りの記述も可能な低水準言語の特徴も併せ持つ。基幹系システムや、動作環境の資源制約が厳しい、あるいは実行速度性能が要求されるソフトウェアの開発に用いられることが多い。後発のC++やJava、C#など、「C系」と呼ばれる派生言語の始祖でもある[注釈 1]。
ANSI、ISO、またJISにより言語仕様が標準規格化されている。
特徴
![]() | この節に雑多な内容が羅列されています。 |
Cには他のプログラミング言語と比較して、特筆すべきいくつかの特徴がある。
利点
- 構造化プログラミングのパラダイムに対応した高水準の手続き型言語である。ハードウェアの直接的な制御ができる機能を備えつつ、機械語やアセンブリ言語(アセンブラ)のような低水準言語と比較して、ソースコードの再利用性やメンテナンス性に優れており、目的に応じたプログラムの変更や拡張が容易である。
- 汎用性およびプログラムの自由度が高く、リソースや性能要求の厳しい用途にも耐えうるため、アプリケーションソフトウェアの開発だけでなく、オペレーティングシステム(OS)やデバイスドライバー、ファームウェアの記述、マイコン制御・機械制御など、上位層・下位層を問わず、あらゆる分野で利用されている。
- 対応する機器の範囲が広い。パーソナルコンピュータやワークステーションはもちろん、自動車や家電の組み込み用マイコンからスーパーコンピュータまで、C言語を使用できるハードウェアは多様である。そのため、C言語のコード資産が蓄積されている環境・分野は多岐に渡る。
- 商用・非商用を問わず、採用ソフトウェア分野が広い。プログラム作成やデバッグのための補助的なソフトウェア(プログラミングツール)が豊富である。
- ソースコードを機械語に変換するソフトウェア(コンパイラ)などの開発環境がCPUやOSに付属していたり無償だったりするものもあるため、ライセンス料の支払いをしなくても使用が始められる。
欠点
- 開発時期が古いことから、言語構文(文法)に機械語の影響が強く、仕様自体は単純ではあるが明快ではなく難解である。この欠点を改良するためのちに開発された後発言語に比較し、プログラマが記述しなければならないことが多く、低水準言語のように面倒で習得しにくい側面を持つ。
- Cは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。また、詳細を規格で規定せず処理系に委ねている部分が多く、Cで書かれたソフトウェアでは処理系依存のコードが氾濫する原因となった。セキュリティ上の脆弱性や潜在的バグによる想定外の動作、コンパイラによる最適化の難しさ[注釈 2]といった問題を抱えており、最適化するとコンパイル速度が遅くなるなどの問題が生じることがある。
上記のように、利点でもあり、同時に欠点にもなる特徴を備えている。
もともとUNIXおよびCコンパイラの移植性を高めるために開発されてきた経緯から、オペレーティングシステム(OS)のカーネルおよびコンパイラ向けの低水準な記述ができるなど、ハードウェアをある程度抽象化しつつも、必要に応じて低水準言語と同じことを実現できるようなコンピュータ寄りの言語仕様になっている。そのため、低水準な記述ができる高水準言語と言われたり、高水準言語の顔をした低水準言語(高級アセンブラ[2]、汎用アセンブラ[3])と言われたりすることがある。
Cはアマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。使用者の多さから、正負の両面含め、Cはプログラミング文化に大きな影響を及ぼしている。また、多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、Cで対応可能である。ただし、Cで効率的かつ安全に記述できるかどうかはまた別の話である。スクリプト言語やコマンドラインシェルを使えば手軽に実現にできるような処理まで、わざわざCで記述する必要はない。また、GUIアプリケーションフレームワークは、Cからは利用できず、統合開発環境と連携する新しいプログラミングツールやプログラミングパラダイムに対応した後発言語でなければ利用できないものもある。
MISRA CやCERT Cというコーディング標準(コーディング規約)を定義して、危険な機能の使用や記述を禁止するという制限を設けることでCを安全に利用するためのガイドラインが運用されている分野もある。特にプログラミングミスが人命に直結する自動車分野などでCを利用するには、このような制約が重要である。
機能と自由度
- 文の区切りを終端記号 セミコロン「
;
」で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。中括弧{ }
によるブロック構造およびスコープをサポートする。 - ALGOLの思想を受け継いで構造化プログラミングに対応している。手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐(
goto
)を使用する必要はなく、MISRA Cでは当初goto文を禁止していた。 - モジュール化がファイルを単位として可能。モジュール内だけで有効な名前を使うことができるスコープを持っている。
- プログラムを戻り値つきのサブルーチンに分離できる。C言語ではこれを関数と呼び、関数内のプログラムコードでは、独立したスコープを持つ変数(ローカル変数)が使用できる。これにより、データの流れがブロックごとに完結するのでデバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提としたホスト環境と、割り込み制御のようなOSを前提としないフリースタンディング環境とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を
main
という名前の関数として定義する[注釈 3]。プログラム中で再帰的にmain
関数を呼ぶことも可能(C++では不可能[4][5])。フリースタンディング環境では、エントリーポイントと呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しそのものは、スタックオーバーフローの原因となるため、MISRA Cでは禁止している。 - システム記述言語として開発されたため、高級言語であるがアセンブラ的な低水準の操作ができる。ポインタ演算、ビットごとの論理演算、シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはオペレーティングシステムやデバイスドライバーなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
- ソースコードの記述に使う文字集合はANSI C (C89) およびISO/IEC 9899:1990 (C90) ではASCIIを標準としている。他のISO 646でも書けるように、3文字利用したトライグラフと呼ばれる表記法も存在する。その後、ISO/IEC 9899:1995 AMD (C95) などではマルチバイト文字セット対応の拡張を規定している。さらに、その後トライグラフは複数のコードを利用したシステムでしか利用がない[要説明]ため、より分かり易い2文字によるダイグラフを規定している。
- 組み込みの整数型および浮動小数点数型のほか、構造体、共用体、列挙体(列挙型)によるユーザー定義のデータ型や列挙定数をサポートする。構造体および共用体はビットフィールドをサポートする。
アセンブラとのインタフェース
- 多くの処理系がインラインアセンブラを搭載しているほか、アセンブラで出力したオブジェクトとのリンクが容易になっている。これにより速度が要求される部分だけをアセンブリ言語で記述するということが容易に行えることが多い。アセンブラとのインタフェースは#pragma asmなどを用いて局所化を図る努力はあるが、コンパイラごとに定義があり、CPUが同一であっても移植性が低い場合がある。
コンパイラ仕様
- コンパイラの処理が1パスで済む仕様になっている。歴史的な経緯から、変数の宣言において型指定がない場合は
int
型とみなし、関数の戻り値の型指定がない場合はint
型とみなす。ANSI C (C89) ではコンパイル時型検査の強化のために関数プロトタイプの機能が導入されたが、関数の宣言がない場合の戻り値はint
型とみなし、引数は未知(任意)とみなす。しかし、このような暗黙の型指定は型安全性を損ない未定義動作を引き起こす危険性があるため、ISO/IEC C:1999 (C99) 以降では暗黙の型指定に関する仕様が標準規格の文面から削除された。いずれも使用(参照)するより前に適切に宣言する必要がある。ClangやGCCといったC99準拠のコンパイラは、このような暗黙の型指定について、C99モードであってもC89互換の動作を残してはいるものの、非標準の動作であるため警告を出すようになっている。なお、関数宣言において()
のように引数を省略すると、引数を未知とする仕様はC99でも残されている。後継言語では完全なプロトタイプ宣言を必須とするか、あるいはプロトタイプ宣言自体を不要としているが、記述によっては先読みが必要になりうる。 - マクロ記述やコンパイル条件の指定などができる前処理指令が標準化されている。前処理指令の解釈をするプリプロセッサ (preprocessor) を持っている。プリプロセッサは、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。
処理系の簡素化
処理系の簡素化と効率のために、以下のように安全性を犠牲にした仕様が多い。なお、ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施したとしても実行速度の低下が無視できる程度であることも多く、言語仕様側の欠点とみなされることも少なくない。
- 配列の参照時に添字の値が範囲内にあるかを検査しない
- これを要因とする代表的なバグが、固定長のバッファ領域をはみだしてデータの書き込みが行われてしまう「バッファオーバーフロー」(バッファオーバーラン)である。範囲外のアクセスは、書き込みだけでなく読み取りの場合も未定義動作を引き起こす。標準ライブラリにはバッファオーバーフローや範囲外アクセスを考慮していない関数があり、かつ多用されがちなため、しばしば脆弱性の原因となる。また、Cではプログラムにより明示的に制御(動的メモリ確保)することで可変長配列の実現を可能にしているが、確保した領域の範囲外にアクセスしても自動的な伸長は行なわれない。
- 後継言語では、標準ライブラリまたは組み込み型により可変長配列をサポートしていたり、範囲外アクセス時には例外(実行時エラー)を送出するなどして安全性を優先していたりすることが多い。
- 文字列を格納するための特別な型が存在しない
- 文字列には
char
型の配列を利用する。言語仕様上に特別な扱いはないが、ヌル文字('\0'
)を終端とする文字列表現を使い、その操作をする標準ライブラリ関数がある。これは実質的にメモリ領域へのポインタアクセスそのものであり、確保されている領域の長さよりも長い文字列を書き込めてしまうために、バッファオーバーランの元凶の1つとなっている。 - 後継言語では文字列処理を特に強化している場合が多く、標準ライブラリあるいは言語仕様による組み込みの文字列型を提供している。
- 自動変数(auto variable)の自動的な初期化をしない
- 自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合にはその値は不定であるが、不定な値へのアクセスは未定義動作であるので、コンパイラ最適化の過程で想定しない形に改変することもある[6]。変数宣言・初期化の仕様による制限から、変数宣言の時点では初期化をせずに後で代入等により値を入れてつかうことが普通なので、誤って不定の値の変数を読み出すバグを作り込みやすい。なお自動変数の自動とは変数の領域の確保と解放が自動であるという意味であり、自動的に初期化されるという意味ではない。
- 後継言語では、明示的な初期化が記述されていない変数は、不定値ではなくその変数の型の既定値(ゼロあるいはゼロ相当の値)で初期化される仕様になっていることが多い。
その他
- ソースコード上の文字の大文字・小文字を区別する。
- 入出力や動的メモリ確保を含めほとんどの機能が、C言語自身で書かれたライブラリによって提供される。このことは、C言語の機種や環境依存性が低く、それらに依存する箇所をライブラリへ分離することにより移植性(ポータビリティ)が高いことを意味する[要出典]。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
- 例として、POSIX環境での動的メモリ確保は
malloc
およびその類似関数にて提供される。一方、カーネルではメモリ確保の際にスレッドがブロックされるとカーネル内のデータが他のスレッドにより変更され、予期せぬ動作を起こす恐れがあることや、メモリ内容の初期化が必要かどうかによって割当先のページを選択することによりシステムの効率が上がることから、多くの場合POSIXとは異なるAPIを使用している。Linuxカーネルの場合、前者はフラグGFP_KERNEL
とGFP_ATOMIC
の使い分け、後者は関数kmalloc
(割り当てたメモリの内容は不定)とkzalloc
(割り当てたメモリの内容はゼロクリア済)の使い分けにより実装している[7]。
- 例として、POSIX環境での動的メモリ確保は
- プログラムの実行に必要とするハードウェア資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの組み込みシステムでも使用されている。
- 組み込み向けの場合は、プログラミング言語として、アセンブラ以外ではCとC++しか用意されていないことがある。その場合、他のプログラミング言語は、CやC++で書かれた処理系が存在すればコンパイルすることにより利用可能となることもあるが、メモリ制約などで動作しないことがある。
- ANSI/ISOにより規格が標準化された後は言語仕様の変化が小さく安定していること、C言語のプログラマ人口やコード資産が多いこと、C++やObjective-CからC言語関数を直接利用できること、また必要に応じて他のプログラミング言語からC言語関数を呼び出すためのバインディングを記述することが容易であることなどから、APIの外部仕様としてC言語の関数インターフェイスが選ばれることが多い。例えばOpenGLやOpenCLのようなオープン規格は第一級言語としてC言語を採用している。
コード例
Hello worldプログラム
C言語のHello worldプログラムは、ホスト環境を前提とするか、フリースタンディング環境を前提とするかで、方向性が異なる。ホスト環境を前提とする場合には、標準入出力の利用により、動作をすぐに確かめることができる。以下では、標準Cライブラリのヘッダstdio.h
にて宣言されている、puts
関数あるいはprintf
関数を利用したものを例示する。
/* int puts(const char* s) を使う場合。 */
#include <stdio.h>
int main(void)
{
puts("Hello, world!");
return 0;
}
/* int printf(const char* format, ...) を使う場合。 */
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Hello, world!\n");
return 0;
}
上記サンプルソース中の「\n
」は、エスケープ文字\
によるエスケープシーケンスのひとつであり、改行(ラインフィード)を表す。
main
関数は標準的なプログラムエントリーポイントであり、プログラムを開始すると、ランタイムライブラリによるスタートアップ処理が実行された後にこのmain
関数が呼ばれる。引数のないバージョンと、コマンドライン引数をポインタ配列として受け取るバージョンどちらを使ってもよい[8]。
なお、printf
関数は書式文字列とそれに対応する可変個引数を受け取り、書式化された文字列として表示できる高機能な標準出力関数であるが、序盤から例示に使用している入門書もある。
main
関数とprintf
関数は、いずれも入門者や初学者にとっては最初の関門となる難解な関数であり、C言語によるプログラミングのハードルを高くしている一因でもある[9][10]。JavaやC#のような後発言語では、文字列の扱いや、可変個引数の扱いがより簡潔で安全になっている。Pythonのようなインタプリタや対話環境上で動作することを前提とした言語では、main
関数を定義する必要はない。
主な制御構造
主な標準ライブラリ関数
歴史
誕生
C言語は、AT&Tベル研究所のケン・トンプソンが開発したB言語の改良として誕生した(#外部リンクの「The Development of the C Language」参照)。
1972年、トンプソンとUNIXの開発を行っていたデニス・リッチーはB言語を改良し、実行可能な機械語を直接生成するC言語のコンパイラを開発した[11]。後に、UNIXは大部分をC言語によって書き換えられ、C言語のコンパイラ自体も移植性の高い実装のPortable C Compilerに置き換わったこともあり、UNIX上のプログラムはその後にC言語を広く利用するようになった。
ちなみに、「UNIXを開発するためにC言語が作り出された」と言われることがあるが、「The Development of the C Language」によると、これは正しくなく、経緯は以下の通りである。C言語は、当初はあくまでもOS上で動くユーティリティを作成する目的で作り出されたものであり、OSのカーネルを記述するために使われるようになるのは後の展開である。
- UNIXの開発当初、Multicsプロジェクトが目指していた高級言語によるOSの開発という目標は見送られた。
- アセンブリ言語でUNIXが作成されると、OS上で動くユーティリティを作成するためのプログラミング言語が必要とされた。
- ケン・トンプソンは、当初Fortranコンパイラを作ろうとしたが、途中で放棄し、新しい言語であるB言語を作成した。
- B言語はインタプリタ言語であったため動作が遅く、B言語でユーティリティを作ることはあまりなかった。
- 開発者達は、コンパイラなどのユーティリティを「システムプログラム」と呼んでいたが、それらの作成に使われる「システムプログラミング言語」は、OSのカーネルを作成するための言語という意味ではない[12]。
- B言語の欠点を解消するため、1971年に改良作業を開始した。
- 1972年にC言語のコンパイラができあがり、UNIXバージョン2において、いくつかのユーティリティを作成するために使用された。
UNIX環境とC言語
アセンブラとの親和性が高いために、ハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述のK&Rといった解説文書が存在していたことなど、さまざまな要因からC言語は業務開発や情報処理研究での利用者を増やしていった。特にメーカー間でオペレーティングシステムやCPUなどのアーキテクチャが違うUNIX環境では再移植の必要性がしばしば生じて、プログラムをC言語で書いてソースレベル互換[13]を確保することが標準となった。
C言語誕生時の環境と他言語との比較
C言語の開発当初に使われた入力端末はASR-37であったことが知られている[12]。
ASR-37は1967年制定の旧ASCII ISO R646-7bitにもとづいており、「{
」および「}
」の入力を行うことができたが、当時は一般的に使われていた入力端末ではなかった。
当時PDP-11の入力端末として広く使われていたのはASR-33であるが、これは1963年制定の旧ASCIIであるASA X3.4に準拠しており、「{
」や「}
」の入力を行うことはできなかった[14]。
このことは、ブロック構造に「{
」や「}
」を用いるC言語(さらに元をたどればB言語)は、当時の一般的な環境では使用不可能であったことを示している。
これは、C言語はその誕生当初にあっては一般に広く使われることを想定しておらず、ベル研究所内部で使われることを一義的に考えた言語であったという側面の表れである。
これに対し、PascalやBASIC等の当初から広く使われることを想定した言語では、ブロック構造に記号を用いずにbegin
とend
をトークンとして用いることや、コメント行を表す際に開始トークンとしてREM
という文字列を用いることなど、記号入力に制約がある多くの入力端末に対応できるように配慮されていた。この頃の他の言語やOSで大文字と小文字の区別をしないものが多いのも、当時は大文字しか入力できない環境も少なくなかったことの表れである。
このような事情のため、C言語が普及するのは、ASCII対応端末が一般化した1980年代に入ってからである。
現在、ブロック構造の書式等で、{...}
形式のC言語と、begin...end
等を使用する他の言語との比較において優劣を論じられることがあるが、開発時の環境等をふまえずに現時点での利便性のみで論じるのは適切ではない場合があることに留意が必要である。
PCとC言語
1980年代に普及し始めたパーソナルコンピュータ (PC) は当初、8ビットCPUでROM-BASICを搭載していたものも多く、BASICが普及していたが、1980年代後半以降、16ビットCPUを採用しメモリも増えた(ROM-BASIC非搭載の)PCが主流になりだすと、Turbo CやQuick Cといった2万円程度の比較的安価なコンパイラが存在したこともあり、ユーザーが急増した。8ビットや8086系のPCへの移植は、ポインタなどに制限や拡張を加えることで解決していた。
現在のC言語
1990年代中盤には、最初に学ぶプログラミング言語としても主流となった。また、同時期にはゲーム専用機(ゲームコンソール)の性能向上とプログラムの大規模化、マルチプラットフォーム展開を受け、メインの開発言語がアセンブラからC言語に移行した。
1990年代後半 - 2000年代以降は、PCのさらなる性能向上と普及、GUI環境やオブジェクト指向の普及、インターネットおよびウェブブラウザの普及、スマートフォンの普及に伴い、より高水準で開発効率の高い言語やフレームワークを求める開発者が増えたことにより、C++、Visual Basic、Java、C#、Objective-C、PHP、JavaScriptなどが台頭してきた。広く利用されるプログラミング言語の数は増加傾向にあり、相対的にC言語が使われる場面は減りつつある。特にアプリケーションソフトウェアなどの上位層の開発には、C言語よりも記述性に優れるC++、Java、C#などC言語派生の後発言語が利用されることが多くなっている。資源制約の厳しかったゲーム開発においても、ハードウェアの性能向上やミドルウェアの普及により、C++やC#などが使われる場面が増えている。速度性能や省メモリが特に重視されるシステムプログラミングに関しても、伝統的にC/C++の独壇場だったが、新規コードではより安全性の高いRustを導入する事例が現れている[15][16]。
しかし、C言語は比較的移植性に優れた言語であり、個人開発/業務用開発/学術研究開発やプロプライエタリ/オープンソースを問わず、オペレーティングシステムやデバイスドライバーなどの下位層、クロスプラットフォームAPIの外部仕様、C++やJavaなどの高水準言語の処理系および実行環境の実装が困難な小規模の組み込みシステムなどを中心に、2021年現在でも幅広く利用されている。
プログラミング入門者にとっては、Python、JavaScript、Swift、Kotlinなどのように、インタラクティブな対話環境(REPL、インタプリタ)が利用でき、抽象化が進んでおり、煩雑なメモリ管理が不要で、危険な機能を制限した高水準言語のほうが学習・習得しやすいが、コンピュータの動作原理やハードウェア仕様を理解するには、Cのような原始的な言語を用いたほうがかえって分かりやすいケースもある。
規格
K&R
米国国家規格協会(ANSI)による標準化が行われるまで、1978年出版のデニス・リッチーとブライアン・カーニハンの共著『The C Programming Language』が実質的なC言語の標準として参照されてきた。この書籍は、著者らのイニシャルを取って「K&R」とも呼ばれている。C言語は発展可能な言語で、K&Rの記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。そのためC言語が普及するとともに、互換性のない処理系が数多く誕生した。
C89/C90
そこで、ISO/IEC JTC1とANSIは協同でC言語の規格の標準化を進め、1989年12月にANSIがANSI X3.159-1989, American National Standard for Information Systems -Programming Language-Cを、1990年12月にISOがINTERNATIONAL STANDARD ISO/IEC 9899 : 1990(E) Programming Languages-Cを発行した。ISO/IEC規格のほうが章立てを追加しており、その後ANSIもISO/IEC規格にならって章立てを追加した。それぞれC89 (ANSI C89) およびISO/IEC C90という通称で呼ぶことがある。
日本では、これを翻訳したものを『JIS X 3010-1993 プログラム言語C』として、1993年10月に制定した。
最大の特徴は、C++と同様の関数プロトタイプ[注釈 4]を導入して引数の型チェックを強化したことと、void
やenum
などの新しい型を導入したことである。一方、「処理系に依存するものとする」に留めた部分も幾つかある(int
型のビット幅、char
型の符号、ビットフィールドのエンディアン、シフト演算の挙動、構造体などへのパディング等)。
規格では以下の3種類の自由を認めている部分がいくつかある[17]。
- 規格で定義しないことを決めている「未定義」 (undefined)
- 規格で選択肢を定義したもののどれにするかを決めておらず、処理系が選択する必要があるが、文書化の必要はない「未規定」 (unspecified)
- 処理系ごとに決めて文書化する必要のある「処理系定義」 (implementation-defined)
これにより、プラットフォームやプロセッサアーキテクチャとの相性による有利不利が生じないような仕様になっている。
8ビット/16ビット/32ビットなど、レジスタ幅(ワードサイズ)の異なるプロセッサ (CPU) に対応・最適化できるようにするため、組み込み型の情報量(大きさ)や内部表現にも処理系の自由を認めている。型のバイト数はsizeof
演算子で取得し、各型の最小値・最大値はlimits.h
で定義されているマクロ定数で参照することとしている。ただし、1バイトあたりのビット数は規定されていない。sizeof(char) == 1
すなわちchar
型が1バイトであることは常に保証されるが、8ビット(オクテット)とは限らない。実際のビット数はCHAR_BIT
マクロ定数で取得できる。とはいえ、現実の多くの処理系ではchar
型は8ビットである。また、その他の整数型については、sizeof(int) >= 2
、sizeof(int) >= sizeof(short)
、sizeof(long) >= sizeof(int)
、という大小関係が定められているだけである(符号無し型も同様)。多くの処理系ではshort
型のサイズは2バイト(16ビット)であるが、int
やlong
のサイズはCPUのレジスタ幅などによって決められることが多い。int
型、short
型、long
型で符号を明示しない場合はsigned
を付けた符号付き型として扱われる。しかしchar
型に関しては、signed
(符号付き)にするか、それともunsigned
(符号無し)にするかは処理系依存である。char
型、signed char
型、unsigned char
型はそれぞれ異なる型として扱われる。
規格上には、BCPLやC++形式の1行コメント(//…
)は無いが、オプションで対応した処理系も多く、gccやClangはGNU拡張-std=gnu89
でサポートしている。
GNU Cコンパイラ や Clang では、-std=c89
(または-ansi
もしくは-std=c90
)をつけることにより、GNU拡張を使わないC89規格に準拠したコンパイルを行うことができる[注釈 5]。加えて、-pedantic
をつければ診断結果が出る。商用のコンパイラではWatcom Cコンパイラが規格適合の比率が高いと言われていた。現在Open Watcomとして公開している。
C89には、下記の追加の訂正と追加を行った。
- ISO/IEC 9899/COR1:1994
- ISO/IEC 9899/AMD1:1995 - 英語圏での利用を想定して制定したC89に対して、国際化のためワイド文字版ライブラリを追加したAmendment1が1995年に発行された。
- ISO/IEC 9899/COR2:1996
C99
1999年12月1日に、ISO/IEC JTC1 SC22 WG14 で規格の改訂を行い、C++の機能のいくつかを取り込むことを含め機能を拡張し、ISO/IEC 9899:1999(E) Programming Language--C (Second Edition) を制定した。この版のC言語の規格を、通称としてC99と呼ぶ。
日本では、日本産業規格 JIS X 3010:2003「プログラム言語C」がある。
主な追加機能:
- 変数宣言がブロックの先頭でなくても良くなった。
- ブール代数を扱うための
_Bool
型が予約語に追加され、標準ライブラリとしてstdbool.h
を追加した。 - 複素数を扱うための
_Complex
型や_Imaginary
型を予約語に追加し、標準ライブラリとして、complex.h
を追加した。 - 少なくとも64ビットの整数値を保持できる
long long int
型の追加。 - オプションとして、固定幅かつ内部表現の規定された整数型の標準化(
stdint.h
)。 //
による1行コメント。- インライン関数(
inline
キーワード)。 - 可変長配列(
alloca
関数の代替)[18]。
C99は下記の訂正がある。
- ISO/IEC 9899:1999 Cor. 1:2001(E)
- ISO/IEC 9899:1999 Cor. 2:2004(E)
- ISO/IEC 9899:1999 Cor. 3:2007(E)
C11
2011年12月8日にISO/IEC 9899:2011(通称・C11)として改訂された。
C11はUnicode文字列(UTF-32、UTF-16、UTF-8の各符号化方式)に標準で対応している。そのほか、type-generic
式、C++と同様の無名構造体・無名共用体、排他的アクセスによるファイルオープン方法、quick_exitなどのいくつかの標準関数などを追加した。
また、_Noreturn
関数指示子を追加した。_Noreturn
は従来処理系ごとに独自に付加していた属性情報(たとえばgccでは__attribute__((__noreturn__))
)を標準化したもので、「呼び出し元に戻ることがない」という特殊な関数についてその特性を示すためにある。return
文を持たない関数という意味ではなく(規格ではreturn
文を持たなくとも、関数の最後の文の実行が終われば制御は呼び出し元に戻る)、_exit
やexecve
を実行したり、例外、longjmp
による大域ジャンプ[注釈 6]などのために、制御が呼び出し元に戻らないことを明示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。
C11規格では一部の機能を省略可能とした。即ちコンパイラがC11に合致していても、一部機能は提供しないことがある。コンパイラがどの機能を提供しているかは、テスト用のマクロで判別できる。アラインメント機能や_Atomic
型、C言語ネイティブの原始的なスレッド機能などが、C11では省略可能な機能として追加された。また、複素数型と可変長配列はC99では必須機能であったが、C11では省略可能である。
gets
関数が廃止された。
C17
2018年にISO/IEC 9899:2018(通称・C17またはC18)として改訂された。仕様の欠陥修正がメインのマイナーアップデートである[19]。
C23
主なC言語処理系
大抵の処理系はC言語とC++双方をサポートしている。C言語とC++の共通部分を明確にし、2つの言語の違いに矛盾が生じないようにすることが課題になっている。
Linux・Windows・UNIX用
- C++ Builder
- Windows/macOS/iOS/Android対応のC/C++コンパイラBCCを含む、RADツール。以前はWindowsおよびx86のみがメインターゲットだったが、Clang/LLVMをベースに再設計され、多数のプラットフォームやアーキテクチャをサポートするようになった[20]。前身はDOS/Windows用のBorland C/C++。さらに前身としてTurbo C/C++がある。
- Clang
- LLVMをバックエンドとして用いるオープンソースのC/C++・Objective-Cコンパイラ。多数のCPUに対応。
- GNUコンパイラコレクション (GCC)
- C/C++以外の言語もサポートし、多数のCPUやオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われるオープンソースのコンパイラ。独自拡張機能も多い。
- GCC 4.5で実質的にC99を完全サポートした[21]。
- GCC 4.9で実質的にC11を完全サポートした[22]。
- Microsoft Visual C++ (MSVC)
- Windows系プラットフォーム用のC/C++コンパイラ。ANSI C準拠(バージョン2013にてC99ライブラリをほぼ実装したが、言語機能など規格自体はサポートされていない)。x86・x64が主だが、Xbox 360、Windows CE等向けにPowerPC、ARM、MIPS、Itanium等に対応した版もある。前身としてMS-DOS・Windows用のMicrosoft C Compilerがある。またその廉価版としてQuick Cがあった[23]。
- Intel C++ Compiler (ICL/ICC)
- インテル製のIA-32 (x86) およびIntel 64 (x64) 用のC/C++コンパイラ。Windows/Linux/macOS/Android向けがある。gcc互換。
- バージョン11.1まではIA-64 (Itanium) をサポートするが、バージョン12.0以降ではサポートされない[24]。
- C99[25]とC11[26]の対応リストが公開されている。バージョン18.0でC11にほぼ対応している。
- Open Watcom C/C++
- Windows・Linux・OS/2・MS-DOS・DOSエクステンダを対象とするx86用C言語・C++コンパイラ。商用だったWatcom C/C++がオープンソース化したもの。
- Portable C Compiler
- gccが普及する以前のUNIXにおける標準的C言語コンパイラ。現在はオープンソース。
- Digital Mars C/C++
- Windows・MS-DOS・DOSエクステンダを対象とするx86用のC言語・C++コンパイラ。無料版もある。ウォルター・ブライト作でDatalight C、Zorland C、Zortech C/C++、Symantec C/C++と変遷している。
組み込み用、8ビット・16ビット・32ビット・64ビットCPU用(クロスコンパイラ)
- Green Hills Software C/C++
- 組み込み向けのC言語・C++コンパイラ。 Windows用・Solaris用・Linux用があり、HP/UX用がver4ではあった。
- CodeWarrior C/C++
- 組み込み向けやゲーム機開発向けのC言語・C++コンパイラ。Classic Mac OS用として発祥、かってはWindows用・BeOS用・Palm用もあった。
- ARM C/C++
- ARM CPU用C言語・C++コンパイラ。
- IAR C/C++
- 新旧の組み込み向けCPU各種を広くカバーしていた。後に統合開発環境EW・SWに移行。使用には付属のドングルが必要だった。ARM CPU用C言語・C++コンパイラが著名。ARMをコアにした各社のCPUに対応している。
- High C
- 元はx86向けでPC/AT互換機用だが80386のネイティブモードに対応したためFM TOWNSでも標準開発環境、「High C 386」として使用された。後に各社RISC向けとなる。
- BDS-C
- CP/M(8080・Z80)用のサブセット(整数のみ)のK&R系のC言語コンパイラ。現在はパブリックドメインソフトウェア。
- Hitech-C
- Z80、PICなど。
- Lattice C
- 1980年代に、日本で高い普及率を見せたコンパイラ。解説書も多く出版されていた。日本での発売はライフボート。初期版はマイクロソフトCコンパイラ1.0として発売された。商用利用のできない個人向けの「personal」版も販売されており、これの価格は19,800円であった[27][28]
- LSI C
- 8080・Z80用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用のLSI C-86がある。8086では機能限定(スモールモデルのプログラムしか開発できず、デバッガがない)の「試食版」がフリーソフトで公開され、広く使われた。
- micro-C
- 8ビット・マイクロプロセッサMC6809用C言語サブセット・コンパイラ[29]。
- Small-C
- 元は8080向けの小型のC言語コンパイラだが派生版のクロスコンパイラとしてcc65(MOS6502用)や、z88dkなどがある。
- SDCC
- 各種8ビット・マイクロプロセッサ向けのフリーソフトウェア(GPL)のC言語クロスコンパイラ。
関連する主なプログラミング言語
先祖
- ALGOL
- ヨーロッパ生まれのアルゴリズム記述言語。PascalやC言語などに影響を与えたとされる。
- BCPL
- MULTICSで作成された高級言語。
- B言語
- 初期のUNIXで作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。
継承・拡張・サブセット
- C++
- C言語を拡張してオブジェクト指向化したもの。Simulaの影響を強く受けている。当初はC言語のスーパーセットだったが、現在は細かい部分において非互換仕様が増えている。
- Objective-C
- C言語を拡張してオブジェクト指向化したもの。C言語に Smalltalk のオブジェクトシステムを取り付けたような設計で、互換性は保たれている。C言語からの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
- Java
- C++よりも言語文法レベルでオブジェクト指向を重視した言語。バッファオーバーランなどの危険性が高いポインタといったローレベルな要素を言語文法から排除している。仮想マシン(Java VM, JVM)上で動作する。
- C#
- マイクロソフトが.NET Framework向けに開発した言語。文法はC言語およびC++に近い書式を持ち、Javaと似ている部分も存在するが、機能的にはDelphiがベースとなっている。
- Rust
- C言語およびC++に代わるシステムプログラミング言語を目指している言語。言語レベルでのRAIIの強制による自動メモリ管理機構を持ち、ガベージコレクション無しでも手動のメモリ管理が不要であり、実行性能はC/C++と同等である。
- Cyclone
- C言語の上位互換セキュア実装。ポインタの扱いを厳格化して安全面に配慮して拡張したもの。その他リージョンベースメモリ管理システム、正規表現、タグ付共用体などを追加している。
- SystemC
- ハードウェア記述言語向けに拡張したもの。書式はC++。IEEE 1666-2005。ISO 8866:1991。
- Impulse C
- ハードウェア記述言語向けに拡張したもの。書式はC。
- Unified Parallel C
- 並列計算向けにC99を拡張して作られた言語。
- Cg
- C言語をGPU上での3次元コンピュータグラフィックス処理用に特化させたもの(シェーダー言語、シェーディング言語)。NVIDIAによって開発された。
その他にも、OpenGLシェーダー言語であるGLSL、DirectX(Direct3D)シェーダー言語であるHLSL、OpenCLカーネル記述言語であるOpenCL-Cなど、C言語の文法的特徴を取り入れた派生言語やDSLが多数存在する。
注釈・出典
注釈
- ^ 英語ではC-family, C-style, C-likeなどと呼ばれる。「C系」の定義は明確ではないが、構文がCに類似しているものを指すことが多い。
- ^ 例えばポインタのエイリアシングは最適化やベクトル化を妨げる[1]。
- ^ 他の言語、例えば、BASICやPascalではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。
- ^ C89においては関数プロトタイプは必須ではない。
- ^ C89規格に準拠しないソースコードをGNU Cコンパイラでコンパイル失敗させるには、
gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c
とすれば良い(→エイリアシング)。 - ^
setjmp.h
を参照。
出典
- ^ iSUS
- ^ もう一度基礎からC言語 第19回 いろいろな演算子~ビット演算子 Cは高級アセンブラ?
- ^ 第1回 Chapter 1 C言語の概要(1):Cプログラミング入門|gihyo.jp … 技術評論社
- ^ ISO/IEC 14882:2003 §3.6.1 「The function main shall not be used within a program.」
- ^ Template:Cite Jis §3.6.1 「関数mainは、プログラムの中で挙用してはならない。」
- ^ EXP33-C. 未初期化のメモリを参照しない JPCERT/CC、2014年3月25日(2014年8月22日閲覧)。
- ^ “Memory Allocation Guide”. The Linux Kernel documentation. 2023年11月8日閲覧。
- ^ main関数 - cppreference.com
- ^ [Python入門]Pythonってどんな言語なの?:Python入門(1/2 ページ) - @IT
- ^ Hello, Worldプログラム | Programming Place Plus C言語編 第2章
- ^ Portability of C Programs and the UNIX Systems
- ^ a b The Evolution of the Unix Time-sharing System
- ^ [\{{URhttp://japan.zdnet.com/glossary/exp/%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%AC%E3%83%99%E3%83%AB%E4%BA%92%E6%8F%9B/?s=4|ソースレベル互換}} - ZDNet Japan
- ^ http://www.tohoho-web.com/ex/draft/kanji.htm
- ^ Rust言語でAndroidはより強固・安全に ~GoogleがOS開発への導入を進める - 窓の杜
- ^ Microsoft、Windows 10の一部をRustへ書き換えてセキュリティ強化狙う - TECH+
- ^ C FAQ 11
- ^ 6.19 Arrays of Variable Length
- ^ C の歴史 - cppreference.com
- ^ Clang 拡張 C++ コンパイラ - RAD Studio
- ^ Status of C99 features in GCC - GNU Project - Free Software Foundation (FSF)
- ^ C11Status - GCC Wiki
- ^ “Microsoft Releases C Program Wares, Provides Rebates”. InfoWorld: p. 29. (November 9, 1987)
- ^ インテル® C++ Composer XE 2011 Windows* 版インストール・ガイドおよびリリースノート - w_ccompxe_2011.7.258_Release_Notes_ja_JP.pdf
- ^ C99 Support in Intel® C++ Compiler | Intel® Software
- ^ C11 Support in Intel C++ Compiler | Intel® Software
- ^ 脇英世(監修)、1987、『パソコンの常識事典』、日本実業出版社 pp. 339、342 - 普及率、解説書の多さについて。
- ^ 長沢英夫(編)、1988、『パソコンベストソフトカタログ』、JICC出版局 pp. 201 - Personal版、解説書の多さについて。
- ^ ucom10 1983, p. 80.
参考文献
2025年現在、初心者向けのイラスト入り入門書やサブルーチンのサンプル集の他、組み込み機器の制御や科学技術計算など目的を特化した専門書なども多数ある。便利な機能の説明はあっても、学習者の水準や目的にあった本を見つけるのは必ずしも容易でない。オープンソースのCコンパイラ、OSも大規模なものがあり、直接読み始めるのは困難になっている。オープンソースのOSの小規模なものから始めるとよい。
- プログラミング言語C
- ブライアン・カーニハン、デニス・リッチー 共著、石田晴久訳、共立出版。
- 「K&R」として知られている「The C Programming Language」の邦訳。入門書ではなく、特にプログラミングそのものが初めてという読者には不適である。初版と第2版があり、第2版が現在も時折増刷されている(邦訳では事情により、原書第2版を基とした版には旧版と改訂新版がある。旧版は装丁が緑地で新版は白地である)。標準の制定以前は本書初版を言語仕様の参考文献として扱っていたが、現在はISOなどの標準規格を参照すべきであり、本書の記述は参考にとどめるべきである。なお、日本工業規格(現・日本産業規格)のJIS X 3010:2003「プログラム言語C」は、ISO/IEC JTC1 SC22 WG14+ISO/IEC 9899:1999 Cor. 1:2001(E)つまりC99の和訳相当で、2021年8月現在の最新規格であるISO/IEC 9899:2018との乖離を生じている。
- Cプログラミングの落とし穴
- コーニグ、中村明訳、新紀元社
- Cプログラミングで嵌まるところを指摘している。MISRA Cでも参考文献になっている。
- Cパズルブック
- アラン・R. フューアー、田中和明訳、カットシステム
- Cプログラミングの芸当を示し、読み書きを推奨しない例を示している。
- 『マイコンピュータ No.10』CQ出版社、1983年9月1日。
- 入門特集 C言語の研究
外部リンク
ウィキメディア・コモンズには、C言語に関するメディアがあります。
- 日本語
- C言語リファレンス - cppreference.com - 標準C/C++のオンライン言語リファレンス
- 英語
- ISO C Working Group
- The Development of the C Language - C言語がどのように開発されたかがわかる英文の文書
- stdio.h on Coding Programmer Page / C Library Reference and Examples - C Reference
ローマ数字
![]() | この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。(2016年12月) |
ローマ数字(ローマすうじ)は、数を表す記号の一種である。ラテン文字の一部を用い、例えばアラビア数字における 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 をそれぞれ I, II, III, IV, V, VI, VII, VIII, IX, X のように表記する。I, V, X, L, C, D, Mはそれぞれ 1, 5, 10, 50, 100, 500, 1000 を表す。i, v, x などと小文字で書くこともある。現代の一般的な表記法では、1以上4000未満の数を表すことができる。
ローマ数字のことをギリシャ数字と呼ぶ例が見られるが、これは誤りである。
表記法
古代ローマにおいて成立し、中世後期までヨーロッパで一般的に用いられていた表記法。ただしこれを規定する公式な、あるいは広く知られた標準となる表記法は存在していない[注 1]。 16世紀頃からはアラビア数字での表記が一般的になったが、特定の場面においては現代でも用いられている。
十進法に基づいている。 数を10の冪ごとに、つまり 1000の位の量 + 100の位の量 + 10の位の量 + 1の位の量 と分解し、左からこの順番に書き下す。この際、空位の0は書かれることはない。位ごとに異なる記号が用いられるが、記号の組み合わせのパターンは共通である。
ローマ数字 | I | V | X | L | C | D | M |
---|---|---|---|---|---|---|---|
アラビア数字 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
それぞれの位の量は更に上記の数字の和に分解され、大きい順に並べて書かれる。5未満はIの繰り返しで表され、5以上はVにIをいくつか加える形で表される。(画線法)
また、小さい数を大きい数の左に書くこともあり、この場合右から左を減ずることを意味する。これを減算則という。
ローマ数字 | IV | IX | XL | XC | CD | CM |
---|---|---|---|---|---|---|
アラビア数字 | 4 | 9 | 40 | 90 | 400 | 900 |
これらの数は減算則を使わず表現することも可能(例:4 を「IIII」、9を「VIIII」)だが、通常は減算則を用いて表記する。なお、減算則が用いられるのは4 (40, 400) と9 (90, 900) を短く表記する場合だけであり、それ以外で使うことは通常行われない(例外は#異表記を参照のこと)。つまり、8を「IIX」と表記したり、位ごとの分離を破って45を「VL」、999を「IM」と表記することは基本的でない書き方とされる。
以上を踏まえると、1 から 9 とその 10 倍と 100 倍、および1000、2000、3000は以下のような表記となる。
×1 | ×10 | ×100 | ×1000 | |
---|---|---|---|---|
1 | I | X | C | M |
2 | II | XX | CC | MM |
3 | III | XXX | CCC | MMM |
4 | IV | XL | CD | [注 2] |
5 | V | L | D | |
6 | VI | LX | DC | |
7 | VII | LXX | DCC | |
8 | VIII | LXXX | DCCC | |
9 | IX | XC | CM |
これらを組み合わせることで、1 から 3999 の値が表現できる。だが言い換えれば、(パターンを守ろうとすると)4000以上の数値を表すことは不可能である。また、0 を表す記号は存在しない。このため、 0 の値が入る桁の数値は表記せず、そのまま空位とする。
また、整数と小数が一貫しておらず、整数が十進法(二五進法)である一方、小数には十二進法が適用され、1/12や1/144の小数が作られている。
小数は、3/12 (= 1/4)が「点3つ」、6/12 (= 1/2)が「S」、9/12 (= 3/4)が「Sに点3つ」として、六で一旦繰り上がる方法で表記されている。
ローマ数字の並べ方の例
12 | = | 10 × 1 | + | 1 × 2 | |||||||
= | X | + | II | ||||||||
= | XII | ||||||||||
24 | = | 10 × 2 | + | (−1 + 5) | |||||||
= | XX | + | IV | ||||||||
= | XXIV | ||||||||||
42 | = | (−10 + 50) | + | 1 × 2 | |||||||
= | XL | + | II | ||||||||
= | XLII | ||||||||||
49 | = | (−10 + 50) | + | (−1 + 10) | |||||||
= | XL | + | IX | ||||||||
= | XLIX | ||||||||||
89 | = | 50 | + | 10 × 3 | + | (−1 + 10) | |||||
= | L | + | XXX | + | IX | ||||||
= | LXXXIX | ||||||||||
299 | = | 100 × 2 | + | (−10 + 100) | + | (−1 + 10) | |||||
= | CC | + | XC | + | IX | ||||||
= | CCXCIX | ||||||||||
302 | = | 100 × 3 | + | (10 × 0) | + | 1 × 2 | |||||
= | CCC | + | + | II | |||||||
= | CCCII | ||||||||||
493 | = | (−100 + 500) | + | (−10 + 100) | + | 1 × 3 | |||||
= | CD | + | XC | + | III | ||||||
= | CDXCIII | ||||||||||
1960 | = | 1000 × 1 | + | (−100 + 1000) | + | 50 | + | 10 | + | (1 × 0) | |
= | M | + | CM | + | L | + | X | ||||
= | MCMLX | ||||||||||
3999 | = | 1000 × 3 | + | (−100 + 1000) | + | (−10 + 100) | + | (−1 + 10) | |||
= | MMM | + | CM | + | XC | + | IX | ||||
= | MMMCMXCIX | ||||||||||
なお、手書きでは、大文字のローマ数字は上下のセリフをつなげて書くことが多い。「V」は上部のセリフをつなぎ、逆三角形(▽)のようになる。小文字ではセリフを書かない。
時計の文字盤での表記
時計の文字盤は伝統的に4時を「IIII」と表記することが多い。その由来には下記のように様々な説が唱えられているが定説はない。なお、9時は通常表記の「IX」の場合が多い。また、4時を通常表記の「IV」と表記している時計も存在しており、この表記方法は絶対的な物ではない(同様に、9時を「VIIII」と表記している時計も存在する)。
- ローマ神話の最高神・ユピテル (IVPITER) の最初の2文字と重なるのを避けるため。
- 4を「IV」と書くと「VI」と見分けにくいため。
- 「IIII」ならば「I」という刻印を4回押せば文字盤の文字が作れるが、「IV」だと専用の型が必要になる。
- 専用の文字を使うのは、ちょうど間が4時間おきになる V と X だけのほうがいい。
- 「IIII」にすれば左側の「VIII」と文字数が釣り合い、見栄えがよい。
- 特定の有力なローマの時計製造者が「IIII」と書いた時計を作ったため、他の製造者もそれに倣った。
- ルイ14世が、文字盤に「IV」を用いることを禁じた。
- シャルル4世が、「IV」を用いることを禁じた。
異表記

- 減算の文字を複数並べる。(例)8 = IIX,80 = XXC
- 500 に「D」を使わない。(例)1611 = MCCCCCCXI
- 減算を行わない。(例)1495 = MCCCCLXXXXV
- 任意の自然数 n に対し、10n を表す文字の前に、5m10n − 2 (m = 0, 1) 以下を表す文字を使う。(例)490 = -10 + 500 = XD
- 簡略表記。Microsoft Excel の ROMAN 関数で「書式4」を使用。(例)999 = IM
ローマ数字はもともと厳密な規則が定義されたものではなく、特に減算則に関しては様々な異表記が見られる。当初は減算則が存在しなかったため、4 を「IIII」、9 を「VIIII」と書いていた。「The Forme of Cury」(14世紀の著名な英語の料理解説書)は 4 = IIII、9 = IXと表記している一方で「IV」と表記した箇所もある。
ほかに、80 = R、2000 = Zとする異表記もある。また、1⁄2 = S、1⁄12 = • などとする分数の記号もあった。
4000以上の大きな数字
前述の通り、4000以上の数値の表記は、パターンに従った通常の方法では不可能であり、1 から 3999 の数値までしか表記できない。現代ではあまり使用されないが、4000以上の表記は下記の方法によって行う。
- 重ね表記
1000 を表すのに「M」ではなく「ↀ」または「CIↃ」を用いる場合もある。5000 を「ↁ」または「IↃↃ」、10000 を「ↂ」または「CCIↃↃ」で表した例もある。同様にして 50000 は「ↇ」または「IↃↃↃ」、100000 は「ↈ」または「CCCIↃↃↃ」となる。
基本数字 | C|Ɔ (M) = 1,000 | CC|ƆƆ = 10,000 | CCC|ƆƆƆ = 100,000 |
+ |Ɔ (D) = 500 | C|Ɔ|Ɔ (MD) = 1,500 | CC|ƆƆ|Ɔ = 10,500 | CCC|ƆƆƆ|Ɔ = 100,500 |
+ |ƆƆ = 5,000 | - | CC|ƆƆ|ƆƆ = 15,000 | CCC|ƆƆƆ|ƆƆ = 105,000 |
+ |ƆƆƆ = 50,000 | - | - | CCC|ƆƆƆ|ƆƆƆ = 150,000 |
- つなぎ表記
- 通常のローマ数字に上線を付加することで、1,000 倍を表現する。また二重上線では 1,000,000 倍となる。すなわちn重の上線は 1,000n (1,000のn乗)倍を表す。
- 4,000 = IV = MV
- 5,300 = VCCC
- 6,723 = VIDCCXXIII = VMDCCXXIII
- 9,999 = IXCMXCIX = MXCMXCIX
- 51,200 = LICC
- 99,999 = XCIXCMXCIX
- 500,000 = DI
- 921,600 = CIXXIDC
- 3,000,000 = III
- 9,125,334 = IXCCXXVCCCXXXIV
- 91,200,937 = XCICCCMXXXVII
- 235,002,011 = CCXXXVIIXI
- 前後に縦線を付加することで、さらに 100 倍(都合 100,000 倍)を表す。
- 800,000 = |VIII|
- 1,040,000 = |X|XL (= 10 × 1,000 × 100 + (-10 + 50) × 1,000) = IXL (= 1 × 1,000,000 + (-10 + 50) × 1,000)
用途

現在、ローマ数字は序数、章番号、ページ番号、文章の脚注番号などに使うことが多いが、酸化銅(II)など一部例外がある[2]。
- 英語圏では、ローマ教皇や国王の名前に使用される。
- イギリスでは、大学の学年表記の他、英国放送協会(BBC)が番組の製作年を表すのにローマ数字を使っており、エンドクレジットの最後で下部分に「MMXIII (2013)」などと表示される。
- 1980年代ごろまでは映画の著作権表示の制作年にローマ数字が使われることが多かった。例えば、1983年に発売されたタイトーの業務用ゲーム『エレベーターアクション』の著作権表記は「© TAITO CORP. MCMLXXXIII」となっている。
- 音楽理論では、音階の中での音の位置を表すのにローマ数字を用いる。最もよく用いられるのは和音の調の中での位置を表す時である。大文字と小文字は場合によって様々な意味で使い分けられる。手書きでは「i」の点を打たないのが普通である(それはしかも逆感嘆符である「¡」と見分けにくいという欠点もある)。
- 日本の公営競技の確定板でも、着順の表示に用いられている。
- 競馬の「GIレース」など、グレードを示す際にも利用される(グレード制)。
- 高等学校数学の科目名や大学入試類型など、教育部門で使用されている面が見られる。
- 『ドラゴンクエストII 悪霊の神々』や『ファイナルファンタジーIII』など、コンピュータゲームの続編ではローマ数字を使用したものがある。
- 陸上自衛隊の第14旅団、第15旅団などは部隊章にローマ数字を使用している。
ローマ数字の歴史
![]() | この節は検証可能な参考文献や出典が全く示されていないか、不十分です。(2016年12月) |
古代ローマ人は元々農耕民族だった。羊の数を数えるのに木の棒に刻み目を入れた。柵から1匹ずつヤギが出て行くたびに刻み目を1つずつ増やしていった。3匹目のヤギが出て行くと「III」と表し、4匹目のヤギが出て行くと3本の刻み目の横にもう1本刻み目を増やして「IIII」とした。5匹目のヤギが出て行くと、4本目の刻み目の右にこのときだけ「V」と刻んだ(∧と刻んだ羊飼いもいた)。このときの棒についた刻み目は「IIIIV」となる。6匹目のヤギが出て行くと、刻み目の模様は「IIIIVI」、7匹目が出て行くと「IIIIVII」となる。9匹目の次のヤギが出て行くと「IIIIVIIII」の右に「X」という印を刻んだ。棒の模様は「IIIIVIIIIX」となる。31匹のヤギは「IIIIVIIIIXIIIIVIIIIXIIIIVIIIIXI」と表す。このように刻んだのは、夕方にヤギが1匹ずつ戻ってきたときに記号の1つ1つがヤギ1匹ずつに対応していたほうが便利だったためである。ヤギが戻ると、記号を指で端から1個1個たどっていった。最後のヤギが戻るときに指先が最後の記号にふれていれば、ヤギは全部無事に戻ったことになる。50匹目のヤギはN、+または⊥で表した。100匹目は*で表した。これらの記号はローマのそばのエトルリア人も使った。エトルリアのほうが文明が栄えていたので、そちらからローマに伝わった可能性もある。1000は○の中に十を入れた記号で表した。
よく言われる「X」は「V」を2つ重ねて書いたもの、あるいは「V」は「X」の上半分という説は、誤りとは言い切れないが確たる根拠もないようである。
やがて時代が下り、羊以外のものも数えるようになると、31は単に「XXXI」と書くようになった。5はしばらく「V」と「∧」が混在して使われた。50は当初N、И、K、Ψ、などと書き、しばらく「⊥」かそれに似た模様を使ったが、アルファベットが伝わると混同して「L」となった。100は*だけでなくЖ、Hなどと書いたが、*がしだいに離れて「>|<」や「⊃|⊂」になり、よく使う数なので簡略になり、「C」や「⊃」と書きそのまま残った(ラテン語の"centum=100"が起源という説もある)。500は最初、1000を表す「⊂|⊃」から左の⊂を外し、「|⊃」と書いた。やがて2つの記号がくっつき、「D」となった。「D」の真ん中に横棒がついて「D」や「Ð」とも書いた。1000は○に十の記号が省略されて「⊂|⊃」となった。「∞」と書いた例もある。これが全部くっついたのが「Φ」に似た記号である。これが別の変形をし上だけがくっついて「m」に似た形になり、アルファベットが伝わると自然と「M」と書かれるようにもなった(ラテン語の"mille=1000"からも考慮されている)。そのため、1000は今でも2つの表記法が混在している。
5000以上の数は100と1000の字体の差から自然に決まった。ただし、「凶」を上下逆に書いた形(X)で1000000 (100万)を表したこともある。
古代ローマ共和国時代の算盤では、記号の上に横棒を引いて1000倍を表したものもある。この方法では、10000は「X」の上に横棒を1本引いたもので表される。100000 (10万) や1000000 (100万) は「C」や「M」の上に横棒を1本を引いて表した。たとえば10000は「X」となる。
例:CCX[注 3] = 210000 (21万)
数字の上部分に「 ̄」・左右に「|」をそれぞれつけて10万倍を表すこともあった(上と左右の線をくっつけて表記することも多い)。たとえば10(X)を10万倍した数=1000000 (100万) は、「X」と表記する。
例:
その後、他の文明との接触により変わった表記法が現れた。1世紀、プリニウスは著書『博物誌』で83000を「LXXXIII.M[注 6]」と表記した。83.1000 (83の1000倍) という書き方である。同じ文書中に、XCII.M [注 7](92000)、VM [注 8](5000) という表記もある。この乗算則はしばらく使われたようである。1299年に作成された『王フィリップ4世の財宝帳簿』では、5316を「VmIIIcXVI[注 9]」と表した。漢数字の書き方によく似ている。ただしこれらの乗算則は現在は使われない。
1000を超える数の表記法に混乱があるのは一般人は巨大な数を扱う機会がなかったためと考えられる。
その他
- Microsoft Excel のROMANという関数は 0 から 3999 までの数をローマ数字に変換する。範囲外の数ではエラー値「#VALUE!」が表示される。なお、0の場合はエラー値でなく空文字列を返す。
- 英語で100 ドル札を「C-bill」や「C-note」と呼ぶのはローマ数字の C に由来する[要出典]。
文字コードにおけるローマ数字
基本的には通常のラテン文字を並べてローマ数字を表現する。Unicode 以前から欧米で一般的に使用されている ISO/IEC 8859 などの文字コードは、ローマ数字専用の符号を持っていない。
JIS規格
日本で用いられる文字コードとしても、JIS X 0208 にはローマ数字専用の符号は定義されていない。これを拡張した Microsoftコードページ932 (CP932) や MacJapanese などにおいて、いわゆる機種依存文字として定義されており、追って JIS X 0213 にも取り入れられた。CP932 にあるのは大文字 I から X と小文字 i から x の合成済み 20 字 (1 から 10 に相当)、MacJapanese にあるのは 大文字 I から XV と小文字 i から xv の合成済み 30 字 (1 から 15 に相当)、JIS X 0213 は大文字 I から XII と小文字 i から xii の合成済み 24 字 (1 から 12 に相当) である。これらは縦書きの組版の際に縦中横を容易に実現するために用いられ(一般の組版ルールでローマ数字は縦中横である)、多くのフォントで全角文字としてデザインされる。
Unicode
Unicode は、JIS X 0213 などとの互換性のために上述の合成済みローマ数字を収録した上、その延長として Ⅼ, Ⅽ, Ⅾ, Ⅿ, ⅼ, ⅽ, ⅾ, ⅿ[注 10]、また通常のラテン文字にない Ↄ, ↄ, ↀ, ↁ, ↂ, ↇ, ↈ, ↅ, ↆ [注 11]も定義している。これらは U+2160 から U+2188 までの符号位置を割り当てられている。(Unicode 7.0.0 時点)〈登録領域〉Number Form(数字に準じるもの)
機械処理の注意点
ラテン文字と共通の符号を用いるため、「I」「V」「X」「L」「C」「D」「M」が機械処理の際にアルファベットそのものを表しているのか、数字の「1」「5」「10」「50」「100」「500」「1000」を表しているのか解釈を誤る場合がある。
符号位置
Unicodeに存在しないMacJapaneseのローマ数字 (XIII, XIV, XV, xiii, xiv, xv) は、Unicodeの私用領域にAppleが独自に定義した制御文字の後ろに組文字を構成する文字を続けることで表される[3]。
大文字 | Unicode | JIS X 0213 | 文字参照 | 小文字 | Unicode | JIS X 0213 | 文字参照 | 備考 |
---|---|---|---|---|---|---|---|---|
Ⅰ | U+2160
|
1-13-21
|
Ⅰ Ⅰ
|
ⅰ | U+2170
|
1-12-21
|
ⅰ ⅰ
|
ローマ数字1 |
Ⅱ | U+2161
|
1-13-22
|
Ⅱ Ⅱ
|
ⅱ | U+2171
|
1-12-22
|
ⅱ ⅱ
|
ローマ数字2 |
Ⅲ | U+2162
|
1-13-23
|
Ⅲ Ⅲ
|
ⅲ | U+2172
|
1-12-23
|
ⅲ ⅲ
|
ローマ数字3 |
Ⅳ | U+2163
|
1-13-24
|
Ⅳ Ⅳ
|
ⅳ | U+2173
|
1-12-24
|
ⅳ ⅳ
|
ローマ数字4 |
Ⅴ | U+2164
|
1-13-25
|
Ⅴ Ⅴ
|
ⅴ | U+2174
|
1-12-25
|
ⅴ ⅴ
|
ローマ数字5 |
Ⅵ | U+2165
|
1-13-26
|
Ⅵ Ⅵ
|
ⅵ | U+2175
|
1-12-26
|
ⅵ ⅵ
|
ローマ数字6 |
Ⅶ | U+2166
|
1-13-27
|
Ⅶ Ⅶ
|
ⅶ | U+2176
|
1-12-27
|
ⅶ ⅶ
|
ローマ数字7 |
Ⅷ | U+2167
|
1-13-28
|
Ⅷ Ⅷ
|
ⅷ | U+2177
|
1-12-28
|
ⅷ ⅷ
|
ローマ数字8 |
Ⅸ | U+2168
|
1-13-29
|
Ⅸ Ⅸ
|
ⅸ | U+2178
|
1-12-29
|
ⅸ ⅸ
|
ローマ数字9 |
Ⅹ | U+2169
|
1-13-30
|
Ⅹ Ⅹ
|
ⅹ | U+2179
|
1-12-30
|
ⅹ ⅹ
|
ローマ数字10 |
大文字 | Unicode | JIS X 0213 | 文字参照 | 小文字 | Unicode | JIS X 0213 | 文字参照 | 備考 |
---|---|---|---|---|---|---|---|---|
Ⅺ | U+216A
|
1-13-31
|
Ⅺ Ⅺ
|
ⅺ | U+217A
|
1-12-31
|
ⅺ ⅺ
|
ローマ数字11 |
Ⅻ | U+216B
|
1-13-55
|
Ⅻ Ⅻ
|
ⅻ | U+217B
|
1-12-32
|
ⅻ ⅻ
|
ローマ数字12 |
大文字 | Unicode | JIS X 0213 | 文字参照 | 小文字 | Unicode | JIS X 0213 | 文字参照 | 備考 |
---|---|---|---|---|---|---|---|---|
Ⅼ | U+216C
|
‐
|
Ⅼ Ⅼ
|
ⅼ | U+217C
|
‐
|
ⅼ ⅼ
|
ローマ数字50 |
Ⅽ | U+216D
|
‐
|
Ⅽ Ⅽ
|
ⅽ | U+217D
|
‐
|
ⅽ ⅽ
|
ローマ数字100 |
Ⅾ | U+216E
|
‐
|
Ⅾ Ⅾ
|
ⅾ | U+217E
|
‐
|
ⅾ ⅾ
|
ローマ数字500 |
Ⅿ | U+216F
|
‐
|
Ⅿ Ⅿ
|
ⅿ | U+217F
|
‐
|
ⅿ ⅿ
|
ローマ数字1000 |
Ↄ | U+2183
|
‐
|
Ↄ Ↄ
|
ↄ | U+2184
|
‐
|
ↄ ↄ
|
ローマ数字逆100 |
記号 | Unicode | JIS X 0213 | 文字参照 | 名称 |
---|---|---|---|---|
ↀ | U+2180 |
‐ |
ↀ ↀ |
ローマ数字1000 C D |
ↁ | U+2181 |
‐ |
ↁ ↁ |
ローマ数字5000 |
ↂ | U+2182 |
‐ |
ↂ ↂ |
ローマ数字10000 |
ↇ | U+2187 |
‐ |
ↇ ↇ |
ローマ数字50000 |
ↈ | U+2188 |
‐ |
ↈ ↈ |
ローマ数字100000 |
ↅ | U+2185 |
‐ |
ↅ ↅ |
ローマ数字6 LATE FORM |
ↆ | U+2186 |
‐ |
ↆ ↆ |
ローマ数字50 EARLY FORM |
記号の再現 | MacJapanese | 記号の再現 | MacJapanese | 名称 |
---|---|---|---|---|
XIII | 0x85AB | xiii | 0x85BF | ローマ数字13 |
XIV | 0x85AC | xiv | 0x85C0 | ローマ数字14 |
XV | 0x85AD | xv | 0x85C1 | ローマ数字15 |
脚注
注釈
- ^ 書き方ではなく読み方については以下の事例が参考になる――著作権法 (アメリカ合衆国)においてローマ数字による発行年表示が有効なものであるとされていて、不正なローマ数字は著作権表示を無効化しうる[1]。この際、下記のような書き方ルールに合致しているかどうかは問題とされない。
- ^ 詳しくは#4000以上の大きな数字を参照。
- ^ = [{(100 × 2) + 10} × 1000] = 210 × 1000 = 210000 (21万)
- ^ = [{1000 + 100 + 50 + (1 × 2)} × 100000] + [{(10 × 3) + 5 + (1 × 2)} × 1000] + {(100 × 2) + (10 × 3) + (1 × 2)} = 1152 × 100000 + 37 × 1000 + 232 = 115200000 (1億1520万) + 37000 + 232 = 115237232 (1億1523万7232)
- ^ = [{(1000 × 2) + (100 × 3) + (10 × 2) + (1 × 2)} × 100000] + (((50 + (10 × 2)) + 1) × 1000) + [(100 × 2) + (10 × 3) + {5 + (1 × 3)}] = 2322 × 100000 + 71 × 1000 + 238 = 232200000 (2億3220万) + 71000 + 238 = 232271238 (2億3227万1238)
- ^ = [{50 + (10 × 3)} × 1000] = 83 × 1000 = 83000
- ^ = [{(100 − 10) + 2} × 1000] = 92 × 1000 = 92000
- ^ = 5 × 1000 = 5000
- ^ = [(5 × 1000) + {(1 × 3) × 100} + (10 + 5 + 1)] = 5000 + 300 + 16 = 5316
- ^ 〔大文字〕U+216C, 216D, 216E, 216F〔小文字〕U+217C, 217D, 217E, 217F
- ^ (左から順に) U+2183, 2184, 2180, 2181, 2182, 2187, 2188, 2185, 2186
出典
- ^ Hayes, David P.. “Guide to Roman Numerals”. Copyright Registration and Renewal Information Chart and Web Site. 2021年11月29日閲覧。
- ^ 比留間直和 (2012年10月1日). “いつ使う?ローマ数字 - ことばマガジン”. 朝日新聞デジタル. 朝日新聞社. 2021年11月29日閲覧。
- ^ UnicodeコンソーシアムにあるMac OS Japaneseとの変換テーブル
関連項目
上付き文字
上付き文字(うえつきもじ、英: superscript)は、基準となる文字より上部に記述される添え字である。
数学における冪乗を表す目的や、化学におけるイオン価数を表す目的、原子核物理学・放射線医学などにおける放射性同位元素の質量数を表す目的として使われるほか、文書における脚注参照、単位記号、TMなどの一部記号、発音記号などとしても用いられる。
冪乗の目的で使用される場合は、イオン価数の目的で使用される文字よりも上部に表記される。
フランス語、イタリア語、スペイン語などのロマンス諸語では、数字に上付きで e もしくは o/a を付記し、序数とその性を表示する。Unicode では、序数標識 º と ª が用意されている。これらは音楽などにも流用され、たとえばtempo primo(テンポプリーモ)をtempo 1ºと表記する。
HTMLのタグで表記する場合は<sup>上付き文字</sup>
が使用される。
符号位置
大文字 | Unicode | JIS X 0213 | 文字参照 | 小文字 | Unicode | JIS X 0213 | 文字参照 | 備考 |
---|---|---|---|---|---|---|---|---|
ᴬ | U+1D2C
|
-
|
ᴬ ᴬ
|
ᵃ | U+1D43
|
-
|
ᵃ ᵃ
|
A |
ᴮ | U+1D2E
|
-
|
ᴮ ᴮ
|
ᵇ | U+1D47
|
-
|
ᵇ ᵇ
|
B |
ᴰ | U+1D30
|
-
|
ᴰ ᴰ
|
ᵈ | U+1D48
|
-
|
ᵈ ᵈ
|
D |
ᴱ | U+1D31
|
-
|
ᴱ ᴱ
|
ᵉ | U+1D49
|
-
|
ᵉ ᵉ
|
E |
ᴳ | U+1D33
|
-
|
ᴳ ᴳ
|
ᵍ | U+1D4D
|
-
|
ᵍ ᵍ
|
G |
ᴴ | U+1D34
|
-
|
ᴴ ᴴ
|
ʰ | U+02B0
|
-
|
ʰ ʰ
|
H |
ᴵ | U+1D35
|
-
|
ᴵ ᴵ
|
ⁱ | U+2071
|
-
|
ⁱ ⁱ
|
I |
ᴶ | U+1D36
|
-
|
ᴶ ᴶ
|
ʲ | U+02B2
|
-
|
ʲ ʲ
|
J |
ᴷ | U+1D37
|
-
|
ᴷ ᴷ
|
ᵏ | U+1D4F
|
-
|
ᵏ ᵏ
|
K |
ᴸ | U+1D38
|
-
|
ᴸ ᴸ
|
ˡ | U+02E1
|
-
|
ˡ ˡ
|
L |
ᴹ | U+1D39
|
-
|
ᴹ ᴹ
|
ᵐ | U+1D50
|
-
|
ᵐ ᵐ
|
M |
ᴺ | U+1D3A
|
-
|
ᴺ ᴺ
|
ⁿ | U+207F
|
-
|
ⁿ ⁿ
|
N |
ᴼ | U+1D3C
|
-
|
ᴼ ᴼ
|
ᵒ | U+1D52
|
-
|
ᵒ ᵒ
|
O |
ᴾ | U+1D3E
|
-
|
ᴾ ᴾ
|
ᵖ | U+1D56
|
-
|
ᵖ ᵖ
|
P |
ᴿ | U+1D3F
|
-
|
ᴿ ᴿ
|
ʳ | U+02B3
|
-
|
ʳ ʳ
|
R |
ᵀ | U+1D40
|
-
|
ᵀ ᵀ
|
ᵗ | U+1D57
|
-
|
ᵗ ᵗ
|
T |
ᵁ | U+1D41
|
-
|
ᵁ ᵁ
|
ᵘ | U+1D58
|
-
|
ᵘ ᵘ
|
U |
ⱽ | U+2C7D
|
-
|
ⱽ ⱽ
|
ᵛ | U+1D5B
|
-
|
ᵛ ᵛ
|
V |
ᵂ | U+1D42
|
-
|
ᵂ ᵂ
|
ʷ | U+02B7
|
-
|
ʷ ʷ
|
W |
記号 | Unicode | JIS X 0213 | 文字参照 | 名称 |
---|---|---|---|---|
ᶜ | U+1D9C |
- |
ᶜ ᶜ |
C |
ᶠ | U+1DA0 |
- |
ᶠ ᶠ |
F |
ˢ | U+02E2 |
- |
ˢ ˢ |
S |
ˣ | U+02E3 |
- |
ˣ ˣ |
X |
ʸ | U+02B8 |
- |
ʸ ʸ |
Y |
ᶻ | U+1DBB |
- |
ᶻ ᶻ |
Z |
⁰ | U+2070 |
- |
⁰ ⁰ |
SUPERSCRIPT ZERO |
¹ | U+00B9 |
1-9-16 |
¹ ¹ |
SUPERSCRIPT ONE |
² | U+00B2 |
1-9-12 |
² ² |
SUPERSCRIPT TWO |
³ | U+00B3 |
1-9-13 |
³ ³ |
SUPERSCRIPT THREE |
⁴ | U+2074 |
- |
⁴ ⁴ |
SUPERSCRIPT FOUR |
⁵ | U+2075 |
- |
⁵ ⁵ |
SUPERSCRIPT FIVE |
⁶ | U+2076 |
- |
⁶ ⁶ |
SUPERSCRIPT SIX |
⁷ | U+2077 |
- |
⁷ ⁷ |
SUPERSCRIPT SEVEN |
⁸ | U+2078 |
- |
⁸ ⁸ |
SUPERSCRIPT EIGHT |
⁹ | U+2079 |
- |
⁹ ⁹ |
SUPERSCRIPT NINE |
⁺ | U+207A |
- |
⁺ ⁺ |
SUPERSCRIPT PLUS SIGN |
⁻ | U+207B |
- |
⁻ ⁻ |
SUPERSCRIPT MINUS |
⁼ | U+207C |
- |
⁼ ⁼ |
SUPERSCRIPT EQUALS SIGN |
⁽ | U+207D |
- |
⁽ ⁽ |
SUPERSCRIPT LEFT PARENTHESIS |
⁾ | U+207E |
- |
⁾ ⁾ |
SUPERSCRIPT RIGHT PARENTHESIS |
ª | U+00AA |
1-9-7 |
ª ª |
FEMININE ORDINAL INDICATOR |
ᵃ | U+1D43 |
- |
ᵃ ᵃ |
MODIFIER LETTER SMALL TURNED A |
ᵅ | U+1D45 |
- |
ᵅ ᵅ |
MODIFIER LETTER SMALL ALPHA |
ᶛ | U+1D9B |
- |
ᶛ ᶛ |
MODIFIER LETTER SMALL TURNED ALPHA |
ᴭ | U+1D2D |
- |
ᴭ ᴭ |
MODIFIER LETTER CAPITAL AE |
ᵆ | U+1D46 |
- |
ᵆ ᵆ |
MODIFIER LETTER SMALL TURNED AE |
ᴯ | U+1D2F |
- |
ᴯ ᴯ |
MODIFIER LETTER CAPITAL BARRAD B |
ᵝ | U+1D5D |
- |
ᵝ ᵝ |
MODIFIER LETTER SMALL BETA |
ᶝ | U+1D9D |
- |
ᶝ ᶝ |
MODIFIER LETTER SMALL C WITH CURL |
ᶞ | U+1D9E |
- |
ᶞ ᶞ |
MODIFIER LETTER SMALL ETH |
ᵞ | U+1D5E |
- |
ᵞ ᵞ |
MODIFIER LETTER SMALL GREEK GAMMA |
ᵟ | U+1D5F |
- |
ᵟ ᵟ |
MODIFIER LETTER SMALL DELTA |
ᵋ | U+1D4B |
- |
ᵋ ᵋ |
MODIFIER LETTER SMALL OPEN E |
ᵌ | U+1D4C |
- |
ᵌ ᵌ |
MODIFIER LETTER SMALL TURNED OPEN E |
ᶟ | U+1D9F |
- |
ᶟ ᶟ |
MODIFIER LETTER SMALL REVERSED OPEN E |
ᴲ | U+1D32 |
- |
ᴲ ᴲ |
MODIFIER LETTER CAPITAL REVERSED E |
ᵊ | U+1D4A |
- |
ᵊ ᵊ |
MODIFIER LETTER SMALL SCHWA |
ᶡ | U+1DA1 |
- |
ᶡ ᶡ |
MODIFIER LETTER SMALL DOTLESS J WITH STROKE |
ᶣ | U+1DA3 |
- |
ᶣ ᶣ |
MODIFIER LETTER SMALL TURNED H |
ᶤ | U+1DA4 |
- |
ᶤ ᶤ |
MODIFIER LETTER SMALL I WITH STROKE |
ᶥ | U+1DA5 |
- |
ᶥ ᶥ |
MODIFIER LETTER SMALL IOTA |
ᶦ | U+1DA6 |
- |
ᶦ ᶦ |
MODIFIER LETTER SMALL CAPITAL I |
ᵎ | U+1D4E |
- |
ᵎ ᵎ |
MODIFIER LETTER SMALL TURNED I |
ᶧ | U+1DA7 |
- |
ᶧ ᶧ |
MODIFIER LETTER SMALL CAPITAL I WITH STROKE |
ᶨ | U+1DA8 |
- |
ᶨ ᶨ |
MODIFIER LETTER SMALL J WITH CROSSED-TAIL |
ᶩ | U+1DA9 |
- |
ᶩ ᶩ |
MODIFIER LETTER SMALL L WITH RETROFLEX TAIL |
ᶪ | U+1DAA |
- |
ᶪ ᶪ |
MODIFIER LETTER SMALL L WITH PARATAL HOOK |
ᶫ | U+1DAB |
- |
ᶫ ᶫ |
MODIFIER LETTER SMALL CAPITAL L |
ᶬ | U+1DAC |
- |
ᶬ ᶬ |
MODIFIER LETTER SMALL M WITH HOOK |
ᶭ | U+1DAD |
- |
ᶭ ᶭ |
MODIFIER LETTER SMALL TURNED M WITH LONG LEG |
ᴻ | U+1D3B |
- |
ᴻ ᴻ |
MODIFIER LETTER CAPITAL REVERSED N |
ᶮ | U+1DAE |
- |
ᶮ ᶮ |
MODIFIER LETTER SMALL N WITH LEFT HOOK |
ᶯ | U+1DAF |
- |
ᶯ ᶯ |
MODIFIER LETTER SMALL N WITH RETROFLEX HOOK |
ᶰ | U+1DB0 |
- |
ᶰ ᶰ |
MODIFIER LETTER SMALL CAPITAL N |
ᵑ | U+1D51 |
- |
ᵑ ᵑ |
MODIFIER LETTER SMALL ENG |
º | U+00BA |
1-9-17 |
º º |
MASCULINE ORDINAL INDICATOR |
ᴽ | U+1D3D |
- |
ᴽ ᴽ |
MODIFIER LETTER CAPITAL OU |
ᶱ | U+1DB1 |
- |
ᶱ ᶱ |
MODIFIER LETTER SMALL BARRED O |
ᵓ | U+1D53 |
- |
ᵓ ᵓ |
MODIFIER LETTER SMALL OPEN O |
ᵔ | U+1D54 |
- |
ᵔ ᵔ |
MODIFIER LETTER SMALL TOP HALF O |
ᵕ | U+1D55 |
- |
ᵕ ᵕ |
MODIFIER LETTER SMALL BOTTOM HALF O |
ᶲ | U+1DB2 |
- |
ᶲ ᶲ |
MODIFIER LETTER SMALL PHI |
ᵠ | U+1D60 |
- |
ᵠ ᵠ |
MODIFIER LETTER SMALL GREEK PHI |
ᶳ | U+1DB3 |
- |
ᶳ ᶳ |
MODIFIER LETTER SMALL S WITH HOOK |
ᶴ | U+1DB4 |
- |
ᶴ ᶴ |
MODIFIER LETTER SMALL ESH |
ᶵ | U+1DB5 |
- |
ᶵ ᶵ |
MODIFIER LETTER SMALL T WITH PARATAL HOOK |
ᶶ | U+1DB6 |
- |
ᶶ ᶶ |
MODIFIER LETTER SMALL U BAR |
ᶷ | U+1DB7 |
- |
ᶷ ᶷ |
MODIFIER LETTER SMALL UPSIRON |
ᶸ | U+1DB8 |
- |
ᶸ ᶸ |
MODIFIER LETTER SMALL CAPITAL U |
ᵙ | U+1D59 |
- |
ᵙ ᵙ |
MODIFIER LETTER SMALL SIDEWAYS U |
ᵚ | U+1D5A |
- |
ᵚ ᵚ |
MODIFIER LETTER SMALL TURNED M |
ᶹ | U+1DB9 |
- |
ᶹ ᶹ |
MODIFIER LETTER SMALL V WITH HOOK |
ᶺ | U+1DBA |
- |
ᶺ ᶺ |
MODIFIER LETTER SMALL TURNED V |
ᵜ | U+1D5C |
- |
ᵜ ᵜ |
MODIFIER LETTER SMALL AIN |
ᵡ | U+1D61 |
- |
ᵡ ᵡ |
MODIFIER LETTER SMALL CHI |
ᶼ | U+1DBC |
- |
ᶼ ᶼ |
MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK |
ᶽ | U+1DBD |
- |
ᶽ ᶽ |
MODIFIER LETTER SMALL Z WITH CURL |
ᶾ | U+1DBE |
- |
ᶾ ᶾ |
MODIFIER LETTER SMALL EZH |
ᶿ | U+1DBF |
- |
ᶿ ᶿ |
MODIFIER LETTER SMALL THETA |
関連項目
丸囲みC
(C から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/11/16 02:41 UTC 版)
ナビゲーションに移動 検索に移動丸囲みCは、囲み英数字の一種で、大文字または小文字のCを丸で囲んだものである。
符号位置
大文字のCを丸で囲んだもの (Ⓒ) は、Unicodeでは"U+24B8"に収録されている。UTF-8では"e2 92 b8"とエンコードされる。
小文字のcを丸で囲んだもの (ⓒ) は、Unicodeでは"U+24D2"に収録されている。UTF-8では"e2 93 92"とエンコードされる。
使用例
丸囲みCは、著作権マークとして使用されている。
1947年から1949年にかけて発売された千代田光学(後のミノルタ)のカメラには、レンズに"ⓒ Super Rokkor"のように青いⓒマークが付いているものがあった。これは著作権表示ではなく、反射防止(coated)加工がされていることを示すものだった[1]。他のメーカーのレンズにも同様の意味の刻印があり、例えば、オリンパスのズイコーレンズには、赤い"ZUIKO C."という表記があった。
このマークは、第二次世界大戦中に製造されたクルーバー社のプラスチック製の機体認識訓練用模型で広く使用された[2]。
日本語の敬称の「ちゃん (Chan)」の意味で丸囲みCが使用されることがある。
脚注
- ^ Kilpatrick, David (2007年). “70 years of Minolta - The 1940s and 1950s”. Photoclub Alpha. 2015年6月7日閲覧。
- ^ “Collect Air | Friend or Foe? Museum”. collectair.org. 2017年4月13日時点のオリジナルよりアーカイブ。2021年11月16日閲覧。
関連項目
著作権マーク
著作権マーク(ちょさくけんマーク)またはコピーライトマークとは、大文字のCを丸で囲んだ記号(©)であり、音声録音[1]以外の作品の著作権表示に使用される記号である。
この記号の使用は、アメリカ合衆国の著作権法[2]や、国際的には万国著作権条約[3]に規定されている。ただし、ベルヌ条約の下では登録・納入・著作権表示等の形式的手続がなくても著作物が創作された時に著作権が発生するという無方式主義が採用されたため、ほとんどの国で著作権マークによる明示をしなくても著作権を得ることができる[4]。
歴史
作品の著作権を示す記号の先駆は、1670年代のスコットランドの年鑑に見られる。その書籍には、その真正性を示すための紋章が印刷されていた[5]。
アメリカ合衆国等での方式主義の採用
著作権の発生要件について、登録、納入、著作権表示など一定の方式を備えることを要件とする立法例を方式主義という[6]。
著作権表示は、アメリカ合衆国の1802年の著作権法によって初めて規定された[7]。それは、"Entered according to act of Congress, in the year , by A. B., in the office of the Librarian of Congress, at Washington."( 年、ワシントンにある議会図書館司書の事務所にA. B.が議会制定法に従って記入した。)のように長いものであった。一般に、著作権表示は著作権で保護された作品自体に表示されていなければならなかったが、絵画のような美術作品の場合には、美術作品が設置されるべき物体の表面に刻印されていてもよい[8]。1874年、"Copyright, 18 , by A. B."と大幅に短縮された表示でも可能とするよう著作権法が改正された[9]。
著作権マーク©は、1909年の著作権法(Copyright Act of 1909)第18条[10]で導入され、最初は絵画、グラフィック、彫刻作品にのみ適用された[11]。1954年、出版された著作物にもこの記号の使用が拡大された[11][12]。
1909年の著作権法は、既存の著作権法を完全に書き直し、改訂することを意図していた。この法案の草案で最初に提案されたように、著作権の保護を受けるためには、芸術作品そのものに"copyright"という文言またはその認可された略語を入れることが要求された。この芸術作品には絵画も含まれていたが、額縁は取り外し可能であることから議論が起こった。1905年と1906年に行われた法案についての著作権保持者間の会議では、芸術家組織の代表者はこの要件に反対し、作品自体に作者名以外の文言を書くことを望まなかった。妥協案として、作品自体に書かれる作者名の横に、比較的邪魔されない記号(大文字のCを丸で囲んだ記号)を書き足す案が出された[13]。実際に、ハーバート・パトナム議会図書館司書の指導の下、著作権委員会がまとめた1906年の議会に提出された法案は、特別な著作権マーク、丸で囲まれた文字Cを、"copyright"やその略語"copr."の代わりに使用することができるが、それは芸術作品などの限られたカテゴリについてのみ使用でき、通常の書籍や定期刊行物は含まれないとしている[14]。1909年の著作権法は、1946年に合衆国法典第17号に組み込まれた時点でも変更されなかった。1954年の改正で、全ての著作物について記号©が"Copyright"または"Copr."の代替として許可された[12]。
ベルヌ条約と無方式主義への移行
1886年に締結されたベルヌ条約は1908年のベルリンでの改正条約で無方式主義を採用した[15]。無方式主義とは著作物が創作された時点で何ら方式を必要とせず著作権の発生を認める立法例をいう[4]。
ベルヌ条約締結後もアメリカ合衆国や中南米諸国の一部などは同条約に加盟せず方式主義をとっていた[15][6]。そこで1952年の万国著作権条約は無方式主義を採る国における著作物が方式主義を採る国でも著作権保護を得ることができるよう、氏名と最初の発行年、©のマークの3つを著作権表示として明示すれば自動的に著作権の保護を受けることができるとした[16](万国著作権条約では©マークは代替の記号ではなく著作権表示の要件の一つである[16])。
その後、1989年にアメリカ合衆国がベルヌ条約に加盟したほか中南米諸国も次々にベルヌ条約に加盟し無方式主義に移行した[16]。ベルヌ条約の加盟国では、著作権を確立するのに著作権表示を行う必要はなく、著作物の作成時に自動的に著作権が確立する[17](ベルヌ条約と万国著作権条約の双方に加盟している場合には万国著作権条約17条によりベルヌ条約が優先する[18])。ほとんどの国がベルヌ条約に加盟しているため、著作権の発生要件としての著作権表示を必要としなくなった。
アメリカ合衆国の著作権表示
アメリカ合衆国では、1989年3月1日以前には以下の形式の著作権表示が必要とされた[19]。
- ©記号、または"Copyright"(あるいはその略語の"Copr.")という文言
- その作品の最初の出版年
- 著作権の所有者の識別情報。名前、その省略形、一般に知られている名称のいずれかによる
例えば、2011年に初めて出版された作品の場合は、以下のようになる。
- © 2011 John Smith
以上の表示は、かつてアメリカ合衆国で著作権保護を受けるために必要だったが、ベルヌ条約に加盟している国では必要ない[17]。アメリカ合衆国は1989年3月1日にベルヌ条約に加盟した[20]。ただし、万国著作権条約の適用を受けるためには今も©マークを用いた方式をとる必要がある[16]。
なお、条約上の著作権の発生要件の問題とは別に著作権表示は国内法上一定の効果を生じることがある。アメリカの著作権法では著作権の存在を知らずパブリックドメインと信じた者を保護する善意の侵害者(innocent infringers)の法理があるが、©マーク等の著作権表示が著作物に明確に表示されていれば原則として善意の侵害には当たらないとされている[16]。
デジタル表現
タイプライターやASCIIベースのコンピュータシステムでは、この記号は長らく利用できなかったため、括弧を使い(C)と表現するのが一般的だった。
Unicodeでは、U+00A9 © copyright sign (HTML: ©
©
)として割り当てられている[21]。Unicodeには他にU+24B8 Ⓒ circled latin capital letter c (HTML: Ⓒ
)とU+24D2 ⓒ circled latin small letter c (HTML: ⓒ
)もある[22]。これらは、著作権マークがフォントや文字セットで利用できない場合(一部の朝鮮語コードページなど)に代替として使用されることがある。
Windowsでは、⎇ Altを押しながら0 1 6 9を押すことで入力できる。Macintoshでは、オプションキーを押しながらgを押すことで入力できる。Linuxでは、compose O Cのコンポーズキーシーケンスで入力できる。
記号 | Unicode | JIS X 0213 | 文字参照 | 名称 |
---|---|---|---|---|
© | U+00A9 |
- |
© © |
COPYRIGHT SIGN |
関連する記号
- コピーレフトマーク(
) - 著作権マークを左右反転させた記号であり、コピーレフトのシンボルとして使用される。法的には意味を持たない[23]。
- レコード著作権マーク(℗) - 大文字のPを丸で囲んだ記号。音声記録(フォノグラム)の著作権(原盤権)を表示するために使用される。
- 登録商標マーク(®) - 大文字のRを丸で囲んだ記号であり、公式の事務所に登録されている商標(登録商標)を指定するために使用される。
脚注
- ^ これは丸の中がPのレコード著作権マーク(℗)で示される。
- ^ 合衆国法典第17編第401条 17 U.S.C. § 401
- ^ Universal Copyright Convention, Article III, §1. (Paris text, July 24, 1971.)
- ^ a b 安藤和宏 2018, p. 170.
- ^ Mann, Alastair J.; Kretschmer, Martin; Bently, Lionel (2010). “A Mongrel of Early Modern Copyright”. In Deazley, Ronan. Privilege and property: essays on the history of copyright. Open Book Publishers. ISBN 978-1-906924-18-8
- ^ a b 安藤和宏 2018, p. 171.
- ^ “Copyright Law Revision Study Number 7, page 6”. 合衆国著作権局. 合衆国政府印刷局. 14 June 2013閲覧。
- ^ Copyright Act of 1870, §97.
- ^ 1874 Amendment to the Copyright Act of 1870, §1.
- ^ Copyright Act of 1909, §18
- ^ a b Copyright Law Revision: Study 7: Notice of Copyright. Washington, D.C.: 合衆国政府印刷局. (1960). p. 11
- ^ a b An Act to amend title 17, United States Code, entitled "Copyrights", Pub.L. 83–743, 68 Stat. 1030 1954年8月31日制定.
- ^ Arguments before the Committees on Patents of the Senate and House of Representatives, conjointly, on the bills S. 6330 and H.R. 19853, to amend and consolidate the acts respecting copyright. June 6–9, 1906. 合衆国政府印刷局. (1906). p. 68
- ^ “Proposed Copyright Legislation”. The Writer XVIII (6): 87. (June 1906) .
- ^ a b 半田正夫 & 紋谷暢男 1989, p. 308.
- ^ a b c d e 安藤和宏 2018, p. 172.
- ^ a b Molotsky, Irvin (October 21, 1988). “Senate Approves Joining Copyright Convention”. The New York Times September 22, 2011閲覧。
- ^ 安藤和宏 2018, p. 173.
- ^ 合衆国法典第17編第401(b)条 17 U.S.C. § 401(b)
- ^ Circular 38A: International Copyright Relations of the United States. 合衆国著作権局. (2014). p. 2 March 5, 2015閲覧。
- ^ https://www.unicode.org/charts/PDF/U0080.pdf
- ^ https://www.unicode.org/charts/PDF/U2460.pdf
- ^ Hall, G. Brent (2008). Open Source Approaches in Spatial Data Handling. Springer. p. 29. ISBN 3-540-74830-X Additional 978-3-540-74830-4. See Open Source Approaches in Spatial Data Handling - Google ブックス, page 29
参考文献
- 半田正夫、紋谷暢男『著作権のノウハウ』(第3版増補版)有斐閣〈有斐閣選書〉、1989年。
- 安藤和宏『よくわかる音楽著作権ビジネス 基礎編』(5th Edition)リットーミュージック、2018年。ISBN 978-4-845-63141-4。
関連項目
C(シー)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/08/19 16:39 UTC 版)
金融街の資金が無くなり、さらに金融街の影響範囲内にある人間全ての未来をミダスマネーに変換し尽くした時に発生する現象。いわゆる「市場閉鎖」であり、金融街と共に影響範囲内にある人間や土地が「存在しなかった」ことになり消滅する。また、「C」により国が消滅するとその影響を受け他国の経済状況の改変が起こる。これは、作中では『「C」の連鎖』と呼ばれている。Calamity、Catastrophe、Chaos、Clash、Crisis、Collapse等の頭文字からアントレには「C」と呼ばれる。本編ではカリブとシンガポールの金融街が「C」により消滅している。
※この「C(シー)」の解説は、「C (アニメ)」の解説の一部です。
「C(シー)」を含む「C (アニメ)」の記事については、「C (アニメ)」の概要を参照ください。
「C」の例文・使い方・用例・文例
- そのドラマは今晩8時にCBSで放送される
- 彼はほとんどすべてのお金をCDに費やす
- BBCは昼夜放送している
- 米国のCongressは英国のParliamentに相当する
- その聖歌隊は慈善のためにCDを吹き込んだ
- CDコンパクトディスク
- 「彼らの新しいCDはすごいと思うよ」「私もよ」
- そのCDと全く同じコピーを作った
- BBCによる独占テレビインタビュー
- ABC航空をご利用いただきありがとうございます
- こんなジャングルの中でもラジオでBBC放送が受信できるんだ
- そのバンドは彼らの新しいCDをクリスマス前に出すだろう
- これらのCDはずっと持っていていいですよ
- 寄贈者の名をABC順に表にした
- 彼はCD店を経営している
- 私は友人と同じくらいCDをもっている
- このCDプレイヤーはどこもおかしくない
- レコード店に新しいCDを注文した
- 彼女はいつも寝る時にそのCDをかける
- 「彼の新しいCDを買うつもりかい」「買うかもしれないね」
Cと同じ種類の言葉
固有名詞の分類
「C」に関係したコラム
-
FXやCFDの三角形移動平均とは、移動平均の移動平均のことです。つまり、移動平均値を算出して、さらにその数値の移動平均値を算出します。なお、移動平均には単純移動平均を用います。三角形移動平均は、三角移...
-
FX(外国為替証拠金取引)の三尊とは、釈迦三尊の並びのようにローソク足が並んでいる状態のことをいいます。ヘッドアンドショルダー(head and shoulder)ともいいます。三尊は、三尊天井と逆三...
-
ダウ理論(Dow Theory)とは、ダウ・ジョーンズの創設者のチャールズ・ダウ(Charles Henry Dow)が提唱した相場理論のことです。ダウ理論には以下の6つの基本法則があります。ファンダ...
-
FX(外国為替証拠金取引)の口座明細には、証拠金や維持率のような専門用語が使われています。ここでは、それらの用語の意味や計算方法について解説します。建玉可能金額(たてぎょくかのうきんがく)新規に建玉(...
-
ダブルトップとは、チャートが「W」の字を上下反転したように形成されていることです。ダブルトップが形成されると、2つのエントリーポイントが発生します。下の図は、ダブルトップを形成したチャートです。ダブル...
-
FXやCFDのシャンデモメンタムとは、相場の売られ過ぎや買われ過ぎを判断するためのテクニカル指標のことです。シャンデモメンタムは、0を中心に-100から100までの値で推移します。シャンデモメンタムで...
- >> 「C」を含む用語の索引
- Cのページへのリンク