シー [1] 【 C ・ c 】
C
c
AB(C)ロール 【AB(C)rolls】
炭素(C)
ダイアモンド
アセチレンブラック
システイン
英訳・(英)同義/類義語:Cys, cysteine, C , Cys , cysteien, cysteine
タンパク質を構成するアミノ酸の一種で、残基部分にSH基を持つためタンパク質分子中で立体構造の保持や活性部位として働くこともある。また、分泌タンパク質では2つのSH基が結合されてーS-S-結合を作り、タンパク質の立体構造の安定化に働く場合もある。略号はCys , C
シチジン
シトシン
補体
C
補体(Complement、略号=C)
C
C
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/09/16 09:00 UTC 版)
ナビゲーションに移動 検索に移動正書法
- ポーランド語、チェコ語、スロバキア語、スロベニア語などのスラヴ系言語、バルト語派に分類されるラトビア語、リトアニア語、その他ハンガリー語やアルバニア語など、ラテン文字を用いる東欧の言語の多くでは、c は後続音の如何にかかわらず、常に [ts] 音を表す。ポーランド人ルドヴィコ・ザメンホフの考案によるエスペラントもまた同様である。
- (例) ハンガリー語: cukor [ツコル] 「砂糖」
- また中国語のピンインにおいては、“息を出さない「ツ」音” [ts] を z と書くのに対して、“息を強く出す「ツ」音” [tsʰ] を c と表している。
- (例) 中国語: cānkǎo 参考 [ツァンカオ] 「参考にする」
- 東欧以外のいくつかの言語では c を [ʧ] の音標とするものがある。インドネシア語やマレー語はその代表である。
- (例) インドネシア語: cokelat [チョクラッ] 「チョコレート」
- トルコ語や、トルコ語に倣って正書法を定めたアゼルバイジャン語などでは、c は [dʒ] (ヂャ行のような子音)を表し、[ʧ] にはセディーユ付きの ç が当てられている。
- (例) トルコ語: Cuma [ヂュマ] 「金曜日」
その他
- 国際音声記号では、[c] は 無声硬口蓋閉鎖音を表す。
- ラテン文字による正書法のない言語などで音素寄りの音標文字としてラテン文字を使う場合は、c は [c] や [ʧ] の音に当てることが多い。主要な例としてサンスクリットがある。また日本人になじみの深い例として、アイヌ語のラテン文字表記を挙げることができる。
- (例) サンスクリット: candraḥ [チャンドラ] 「月」、アイヌ語: cise [チセ] 「家」
記号付き文字、多重音字などについて
- 各種ダイアクリティカルマークの付いた c については、#関連項目を参照。
- 二重音字としては、ゲルマン系の言語で ck [k] が広く定着しているほか、多くの言語で ch が様々に使われている。 後者については ch を参照のこと。
- 国際音声記号で用いる ɔ や ɕ については、それぞれの項目を参照。
Cの意味
学術的な記号・単位
- 百を意味する数字。語源はラテン語で「百」を意味するcentum。ないしその派生語の略。
- 十二を意味する数字。十六進法や二十進法など、底が十二を超えるN進法において、十二(十進法の12、十二進法の10)を一桁で表すために用いられる。
- circa (c.)
- 炭素の元素記号。
- 電荷の単位クーロンのシンボル。
- 温度を示すセルシウス度(摂氏)で用いられる記号(℃)。
- 数学では一般に既知の数、集合、行列等を示す、A, Bに次ぐ文字として用いられる。
- 大文字太字の Cは、数学において複素数 (complex number) 全体の集合を表す。
- 中心化群 CG(S)
- 関数の滑らかさ Ck
- 定数 (constant) を表す。特に積分定数を表す時は通例大文字。
- nCm は組合せ (combination) の総数。
- 対称操作のひとつである回転を表現する記号。具体的な使用例は分子対称性を参照。
- 実数連続体の基数。
- 光速度(celeritas)を表す(小文字)。
- 自然科学では熱容量・電気容量(capasity、大文字だが比熱容量を表す際は小文字)、濃度(concentration)、光度 (カンデラ:candela)を示す文字に用いる。電気容量を表すことから、回路素子のコンデンサ (condenser, capacitor) を表す際にも用いる
- 加熱を示すときに用いられる場合がある。加熱を表すフランス語「Chauffage」の略。
- トランジスタの端子の1つ。コレクタ (collector)
- C言語。プログラミング言語の1つ。ここから派生した言語であるC++と組み合わせてC/C++と表記されることもある。
- 虫歯を表す。また C1 - C4 (CはCariesの頭文字。)でその進行度を表す。
- 文法で、補語 (complement)、可算名詞 (countable) の略号。
- 音楽で用いられる拍子の1つ、4 分の 4拍子の記号は大文字の C に似ているが、起源的に関係がない。
- カラー印刷などで使われる基本色 YMC, YMCK の中のシアン (Cyan)。
- 音楽で用いられる音名の1つ(英米式、ツェー(独式))。イタリア式で「do」(ド)、日本式では「ハ」に相当。 → ハ (音名)
- 音階の1番目の音であることから、日本の音楽・芸能関係者の間で1を表す隠語として使われる。例:C(ツェー)万=1万(円)
- 写真の印画紙の面種が光沢仕上げ (crystal) であることを意味する。対する絹目はS (silk) で示す。
- 視力検査で用いられるランドルト環は、Cを基にしている。
- ケッペンの気候区分の温帯を表すC
- マクロ経済学で、Cは消費 (consumption)を表す。また、cは限界消費性向を表す。
その他の記号
- 野球で捕手(キャッチャー、英:Catcher)を表す略称。
- サッカーで主将(キャプテン、英:captain)を表す略称。キャプテンマークなどに「C」と表示。
- アメリカンフットボールでセンター。
- バスケットボールでセンター。
- 大文字のCを丸で囲んだ著作権マークは著作権 (Copyright) を表す記号。マルC。「©」
- 体操競技の技の難度の1つ。現在はB難度の上、D難度の下。「ウルトラC」という言葉は、これに由来する(この言葉の生まれた当時は、3ランク制でC難度が最高だった)。
- 日本国有鉄道の機関車で、動軸が3軸の形式に付される記号。C62、EC40など。
- 日本で電車の用途を表す記号で、運転台付きの車両(制御車)のこと。電動車、付随車を表す記号と組み合わせて、Mc、Tcのように表される。
- 創造 (creation) の頭文字。多くの日本企業で社名などに用いられている。
- 古代ローマ人の個人名ガイウス (Gaius) の略。
- 日本のプロ野球球団広島東洋カープ (Carp) の略号。
- Jリーグのクラブのセレッソ大阪 (Cerezo) 。
- また、中央大学(陸上部・野球部)、智辯学園(高校野球部、高校陸上部、高校野球部、高校陸上部、和歌山高校野球部、和歌山高校野球部等)及び中京大学附属中京高等学校(陸上部・野球部)等の教育機関でも略号として使われている。
- 軍用航空機の形式で輸送機を表す記号。
- 民間航空機の登録番号(レジスタ)における国籍表示でカナダを表す。
- 人名の敬称「ちゃん」を表す。紙媒体ではマルC(©)、WWWや電子メールでは全角小文字のC(c)が主に使われる。1990年代後半から日本語コミュニティにおいて10代前半を中心に流行(同様に、「くん」はK)。
- 日本の地下鉄における駅ナンバリング制度において、東京では千代田線 (Chiyoda)、大阪では中央線・近鉄けいはんな線 (Chuo) を表す。
- (古)男女関係の進行段階で、肉体関係 (H)。
- 欧州の自動車のカテゴリー、全長を基準に設定されている記号。Cセグメント。
- コンピュータエンターテインメントレーティング機構のレーティング表示において15歳以上対象を表す(2006年3月以降)。
- 「チャーリー」フォネティックコードの第三コード。
- シティグループのニューヨーク証券取引所証券コード(ティッカーシンボル)
- 旅客機の座席区分でビジネスクラスを表す。
- 「C調」は通常ハ長調を意味するが、「いい調子」をひっくり返したジャズ・音楽業界の隠語でもある。1960年代から一般に広まる。現在はほぼ死語。
- 「C調気分で-」というフレーズの入った曲が存在する(サザンオールスターズ)。
- C○○(○○は数字)でコミックマーケット○○(通算○○回目のコミックマーケット)を示す。
商品名・作品名
- 「C」 - 中山美穂のデビュー曲。
- 「C」 (アルバム) - 中山美穂のデビューアルバム。
- C (Base Ball Bearのアルバム) - Base Ball Bearのアルバム。
- メルセデス・ベンツ・Cクラス。
- いすゞ自動車が発売していたバスシリーズ(CLM・CJM・CJAなど)。いすゞ・C系を参照。
- C (アニメ) - フジテレビジョン系列で放送のテレビアニメ。
符号位置
| 大文字 | Unicode | JIS X 0213 | 文字参照 | 小文字 | Unicode | JIS X 0213 | 文字参照 | 備考 |
|---|---|---|---|---|---|---|---|---|
| C | U+0043 | 1-3-35 | CC | c | U+0063 | 1-3-67 | cc | 半角 |
| C | U+FF23 | 1-3-35 | CC | c | U+FF43 | 1-3-67 | cc | 全角 |
| Ⓒ | 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 |
他の表現法
| フォネティックコード | モールス符号 |
| Charlie |
| 信号旗 | 手旗信号 | 点字 |
関連項目
脚注
- ^ ギリシア文字のΓは元々様々な角度で書かれていた。
- ^ ただし、G が発明されるより前の最初期のラテン語では、[k · g] の両音兼用だった。
- ^ オランダ語も同様。ただしラテン語やフランス語由来の語彙自体が英語よりはずっと少ない。
- ^ a b c フランス語・英語以外では cy の組み合わせは稀。
- ^ ただし cl の組み合わせは言語によって変形を被っていることが多い。例: ラテン語: clavis 「鍵」 [クラヴィス] > フランス語: clef [クレ] / イタリア語: chiave [キァーヴェ] / スペイン語: llave [リャベ] / ポルトガル語: chave [シャヴィ]
- ^ フランス語では無音の場合もある。 (例) blanc [ブラン] 「白い」。
- ^ ドイツ語ではラテン語の æ を ä に置き換える。
- ^ 正確には、a · o · ô · u · ơ · ư · ă · â の前。
- ^ 正確には音節末では若干違った音になる。
| ||||||||||||||||||||||||
C言語
(C から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2020/02/26 10:15 UTC 版)
ナビゲーションに移動 検索に移動| C言語のロゴ | |
| パラダイム | 命令型プログラミング、構造化プログラミング、手続き型プログラミング |
|---|---|
| 登場時期 | 1972年 |
| 開発者 | ベル研究所、デニス・リッチー、米国国家規格協会、国際標準化機構、ケン・トンプソン |
| 最新リリース | ISO/IEC 9899:2018/ 2018年 |
| 型付け | 弱い静的型付け |
| 主な処理系 | GCC, Clang, Visual C++, Intel C++ Compiler |
| 影響を受けた言語 | ALGOL 68、B言語、アセンブリ言語、FORTRAN、PL/I、CPL、BCPL、ALGOL 60 |
| 影響を与えた言語 | awk、csh、C++、Objective-C、D言語、Java、JavaScript、Limbo |
| プラットフォーム | クロスプラットフォーム |
| 拡張子 | c、h |
C言語(シーげんご、英: C programming language)は、1972年にAT&Tベル研究所のデニス・リッチーが主体となって開発した汎用プログラミング言語である。英語圏では「C language」または単に「C」と呼ばれることが多い。日本でも文書や文脈によっては同様に「C」と呼ぶことがある。制御構文などに高水準言語の特徴を持ちながら、ハードウェア寄りの記述も可能な低水準言語の特徴も併せ持つ。基幹系システムや、動作環境の資源制約が厳しい、あるいは実行速度性能が要求されるソフトウェアの開発に用いられることが多い。後発のC++やJava、C#など、「C系」と呼ばれる派生言語の始祖でもある。ANSI、ISO、またJISにより言語仕様が標準規格化されている。
特徴
この節に雑多な内容が羅列されています。事項を箇条書きで列挙しただけの節は、本文として組み入れるか、または整理・除去する必要があります。(2019年8月) |
- 汎用性が高い。プログラムの自由度が高く、また機械語やアセンブラのような低水準言語と比較するとソースコードの再利用性やメンテナンス性に優れており、目的に応じた拡張が容易であるため、オペレーティングシステムやアプリケーションソフトウェア・ファームウェアの記述、デバイスドライバー開発や機械制御など、あらゆる分野に適応している。
- 対応する機器の範囲が広い。パーソナルコンピュータはもちろん、自動車や家電の組み込み用マイコンからスーパーコンピュータまで、C言語を使用できるハードウェアは多様である。多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、C言語で対応可能である。それゆえ、C言語のコード資産が蓄積されている環境は多岐に渡る。
- 商用・非商用を問わず、採用ソフトウェア分野が広い。プログラム作成やデバッグのための補助的なソフトウェア(プログラミングツール)が豊富である。
- 機械語に変換するソフトウェア(コンパイラ)などの開発環境がCPUに付属していたり無償だったりするものもあるため、ライセンス料の支払いをしなくても使用が始められる。
- 開発時期が古いことから、文法に機械語の影響が強く、仕様自体は単純ではあるが明快ではなく難解である。この欠点を改良するためのちに開発された後発言語に比較し、プログラマが記述しなければならないことが多く、低水準言語のように面倒で習得しにくい側面を持つ。
- アマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。C言語は使用者の多さから、正負の両面含め、プログラミング文化に大きな影響を及ぼしている。
- 言語の適用先であるUNIXの場合、大抵のことがスクリプト言語・マクロプロセッサやフィルタやそれらの組み合わせで処理できるため、うまく分野の棲み分けができていた面があった。仕様規格・派生言語も多く幅広い領域への移植の結果、適切でない分野にC言語が使われている場合もある[要説明]。
- C言語は手続き型言語である。コンパイラ言語とOSを念頭に設計している。ハードウェアをある程度抽象化しつつも、必要に応じて機械語やアセンブラのコードと同じことを実現できるようなコンピュータ寄りの言語仕様になっている。低水準な記述ができる高級言語とも、高級言語の顔をした低級言語とも言うことがある。
- Cコンパイラは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。また、詳細を規格で規定せず処理系に委ねている部分が多く、C言語で書かれたソフトウェアでは処理系依存のコードが氾濫する原因となった。セキュリティー上の脆弱性や潜在的バグによる想定外の動作、コンパイラによる最適化の難しさといった問題を抱えており、最適化するとコンパイル速度が遅くなるなどの欠点が生じることがある。自動車分野ではMISRA CというC言語の部分集合 (subset) を定義して、危険な機能の使用や記述を禁止するという制限を設けることでC言語を安全に利用するためのガイドラインを設けている。
- UNIXおよびCコンパイラの移植性を高めるために開発してきた経緯から、オペレーティングシステムカーネルおよびコンパイラ向けの低水準記述ができる。
機能と自由度
- 文の区切りを終端記号 セミコロン「
;」で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。中括弧{ }によるブロック構造およびスコープをサポートする。- 記述作法についてはしばしば議論の対象となり、書籍も多数出版されている。
- ALGOLの思想を受け継いで構造化に対応している。手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐(
goto)を使用する必要はなく、MISRA Cでは当初goto文を禁止していた。goto文を使わなければ、スパゲティプログラムと呼ばれる読みにくいプログラムになりにくい。 - モジュール化がファイルを単位として可能。モジュール内だけで有効な名前を使うことが出来るスコープを持っている。
- プログラムを戻り値つきのサブルーチンに分離できる。C言語ではこれを関数と呼び、関数内のプログラムコードでは、独立したスコープを持つ変数(ローカル変数)が使用できる。これにより、データの流れがブロックごとに完結するのでデバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提としたホスト環境と、割り込み制御のようなOSを前提としないフリースタンディング環境とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を
mainという名前の関数として定義する[1]。プログラム中で再帰的にmain関数を呼ぶことも可能(C++では不可能[2][3])。フリースタンディング環境では、エントリポイントと呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しは、スタックオーバーフローの原因となるため、MISRA Cでは禁止している。 - システム記述言語として開発されたため、高級言語であるがアセンブラ的な低水準の操作ができる。ポインタ演算、ビットごとの論理演算、シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはオペレーティングシステムやデバイスドライバーなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
- ソースコードの記述に使う文字集合はANSI-C:1989(ISO/IEC 9899:1990)ではASCIIを標準としている。他のISO 646でも書けるように、3文字利用したトライグラフと呼ばれる表記法も存在する。その後、ISO/IEC 9899:1995 AMDなどではマルチバイト文字セット対応の拡張を規定している。さらに、その後トライグラフは複数のコードを利用したシステムでしか利用がない[要説明]ため、より分かり易い2文字によるダイグラフを規定している。
- 組み込みの整数型および浮動小数点数型のほか、構造体、共用体、列挙体(列挙型)によるユーザー定義のデータ型や列挙定数をサポートする。構造体および共用体はビットフィールドをサポートする。
アセンブラとのインタフェース
- 多くの処理系がインラインアセンブラを搭載しているほか、アセンブラで出力したオブジェクトとのリンクが容易になっている。これにより速度が要求される部分だけをアセンブリ言語で記述するということが容易に行えることが多い。アセンブラとのインタフェースは#pragma asmなどを用いて局所化を図る努力はあるが、コンパイラごとに定義があり、CPUが同一であっても移植性が低い場合がある。
コンパイラ仕様
- コンパイラの処理が1パスで済む仕様になっている。ANSI-C:1989では宣言のない変数は
intを想定することになっていた。ISO/IEC C:1999以降では変数はその使用より前に宣言する必要がある。関数の宣言がないと、戻り値や引数をint型とみなす仕様は、自由な発想を促すプログラミングの視点で好ましい[独自研究?]が、型検査・型証明の仕組みが十分にないと不具合の原因になることがある。後継言語では記述によって先読みが必要になりうる。 - マクロ記述やコンパイル条件の指定などが出来る前処理指令が標準化されている。前処理指令の解釈をするプリプロセッサ (preprocessor) を持っている。プリプロセッサは、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。
処理系の簡素化
処理系の簡素化のため、以下のように安全性を犠牲にした仕様が多い。なお、ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施したとしても実行速度の低下が無視できる程度であることも多く、言語仕様側の欠点とみなされることも少なくない。
- 配列参照時の自動的な添字のチェックをしない
- これを要因とする代表的なバグが、固定長のバッファ領域をはみだしてデータの書き込みが行われてしまう「バッファオーバーフロー」(バッファオーバーラン)である。標準ライブラリにはバッファオーバーフローを考慮していない関数があり、かつ多用されがちなため、しばしば脆弱性の原因となる。また、プログラムにより明示的に制御(動的メモリ確保)することで可変長配列の実現を可能にしているが、確保した領域の範囲外にアクセスしても自動的な伸長は行なわれない。
- 文字列を格納するための特別な型が存在しない
- 文字列には
char型の配列を利用する。言語仕様上に特別な扱いはないが、ヌル文字('\0')を終端とする文字列表現を使い、その操作をする標準ライブラリ関数がある。これは実質的にメモリ領域のポインタアクセスそのもので、固定長バッファに対して、それより長い可変長の文字列を書き込んでしまうことがあり、バッファオーバーランの元凶の1つとなっている。後継言語では文字列処理を特に強化している場合が多く、標準ライブラリあるいは言語仕様による組み込みの文字列型を提供している。 - 自動変数の自動的な初期化をしない
- 自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合、値は不定となるが、不定な値へのアクセスは未定義の動作であるので、コンパイラ最適化の過程で想定しない形に改変することもある[4]。変数宣言・初期化の仕様による制限から、変数宣言の時点で初期化せず後で代入することで初期化に代えることが日常的で、誤って不定の値の変数を読み出すバグを作り込みやすい。なお自動変数の自動とは変数の領域の確保と開放が自動であるという意味であり、自動的に初期化されるという意味ではない。
その他
- ソースコード上の文字の大文字・小文字を区別する。
- 入出力を含めほとんどの機能が、C言語自身で書かれたライブラリによって提供される。このことは、C言語の機種依存性が低く、入出力関係ライブラリをのぞいた部分は移植性(ポータビリティ)が高いことを意味する[要出典]。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
- プログラムの実行に必要とするハードウェア資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの組み込みシステムでも使用されている。
- 組み込み向けの場合は、プログラミング言語として、アセンブラ以外では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」はエスケープ文字\による改行を表す。なお、printf 関数は書式文字列とそれに対応する可変個引数を受け取り、書式化された文字列として表示できる高機能な標準出力関数であるが、序盤から例示に使用している入門書もある。また、main関数は引数のないバージョンと、コマンドライン引数をポインタ配列として受け取るバージョンどちらを使ってもよい。main関数とprintf関数は、いずれも入門者や初学者にとっては最初の鬼門となる難解な関数であり、C言語によるプログラミングのハードルを高くしている一因でもある。
主な制御構造
主な標準ライブラリ関数
歴史
誕生
C言語は、AT&Tベル研究所のケン・トンプソンが開発したB言語の改良として誕生した(#外部リンクの「The Development of the C Language」参照)。
1972年、トンプソンとUNIXの開発を行っていたデニス・リッチーはB言語を改良し、実行可能な機械語を直接生成するC言語のコンパイラを開発した[5]。後に、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のカーネルを作成するための言語という意味ではない[6]。
- B言語の欠点を解消するため、1971年に改良作業を開始した。
- 1972年にC言語のコンパイラができあがり、UNIXバージョン2において、いくつかのユーティリティを作成するために使用された。
UNIX環境とC言語
アセンブラとの親和性が高いために、ハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述のK&Rといった解説文書が存在していたことなど、さまざまな要因からC言語は業務開発や情報処理研究での利用者を増やしていった。特にメーカー間でオペレーティングシステムやCPUなどのアーキテクチャが違うUNIX環境では再移植の必要性がしばしば生じて、プログラムをC言語で書いてソースレベル互換[7]を確保することが標準となった。
C言語誕生時の環境と他言語との比較
C言語の開発当初に使われた入力端末はASR-37であったことが知られている[6]。 ASR-37は1967年制定の旧ASCII ISO R646-7bitにもとづいており、「{」および「}」の入力を行うことができたが、当時は一般的に使われていた入力端末ではなかった。 当時PDP-11の入力端末として広く使われていたのはASR-33であるが、これは1963年制定の旧ASCIIであるASA X3.4に準拠しており、「{」や「}」の入力を行うことはできなかった[8]。
このことは、ブロック構造に「{」や「}」を用いる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が主流になりだすと、2万円前後の安価なCコンパイラ[要追加記述]が存在したこともあり、ユーザーが急増した。8ビットや8086系のPCへの移植は、ポインタなどに制限や拡張を加えることで解決していた。
現在のC言語
1990年代中盤以降は、最初に学ぶプログラミング言語としても主流となった。また、90年代中盤にはゲーム専用機(ゲームコンソール)の性能向上とプログラムの大規模化、マルチプラットフォーム展開を受け、開発言語がアセンブラからC言語に移行した。その後、PCのさらなる性能向上と普及、GUI環境やオブジェクト指向の普及、インターネットおよびウェブブラウザの普及により、C++、Visual Basic、Java、C#、Objective-C、PHP、JavaScriptなどの高水準言語の利用者が増加した。広く利用されるプログラミング言語の数は増加傾向にあり、相対的にC言語が使われる場面は減りつつある。特にアプリケーションソフトウェアなどの上位層の開発には、C言語よりも記述性に優れるC++、Java、C#などC言語派生の後発言語が利用されることが多くなっている。資源制約の厳しかったゲーム開発においても、ハードウェアの性能向上やミドルウェアの普及により、C++やC#などが使われる場面が増えている。しかし、C言語は比較的移植性に優れた言語であり、個人開発/業務用開発/学術研究開発やプロプライエタリ/オープンソースを問わず、オペレーティングシステムやデバイスドライバーなどの下位層、クロスプラットフォームAPIの外部仕様、C++やJavaなどの高水準言語の処理系および実行環境の実装が困難な小規模の組み込みシステムなどで、2019年現在でも幅広く利用されている。
C言語の規格
K&R
リッチーとカーニハンの共著である「The C Programming Language」[9](1978年)を出版。その後標準ができるまで実質的なC言語の標準として参照。C言語は発展可能な言語で、この本の記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。C言語が普及するとともに、互換性のない処理系が数多く誕生した。これはプログラミング言語でしばしば起こる現象であり、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++と同様の関数プロトタイプ[10]を導入して引数の型チェックを強化したことと、voidやenumなどの新しい型を導入したことである。一方、「処理系に依存するものとする」に留めた部分も幾つかある(int型のビット幅、char型の符号、ビットフィールドのエンディアン、シフト演算の挙動、構造体などへのパディング等)。
規格では以下の3種類の自由を認めている部分がいくつかある[11]。
- 規格で定義しないことを決めている「未定義」 (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規格に準拠したコンパイルを行うことができる[12]。加えて、-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関数の代替)[13]。
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による大域ジャンプで抜け出す[14]、継続渡しスタイル変換されたコードである、などのために、絶対に制御が呼び出し元に戻らない、という関数を指示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。
アラインメント機能、_Atomic型やC言語ネイティブの原始的なスレッド機能などを省略可能な機能として規格に組み込んだ。また、C99では規格上必須要件とされていた機能のうち、複素数型と可変長配列を省略可能なものに変更した。これらの省略可能な機能はC11規格合致の必須要件ではないので、仮に完全に規格合致の処理系であっても、対応していないかもしれない。C11規格では、省略可能な機能のうちコンパイラがどれを提供しているかを判別するために利用できる、テスト用のマクロを用意している。
これにより、gets関数は廃止されている。
C17
2018年にISO/IEC 9899:2018(通称C17またはC18)として改訂された。仕様の欠陥修正がメインのマイナーアップデートである[15]。
主なC言語処理系
大抵の処理系はC言語とC++両方をサポートしている。C言語とC++の共通部分を明確にし、二つの言語の違いに矛盾が生じないようにすることが課題になっている。
Linux、Windows、UNIX用
- C++ Builder
- Windows/macOS/iOS/Android対応のC/C++コンパイラBCCを含む、RADツール。以前はWindowsおよびx86のみがメインターゲットだったが、Clang/LLVMをベースに再設計され、多数のプラットフォームやアーキテクチャをサポートするようになった[16]。前身はDOS/Windows用のBorland C/C++。さらに前身としてTurbo C/C++がある。
- Clang
- LLVMをバックエンドとして用いるオープンソースのC/C++・Objective-Cコンパイラ。多数のCPUに対応。
- GNUコンパイラコレクション (GCC)
- C/C++以外の言語もサポートし、多数のCPUやオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われるオープンソースのコンパイラ。独自拡張機能も多い。
- GCC 4.5で実質的にC99を完全サポートした[17]。
- GCC 4.9で実質的にC11を完全サポートした[18]。
- 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があった[19]。
- 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以降ではサポートされない[20]。
- C99[21]とC11[22]の対応リストが公開されている。バージョン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用(クロスコンパイラ)
- GreenHILS 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円であった[23][24]
- LSI C
- 8080・Z80用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用のLSI C-86がある。8086では機能限定(スモールモデルのプログラムしか開発できず、デバッガがない)の「試食版」がフリーソフトで公開され、広く使われた。
関連する主なプログラミング言語
先祖
- ALGOL
- ヨーロッパ生まれのアルゴリズム記述言語。PascalやC言語などに影響を与えたとされる。
- BCPL
- MULTICSで作成された高級言語。
- B言語
- 初期のUNIXで作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。
継承・拡張・サブセット
- C++
- C言語を拡張してオブジェクト指向化したもの。当初はC言語のスーパーセットだったが、現在は細かい部分において非互換仕様が増えている。
- Java
- C++よりも言語文法レベルでオブジェクト指向を重視した言語。バッファオーバーランなどの危険性が高いポインタといったローレベルな要素を言語文法から排除している。仮想マシン(Java VM, JVM)上で動作する。
- C#
- マイクロソフトが.NET Framework向けに開発した言語。文法はC言語およびC++に近い書式を持ち、Javaと似ている部分も存在するが、機能的にはDelphiがベースとなっている。
- Cg
- C言語をGPU上での3次元コンピュータグラフィックス処理用に特化させたもの(シェーダー言語、シェーディング言語)。NVIDIAによって開発された。
- Cyclone
- C言語の上位互換セキュア実装。ポインタの扱いを厳格化して安全面に配慮して拡張したもの。その他リージョンベースメモリ管理システム、正規表現、タグ付共用体などを追加している。
- Objective-C
- C言語を拡張してオブジェクト指向化したもの。C言語に Smalltalk のオブジェクトシステムを取り付けたような設計で、互換性は保たれている。C言語からの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
- SystemC
- ハードウェア記述言語向けに拡張したもの。書式はC++。EEE 1666-2005。ISO 8866:1991。
- Impulse_C
- ハードウェア記述言語向けに拡張したもの。書式はC。
- Unified Parallel C
- 並列計算向けにC99を拡張して作られた言語。
その他にも、OpenGLシェーダー言語であるGLSL、DirectX(Direct3D)シェーダー言語であるHLSL、OpenCLカーネル記述言語であるOpenCL-Cなど、C言語の文法的特徴を取り入れた派生言語やDSLが多数存在する。
参考文献
2015年現在、初心者向けのイラスト入り入門書やサブルーチンのサンプル集の他、組み込み機器の制御や科学技術計算など目的を特化した専門書なども多数ある。便利な機能の説明はあっても、学習者の水準や目的にあった本を見つけるのは必ずしも容易でない。オープンソースのCコンパイラ、OSも大規模なものがあり、直接読み始めるのは困難になっている。オープンソースのOSの小規模なものから始めるとよい。
- プログラミング言語C
- ブライアン・カーニハン、デニス・リッチー 共著、石田晴久訳、共立出版。
- 「K&R」として知られている「The C Programming Language」の邦訳。入門書ではなく、特にプログラミングそのものが初めてという読者には不適である。初版と2版があり、2版が現在も時折増刷している(邦訳では事情により、原書2版を基とした版には旧版と改訂新版がある。旧版は装丁が緑地で新版は白地である)。標準の制定以前は本書初版を言語仕様の参考文献として扱っていたが、現在は規格票を参照すべきであり、本書の記述は参考にとどめるべきである。
- Cプログラムの落とし穴
- コーニグ、中村明訳、新紀元社
- Cプログラミングで嵌まるところを指摘している。MISRA Cでも参考文献になっている。
- Cパズルブック
- アラン・R. フューアー、田中和明訳、カットシステム
- Cプログラミングの芸当を示し、読み書きを推奨しない例を示している。
脚注
- ^ 他の言語、例えば、BASICやPascalではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。
- ^ ISO/IEC 14882:2003 §3.6.1 「The function main shall not be used within a program.」
- ^ JIS X 3014:2003「プログラム言語C++」 §3.6.1 「関数mainは、プログラムの中で挙用してはならない。」
- ^ EXP33-C. 未初期化のメモリを参照しない JPCERT/CC、2014年3月25日(2014年8月22日閲覧)。
- ^ Portability of C Programs and the UNIX Systems
- ^ a b The Evolution of the Unix Time-sharing System
- ^ ソースレベル互換 - ZDNet Japan
- ^ http://www.tohoho-web.com/ex/draft/kanji.htm
- ^ 「K&R」という通称がある。
- ^ C89においては関数プロトタイプは必須ではない。
- ^ C FAQ 11
- ^ C89規格に準拠しないソースコードをGNU Cコンパイラでコンパイル失敗させるには、
gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c
とすれば良い(→エイリアシング)。 - ^ 6.19 Arrays of Variable Length
- ^
setjmp.hを参照。 - ^ 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. (1987年11月9日)
- ^ インテル® 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、『パソコンの常識事典』、日本実業出版社 - 普及率、解説書の多さについて。
- ^ 長沢英夫(編)、1988、『パソコンベストソフトカタログ』、JICC出版局 - Personal版、解説書の多さについて。
外部リンク
- ISO C Working Group
- The Development of the C Language - C言語がどのように開発されたかがわかる文書
- stdio.h on Coding Programmer Page / C Library Reference and Examples - C Reference
| ||||||||||||||||||||
| ||||||||||||||||||||||
C--
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2018/04/22 06:23 UTC 版)
| パラダイム | 命令型プログラミング |
|---|---|
| 登場時期 | |
| 開発者 | Simon Peyton Jones |
| 最新リリース | 2 / 2月 23, 2005[1] |
| 影響を受けた言語 | C |
| ウェブサイト | |
| 拡張子 | c-- |
C--(シーマイナスマイナス)は、人間ではなくコンパイラが生成することを想定したC言語風のプログラミング言語(中間言語)である。
歴史
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++
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/10/27 01:54 UTC 版)
ナビゲーションに移動 検索に移動| C++のロゴ | |
| パラダイム | 手続き型プログラミング、データ抽象化、オブジェクト指向プログラミング、ジェネリックプログラミング[1] |
|---|---|
| 登場時期 | 1983年 |
| 開発者 | ビャーネ・ストロヴストルップ |
| 最新リリース | ISO/IEC 14882:2017/ 2017年12月1日 |
| 評価版リリース | ISO/IEC 14882:2020 |
| 型付け | nominative, 安全でない強い静的型付け |
| 主な処理系 | GCC、Clang、Microsoft Visual C++、Intel C++ Compiler、C++ Builder |
| 影響を受けた言語 | C言語、Simula、ALGOL 68、CLU、ML、Ada |
| 影響を与えた言語 | Java、C#、D言語、PHP |
| ウェブサイト | isocpp |
| 拡張子 | cc、cpp、cxx、c、c++、h、hpp、hh、hxx、h++ |
C++(シープラスプラス)は、汎用プログラミング言語のひとつである。派生元であるC言語の機能や特徴を継承しつつ、表現力と効率性の向上のために、手続き型プログラミング・データ抽象・オブジェクト指向プログラミング・ジェネリックプログラミングといった複数のプログラミングパラダイムが組み合わされている[2]。C言語のようにハードウェアを直接扱うような下位層向けの低水準言語としても、複雑なアプリケーションソフトウェアを開発するための上位層向け高水準言語としても使用可能である。アセンブリ言語以外の低水準言語を必要としないこと、使わない機能に時間的・空間的コストを必要としないことが、言語設計の重要な原則となっている[3][4]。
C++は、1983年にAT&Tベル研究所の計算機科学者ビャーネ・ストロヴストルップによって公開された。1980年代半ばからC言語に次ぐ人気を集めるようになり[要出典]、様々なプラットフォームでその開発環境が導入された。1998年からISOとIECの共同で言語仕様とテンプレートライブラリの標準化が行われるようになり、その後2003年、2011年、2014年、2017年に標準規格が改訂されている。2019年現在の最新規格は「ISO/IEC 14882:2017」通称「C++17」である。
目次
歴史
ストロヴストルップはプログラミング言語C with Classes(クラス付きのC言語)の開発を1979年に開始した。彼は大規模なソフトウェアの開発に有用な特徴をSimulaが備えていることに気がついたが、Simulaは実行速度が遅く実用的ではなかった。一方でBCPLは実行速度こそ速かったものの、大規模なソフトウェア開発を念頭に置いた場合にあまりにも低級だった。
これらの事情を鑑みて、ストロヴストルップは当時既に汎用的な言語だったC言語にSimulaの特徴を取り入れることを試みた。この取り組みにあたってはALGOL68 やAda、 CLU、 ML等の言語の影響も受けている。最初はクラスと派生クラス、型検査機構の強化、インライン関数、デフォルト引数の機能を、Cfrontを介してC言語に追加した。1985年10月に最初の商用リリースがなされた[5]。
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)』[6](邦訳『注解C++リファレンスマニュアル』[7])が出版され、将来の標準化の土台となるものを提供した。後に追加された機能にはテンプレートと例外処理、名前空間、新形式のキャスト、ブール型が含まれた。
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-09-01 | ISO/IEC 14882:1998[8] | C++98 | ― |
| 2003-10-16 | ISO/IEC 14882:2003[9] | C++03 | JIS X 3014:2003 |
| 2007-11-15 | ISO/IEC TR 19768:2007[10] | C++TR1 | ― |
| 2011-09-01 | ISO/IEC 14882:2011[11] | C++11 | ― |
| 2014-12-15 | ISO/IEC 14882:2014[12] | C++14 | ― |
| 2017-12 | ISO/IEC 14882:2017[13] | C++17 | ― |
| 2020年 予定 | 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]、2014年12月15日に公式に出版された。
2017年12月、ISO/IEC 14882:2017 (C++17) が公式に発行された。
2019年現在、C++20の仕様策定が進められている。
将来
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++で広く使われていると思われる[独自研究?]ライブラリを挙げる。
- 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++との間には厳密な互換性はない[15][16]。当時、Cとの互換性について議論の末、「C++とANSI Cの間には不正当な非互換性はない」という合意が形成されることとなった。そのため、正当な非互換性を巡って多くの議論が発生した[17]。ただし、まだANSIによるC言語の標準規格も策定途中の時期である。
その後、先祖であるC言語のANSIによる標準規格制定時には、関数のプロトタイプ宣言やconst修飾など、C++の機能がC言語に取り入れられることにもなった。C99の出現により、//コメントなどの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プログラムである[18][19]。
#include <iostream>
int main()
{
std::cout << "Hello, World!\n";
}
書籍でも明記されているが、main()関数で意図的に返り値を返さない手法が使用されている。
演算子と演算子のオーバーロード
C++には四則演算、ビット演算、参照、比較、論理演算などの30を超える演算子がある。メンバーアクセス演算子(.と.*)のような一部の例外はあるが、大半の演算子はユーザー定義によるオーバーロードが可能である。オーバーロード可能な演算子が豊富に揃えられているため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として公開することがよい習慣であると考えられている。このようにしてデータの実装の詳細を隠蔽することにより、設計者はインターフェイスを変更することなく後日実装を根本から変更できる [20] [21]。
継承
継承を使うと他のクラスの資産を流用できる。基底クラスからの継承は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) となる。仮想関数は「メソッド」と呼ばれることもある[22]。派生クラスにて、基底クラスの仮想関数と名前および引数の数や型の順序が同じ関数を定義することでオーバーライドする(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++のパーサを記述することは比較的難しい[23]。その理由の一つは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を削除することを推奨していたが[24]、C++98では最終的にこれを残す決定がなされた[25]。結局、C++11では実装の少なさ・困難さを理由に削除された。
コンパイラ開発者の裁量で決められる範囲を確保するため、C++標準化委員会は名前修飾や例外処理などの実装に依存する機能の実装方法を決定しないことに決めた。この決定の問題は、コンパイラが異なるとオブジェクトファイルの互換性が保証されない点である。特定の機種やOSでコンパイラの互換性を持たせ、バイナリレベルでのコード再利用性を高めようとするABI[26]のような非標準の規格もあり、一部のコンパイラではこうした準規格を採用している。
2019年現在のメジャーなC++コンパイラ(gcc, Clang, Intel C++ Compiler, Microsoft Visual C++など)の最新版はC++11およびC++14規格にほぼ準拠しており、特にClangは2013年4月時点でC++11の全機能を実装完了した[27][28]。ただしマイナーアップデートとなるC++17を含めると、処理系間でのばらつきは依然として存在する。
C言語との互換性
C++は基本的にC言語の上位互換であるが、厳密には異なる[29]。C言語で記述された大半のプログラムはC++でコンパイルできるように簡単に修正できるが、C言語では正当でもC++では不正になる部分や、C++とは動作が異なる部分が若干存在する。
例えば、C言語では汎用ポインタvoid*は他の型へのポインタに暗黙的に変換できるが、C++ではキャスト演算子によって変換を明示する必要がある。またC++ではnewやclassといった数多くの新しいキーワードが追加されたが、移植の際に元のC言語のプログラムでそれらが識別子(例えば変数名)として使われていると、問題になる。
C言語の標準規格であるC99やその後継C11ではこうした非互換性の一部が解決されており、//形式のコメントや宣言とコードの混在といったC++の機能がC言語でサポートされている。その一方でC99では、可変長配列、複素数型の組み込み変数、指示初期化子、複合リテラルといった、C++でサポートしていない数多くの新機能が追加された[30]。C99で追加された新機能の一部はC++11に反映され、次期C++1yに対してもC99やC11との互換性を向上される提案が行われている。また、可変長配列や複素数型などのC99に追加された機能の一部はC11でオプションとなった[31]。
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
脚注
- ^ 『プログラミング言語C++』第4版、pp.12-13。
- ^ 『プログラミング言語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
- ^ We have C++14! : Standard C++
- ^ 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.
- ^ Open issues for The C++ Programming Language (3rd Edition) - このコードはストロヴストルップ自身による訂正文からの引用(633ページ)。
std::endlを'\n'に改めている。またmain関数がデフォルトで0を返す件についてはwww.research.att.com及びwww.delorie.com/djgpp/ を参照されたし。このデフォルト仕様はmain関数のみであり他の関数にはない。 - ^ 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.1 - C++11全実装バージョン”. Faith and Brave - C++で遊ぼう (2013年6月7日). 2013年9月7日閲覧。
- ^ “Bjarne Stroustrup's FAQ - Is C a subset of C++?”. 2008年1月18日閲覧。
- ^ “C9X -- The New C Standard”. 2008年12月27日閲覧。
- ^ C言語の最新事情を知る: C99の仕様 - Build Insider
参考文献
- Stroustrup, Bjarne『プログラミング言語C++』ロングテール、長尾高弘訳、アジソン・ウェスレイ・パブリッシャーズ・ジャパン , アスキー (発売)〈アスキーアジソンウェスレイシリーズ〉、1998年(原著1997年)、第3版。ISBN 475611895X。NCID BA39336320。
- Stroustrup, Bjarne『プログラミング言語C++』柴田望洋訳、SB Creative、2015年(原著2013年)、第4版。ISBN 978-4-7973-7595-4。
- Stroustrup, Bjarne『C++の設計と進化』επιστημη監修、岩谷宏訳、ソフトバンククリエイティブ、2005年(原著1994年)。ISBN 4797328541。NCID BA70383225。
関連項目
- C++11 (C++0x)
- C++14
- C++17
- C++/CLI
- Embedded C++
- JavaとC++の比較
- SystemC - C++言語ベースのハードウェア記述言語
- テンプレートメタプログラミング
- キーワード (C++)
外部リンク
| ||||||||||||||||
| ||||||||||||||||||||||
C Sharp
(C から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2020/01/09 06:24 UTC 版)
ナビゲーションに移動 検索に移動| 本来の表記は「C#」です。この記事に付けられた題名は技術的な制限または記事名の制約により不正確なものとなっています。 |
| C#のロゴ | |
| パラダイム | 構造化プログラミング、命令型プログラミング、オブジェクト指向プログラミング、イベント駆動型プログラミング、関数型言語、ジェネリックプログラミング、reflective programming、並行計算、クラスベース |
|---|---|
| 登場時期 | 2000年 |
| 設計者 | マイクロソフト(アンダース・ヘルスバーグ率いるチーム) |
| 開発者 | マイクロソフト |
| 最新リリース | 8/ 2019年9月23日 |
| 型付け | 強い静的型付け(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 |
| プラットフォーム | Windows, macOS, Linuxなど |
| ライセンス | Apacheライセンス (Roslyn) |
| ウェブサイト | docs |
| 拡張子 | cs |
C#(シーシャープ)は、アンダース・ヘルスバーグが設計したプログラミング言語であり、構文はその名前にもある通りC系言語(C言語、C++やJavaなど)の影響があるが、構文以外の言語機能などについてはヘルスバーグが以前の所属であるボーランドで設計したDelphiからの影響がある[注釈 1]。
マイクロソフトによる謳い文句としては、マルチパラダイムプログラミング言語、強い型付け、命令型、宣言型、手続き型、関数型、ジェネリック、オブジェクト指向の要素を持つ、などといった点が強調されている。
共通言語基盤 (CLI) といった周辺技術も含め、マイクロソフトのフレームワーク「.NET Framework」の一部である他、Visual J++で「非互換なJava」をJavaに持ち込もうとしたような以前のマイクロソフトとは異なり、その多くの[注釈 2]仕様を積極的に公開し標準化機構に託して自由な利用を許す (ECMA-334, ISO/IEC 23270:2003, JIS X 3015) など、同社の姿勢の変化があらわれている。
目次
概要
開発にはボーランドのTurbo PascalやDelphiを開発したアンダース・ヘルスバーグを筆頭に多数のDelphi開発陣が参加している。
C#は共通言語基盤(共通言語ランタイムなど)が解釈する共通中間言語にコンパイルされて実行される。
自動ボックス化、デリゲート、 プロパティ、インデクサ、カスタム属性、ポインタ演算操作、構造体(値型オブジェクト)、多次元配列、可変長引数、などの機能を持つ。また、Javaと同様に大規模ライブラリ、プロセッサ・アーキテクチャに依存しない実行形態、ガベージコレクション、JITコンパイルによる実行の高速化、などが実現されている(もっともこれらはC#の機能というより.NET Frameworkによるものである)。
.NET構想における中心的な開発言語であり、XML WebサービスやASP.NETの記述にも使用される。他の.NET系の言語でも記述可能だが、生産性・機能においてC#が最も優れるとされる[要出典]。マイクロソフトの統合開発環境では、Microsoft Visual C#がC#に対応している。
共通言語仕様のCLSによって、他のCLS準拠の言語(Visual Basic .NETやVisual C++ (C++/CLI) など)と相互に連携することができる。
バージョンおよびリリース時期
| バージョン | 言語仕様 | リリース時期 | 実装 | 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) |
| 1.1 1.2 | 2003年10月 | 2003年4月 | .NET Framework 1.1 | .NET 2003 | ||
| 2.0 | ECMA-334:2006 (2006年6月) | ISO/IEC 23270:2006 (2006年9月) | 2005年9月 | 2005年11月 | .NET Framework 2.0 | 2005 |
| 3.0 | N/A | N/A | 2007年8月 | 2007年11月 | 2008 2010 | |
| 4.0 | N/A | N/A | 2010年4月 | 2010年4月 | .NET Framework 4 | 2010 |
| 5.0 | ECMA-334:2017 (2017年12月) | ISO/IEC 23270:2018 (2018年12月) | 2013年6月 | 2012年8月 | .NET Framework 4.5 | 2012 2013 |
| 6.0 | 未定 | 未定 | Draft | 2015年7月 |
| 2015 |
| 7.0 | 未定 | 未定 | N/A | 2017年3月 | .NET Framework 4.6.2 | 2017 |
| 7.1 | N/A | N/A | N/A | 2017年8月 |
| 2017 version 15.3[5] |
| 7.2 | N/A | N/A | N/A | 2017年11月 |
| 2017 version 15.5[7] |
| 7.3 | N/A | N/A | N/A | 2018年5月 |
| 2017 version 15.7[8] |
| 8.0 | N/A | N/A | N/A | 2019年9月 | .NET Core 3.0[9] | 2019 version 16.3[10] |
言語仕様
さまざまな意味において、基盤であるCLIの機能をもっとも反映している言語であるといえる。C#にある組み込み型のほとんどは、CLIフレームワークに実装されている値型と対応している。しかし、C#の言語仕様はコンパイラのコード生成については何も言及していない。つまり、CLRに対応しなければならないとか、共通中間言語 (CIL) などの特定のフォーマットのコードを生成しなければならないとかいうことは述べられていない。そのため、理論的にはC++やFORTRANのように環境依存のマシン語を生成することも可能である。しかし、現在存在するすべてのC#コンパイラはCLIをターゲットにしている。
CやC++からの改良点
C#では、CやC++と比較してさまざまな制限や改良が加えられている。また、仕様の多くはC#言語というよりは、基盤である.NET Frameworkそのものに依拠している。Javaで導入された制限および改良をC#でも同様に採用しているものが多いが、C#で新たに導入された改良がのちにJavaにも同様に採用されたものもある。その例を次に挙げる。
構文や構文以外の改良点
- 外のブロックで宣言した変数と同じ名前の変数を、内のブロックで再宣言(シャドウ)してはいけない。再宣言は便利なこともあれば、混乱や曖昧のもとと主張されることもあるが、C#では禁止されている。
- C#にはブール型
boolが存在し、while文やif文のように条件をとるステートメントには、bool型の式を与えなければならない。C言語では、ブール型が無くint型(0を偽とし、非0を真とする)に兼用させた上、(ヌルポインタを偽とみなすこととするといろいろと便利だった、ということもあり)ポインタでもwhile文やif文に与える式にできる、という仕様としていた。これは便利なこともあったが、本来比較式を記述すべきところで誤って代入式を記述してもコンパイル適合となってしまうなど、ミスが見逃されることもあった。C#ではミスを防止するため[要出典]に、そのような仕様ではなくブール型を独立させ、またブール型を厳密に要求する場所を多くしている。 switch文に整数型あるいは整数型に準ずる型のみならず、文字列型stringを使用できる。caseラベルには、整数型あるいは整数型に準ずる型の定数のみならず、文字列リテラル(文字列定数)を使用できる。- 組み込み型のサイズおよび内部表現が仕様で定められており、プラットフォームや処理系に依存しない。浮動小数点数はIEEE 754に準拠する[11]。文字および文字列はUTF-16エンコーディングを採用する[12]。
ポインタとメモリ管理
- ポインタをサポートする。ポインタは
unsafeスコープ内のみで使用することができ、適切な権限をもつプログラムのみがunsafeとマークされたコードを実行することができる。オブジェクトへのアクセスの大部分は管理された安全な参照によってなされ、大部分の算術演算はオーバフローのチェックがなされる。unsafeポインタは値型や文字列を指すことができる。セーフコードでは、必ずしもそうする必要はないものの、IntPtr型を通してポインタをやりとりすることができる。 - マネージドなメモリを明示的に解放する方法は存在せず、参照されなくなったメモリはガベージコレクタによって自動的に解放される。ガベージコレクタは、メモリの解放忘れによって起こるメモリリークを解消する。C#は、データベース接続のようなアンマネージドなリソースに対しても明示的に制御する方法を提供している。これは
IDisposableインターフェイスとusingステートメントによってなされる。
名前空間とオブジェクト指向な型システム
- 名前空間は階層構造をもつ。つまり、名前空間は他の名前空間の中に宣言することができる。
- 組み込みの値型を含めたすべての型は、
objectクラス (System.Object) の派生型である。つまりobjectクラスのもつすべてのプロパティやメソッドを継承する。例えば、すべての型はToString()メソッドをもつ。 - クラス (
class) は参照型であり、構造体 (struct) および列挙型 (enum) は値型である。構造体はクラスよりも軽量で、C/C++との相互運用性に優れるが、派生型を定義することができない。 - クラスおよび構造体は複数のインターフェイスを実装することができるが、多重継承はサポートされない。
- C#はC++に比べて型安全である。既定の暗黙変換は、整数の範囲を広げる変換や、派生クラスから基底クラスへの変換といった、安全な変換のみに限定される。これは、コンパイル時、JITコンパイル時、そして一部の動的なケースでは実行時に強制される。ブール型と整数型、列挙型と整数型、の間は暗黙変換はできない。暗黙変換をユーザー定義する際は、明示的にそのように指定しなければならない。これはC++のコンストラクタとは違った仕様である。
- 列挙型のメンバーは、列挙型のスコープの中に置かれる。また、列挙型の定数名を取得することができる。さらに、列挙型の定数名から動的に定数値を得ることができる。
- アクセサの定義と利用を簡略化するためにプロパティ構文を利用できる。C++およびJavaにおけるカプセル化では、通例getter/setterアクセサとなるメンバー関数あるいはメソッドを定義して利用するが、C#ではプロパティ機能により、カプセル化を維持しつつ、あたかもフィールドを直接読み書きするような直感的な構文でオブジェクトの状態にアクセスすることができる。プロパティによってメンバーのアクセス制御やデータの正当性チェックを実行することができる。なお、イベントハンドラーに利用するデリゲートのカプセル化にはイベント構文 (
event) が用意されている。
C# 2.0からの仕様
部分型
部分型 (Partial Type) が導入された[13]。以下のようにクラスや構造体の宣言にpartial修飾子をつけることで、その宣言を分割することができる。
partial class MyClass { int a; }
partial class MyClass { int b; }
これは以下と同義である:
class MyClass { int a; int b; }
これによって、巨大なクラスを分割したり、自動生成されたコードを分離したりすることができる。partial 修飾子はすべての宣言につける必要がある。
ジェネリクス
ジェネリクスが導入された[13]。これは.NET Framework 2.0の機能である。クラス、構造体、インターフェイス、デリゲート、メソッドに対して適用することができる。.NETのGenericsはC++のテンプレート、あるいはJavaにおけるそれとも異なるもので、コンパイルによってではなく実行時にランタイムによって特殊化される。これによって異なる言語間の運用を可能にし、リフレクションによって型パラメーターに関する情報を取得することができる。また、where節によって型パラメーターに制約を与えることができる。一方、C++のように型パラメーターとして式を指定することはできない。なお、ジェネリックメソッドの呼び出し時に引数によって型パラメーターが推論できる場合、型パラメーターの指定は省略できる。
静的クラス
静的クラスが導入された[13]。static属性をクラスの宣言につけることで、クラスはインスタンス化できなくなり、静的なメンバーしか持つことができなくなる。
yieldキーワード
yieldキーワードによるコルーチンを使うことで、イテレータの生成を楽に実装できるようになった。
匿名デリゲート
プロパティに対する個別のアクセス制御
プロパティのget もしくは setアクセサのどちらかにアクセス修飾子を指定することでアクセス制御が別個にできるようになった[13]。次の例では、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が導入された[13]。
int? i = 512;
i = null;
int? j = i + 500; //jはnullとなる。nullとの演算の結果はnullになる。
int?はNullable<int>の糖衣構文である。また、nullを保持しているNull許容型のインスタンスをボックス化しようとすると、単に空参照 (null) に変換される[14]。
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型に代入することはできない
C# 3.0からの仕様
varキーワード
var キーワードが導入され、型推論を利用したローカル変数の宣言ができるようになった[13]。
var s = "foo";
// 上の文は右辺が string 型であるため、次のように解釈される:
string s = "foo";
// 以下に挙げる文は誤りである(コンパイルエラーとなる):
var v; // 初期化式を欠いている (型を推論する対象が存在しない)
var v = null; // 型が推論できない (曖昧である)
拡張メソッド
拡張メソッド (extension method) が導入された[13]。既存のクラスを継承して新たなクラスを定義することなく、新たなインスタンスメソッドを疑似的に追加定義することができる。具体的には、入れ子になっていない、非ジェネリックの静的クラス内に、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
拡張メソッドは糖衣構文の一種であり、カプセル化の原則に違反するものではないが、必要な場合に限り注意して実装することがガイドラインとして推奨されている[15]。
部分メソッド
部分メソッドが導入された[13]。部分型(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. と表示される。
ラムダ式
ラムダ式が導入された[13]。この名前はラムダ計算に由来する。
以下の匿名メソッド
// 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 と命名している。実際はプログラマはこの変数にアクセスすることはできない。
自動実装プロパティ
プロパティをより簡潔に記述するための自動実装プロパティが導入された[13]。プロパティの定義に 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 と命名している。実際はプログラマはこのフィールドにアクセスすることはできない。
匿名型
一時的に使用される型を簡単に定義するための匿名型が導入された[13]。以下に例を挙げる:
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 をサポートするために、クエリ式が導入された[13]。これは 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キーワードが導入され、動的型付け変数を定義できるようになった[13]。dynamic型として宣言されたオブジェクトに対する操作のバインドは実行時まで遅延される。
// xはint型と推論される:
var x = 1;
// yはdynamic型として扱われる:
dynamic y = 2;
public dynamic GetValue(dynamic obj)
{
// objにValueが定義されていなくとも、コンパイルエラーとはならない:
return obj.Value;
}
オプション引数・名前付き引数
VBやC++に実装されているオプション引数・名前付き引数が、C#でも利用できるようになった[13]。
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修飾子を指定することにより、ジェネリクスの共変性・反変性を指定できるようになった[13]。
IEnumerable<string> x = new List<string> { "a", "b", "c" };
// IEnumerable<T>インターフェイスは型引数にout修飾子が指定されているため、共変である。
// したがって、C# 4.0では次の行はコンパイルエラーにならない
IEnumerable<object> y = x;
C# 5.0からの仕様
C# 6.0からの仕様
- 自動実装プロパティの初期化子[16]
- get のみの自動実装プロパティおよびコンストラクタ代入[16]
- 静的 using ディレクティブ[16]
- インデックス初期化子[16]
- catch/finally での await[16]
- 例外フィルタ[16]
- 式形式のメンバー (expression-bodied members)[16]
- null条件演算子[16]
- 文字列補間(テンプレート文字列)[16]
- nameof 演算子[16]
- #pragma
- コレクションの初期化子での拡張メソッド[16]
- オーバーロード解決の改善[16]
静的 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引数で値を受け取る場合、その場所で変数宣言可能となった[17]。
total += int.TryParse("123", out var num) ? num : 0;
パターンマッチング
is 式の拡張
is式の構文が拡張され、型の後ろに変数名を宣言できるようになった[17]。 拡張された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ラベルの処理が実行される。[18]
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;
}
}
タプル
タプルのための軽量な構文が導入された[17]。 従来のSystem.Tupleクラスとは別に、System.ValueTuple構造体が新しく追加された。
タプル記法
2個以上の要素を持つタプルのための記法が導入された。 引数リストと同様の形式で、タプルを記述できる。
// タプル記法
(int, string) tuple = (123, "Apple");
Console.WriteLine($"{tuple.Item1}個の{tuple.Item2}");
分解
多値戻り値を簡単に扱えるように、分解がサポートされた[17]。
var tuple = (123, "Apple");
// 分解
(int quantity, string name) = tuple;
Console.WriteLine($"{quantity}個の{name}");
分解はタプルに限らない。Deconstruct()メソッドが定義されたクラスでも、分解を利用できる[17]。
以下に、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)型が認められた[19]。
static Task Main()
static Task<int> Main()
default式
型推論可能な場面では、defaultの型指定は省略可能となった[19]。
int number = default;
string name = default;
C# 7.2からの仕様
値型の参照セマンティクス
値型におけるパフォーマンス向上を意図した複数の機能が追加された。
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では以下の仕様が追加された。[22]
- ジェネリック型制約の種類の追加
System.Enum,System.Delegateunmanaged(文脈キーワード)
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からの仕様
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#の言語仕様は標準化団体Ecma Internationalを通じて公開・標準化されており、第三者がマイクロソフトとは無関係にコンパイラや実行環境を実装することができる[1][25]。 現段階で、C#コンパイラの実装は次の5つが知られている。
- マイクロソフト製
- Visual Studio 2015 以降で使用されている、.NETコンパイラプラットフォーム (コードネームRoslyn)。ApacheライセンスのオープンソースプロジェクトでGitHubで公開されている[26]。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) と書く[27]。 音楽のシャープ (♯, MUSIC SHARP SIGN (U+266F)) ではなくナンバーサイン (#) を採用したのは、フォントやブラウザなどの技術的な制約に加え、ASCIIコードおよび標準的キーボードには前者の記号が存在しないためである。
- "#"接尾辞は、他の.NET言語にも使用されており、J#(Javaのマイクロソフトによる実装)、A#(Adaから)、F#(System Fなどから[28])が含まれる。また"#"接尾辞はGtk#(GTK+などのGNOMEライブラリの.NETラッパ)、Cocoa#(Cocoaのラッパ)などのライブラリにも使用されている。そのほか、SharpDevelopなどの"Sharp"を冠する関連ソフトウェアも存在する。
- C#という名称の解釈として、「(A-Gで表された)直前の音を半音上げる」という音楽記号の役割に着目し、「C言語を改良したもの」を意味したのではないか、というものがある[要出典]。これは、C++の名称が「C言語を1つ進めたもの」という意味でつけられたことにも似ている。
- アンダース・ヘルスバーグは、「C#」が「C++++」(すなわち「C++をさらに進めたもの」)にみえるのが由来である、と語っている[29][30]。
脚注
注釈
出典
- ^ a b Abel Avram (2009年7月29日). “誰でもC#とCLIの正式な実装が可能に”. InfoQ. 2019年12月2日閲覧。
- ^ “Standard ECMA-334”. ECMA. 2019年6月22日閲覧。
- ^ Standard ECMA-334-archive
- ^ “Using C# 3.0 from .NET 2.0”. Danielmoth.com (2007年5月13日). 2012年10月4日閲覧。
- ^ “Visual Studio 2017 15.3 Release Notes”. Microsoft Docs. 2018年11月12日閲覧。
- ^ Richard Lander (2018年5月30日). “Announcing .NET Core 2.1” (英語). .NET Blog. Microsoft. 2019年12月2日閲覧。
- ^ “Visual Studio 2017 15.5 Release Notes”. Microsoft Docs. 2018年11月12日閲覧。
- ^ “Visual Studio 2017 15.7 Release Notes”. Microsoft Docs. 2018年8月24閲覧。
- ^ Richard Lander (2019年9月23日). “Announcing .NET Core 3.0” (英語). .NET Blog. Microsoft. 2019年12月2日閲覧。
- ^ “Visual Studio 2019 Release Notes”. Microsoft Docs. 2019年9月30日閲覧。
- ^ “2-2 変数と定数”. Microsoft Docs. 2018年11月11日閲覧。
- ^ “.NET での文字エンコード”. Microsoft Docs. 2018年11月11日閲覧。
- ^ a b c d e f g h i j k l m n o p q “C# の歴史”. Microsoft Docs. 2019年12月12日閲覧。
- ^ “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日閲覧。
- ^ “MicrosoftがC# 8.0をリリース”. InfoQ (2019年12月10日). 2019年12月12日閲覧。
- ^ Tim Smith (2010年10月4日). “Javaと.NETの特許問題への短い紹介”. InfoQ. 2019年12月2日閲覧。
- ^ dotnet/roslyn - GitHub
- ^ 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#の文法
- C#のデータ型
- キーワード (C#)
- 実行環境
- 開発環境
- Visual C#
- Visual Studio
- SharpDevelop - フリーの統合開発環境
- 比較
外部リンク
- C# - Microsoft Docs
- 言語仕様
- C# 言語仕様 - Microsoft Docs
- ECMA-334 C# 言語仕様
- JIS X 3015:2008「プログラム言語C#」
- Mono C# コンパイラ
- Microsoft Shared Source Common Language Infrastructure 2.0 Release
| ||||||||||||||
| ||||||||||||||||||||||
| ||||||||||||||
著作権マーク
(C から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/06/11 14:14 UTC 版)
ナビゲーションに移動 検索に移動| この項目には、一部のコンピュータや閲覧ソフトで表示できない文字(丸の中にCなど、丸付き文字)が含まれています。 |
著作権マーク(ちょさくけんマーク)またはコピーライトマーク(copyright mark)とは、大文字の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のコンポーズキーシーケンスで入力できる。
関連する記号
- レコード原盤権マーク(℗) - 大文字のPを丸で囲んだ記号であり、録音の原盤権を指定するために使用される[23]。
- コピーレフトマーク - 著作権マークを左右反転させた記号であり、コピーレフトのシンボルとして使用される。法的には意味を持たない[24]。
- 登録商標マーク(®) - 大文字のRを丸で囲んだ記号であり、公式の事務所に登録されている商標(登録商標)を指定するために使用される。
- マスクワークマーク(Ⓜ) - 大文字のMを丸で囲んだ記号であり、マスクワーク(半導体集積回路の回路配置)の表示に使用される[25]。
脚注
- ^ これはレコード原盤権マーク(℗)で示される。
- ^ 合衆国法典第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”. 合衆国著作権局. 合衆国政府印刷局. 2013年6月14日閲覧。
- ^ 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 (1988年10月21日). “Senate Approves Joining Copyright Convention”. The New York Times 2011年9月22日閲覧。
- ^ 安藤和宏 2018, p. 173.
- ^ 合衆国法典第17編第401(b)条 17 U.S.C. § 401(b)
- ^ Circular 38A: International Copyright Relations of the United States. 合衆国著作権局. (2014). p. 2 2015年3月5日閲覧。.
- ^ https://www.unicode.org/charts/PDF/U0080.pdf
- ^ https://www.unicode.org/charts/PDF/U2460.pdf
- ^ Stephen Fishman (2010), “The Copyright Symbol”, The Public Domain, p. 356, ISBN 978-1-4133-1205-8
- ^ 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
- ^ “Federal Statutory Protection for Mask Works (Copyright Circular 100)”. 合衆国著作権局. pp. 5 (2012年9月). 2014年3月22日閲覧。
参考文献
- 半田正夫、紋谷暢男『著作権のノウハウ』有斐閣〈有斐閣選書〉、1989年、第3版増補版。
- 安藤和宏『よくわかる音楽著作権ビジネス 基礎編』リットーミュージック、2018年、5th Edition。ISBN 978-4-845-63141-4。



