cとは?

シー [1] 【 C ・ c 】

英語のアルファベット第三字。
創案Celsius頭文字から〕 摂氏温度であることを表す記号( C )。
蛇口などで)冷たい(cold)ことを表す記号( C )。 ↔ H
等級三番目。 「 -クラス落ちる」
〘音〙
ハの音。
四分の四拍子記号( C )。 〔本来は右の一部を欠いた円〕
世紀century)を示す記号( C )。
炭素carbon)の元素記号( C )。
サイクルcycle)を表す記号( c )。
ローマ数字100( C )。
電気量単位クーロンcoulomb)を表す記号( C )。
センチcenti-)を表す記号( c )。
プログラム言語の名称( C )。

C

等級の 3 番目。
創案Celsius頭文字から)摂氏温度であることを表す記号
アメリカ・イギリス・ドイツの音名の一(ドイツ語読みツェー)。ハ調長音階の第 1 音「ド」,日本音名の「ハ」。また,4 分の 4 拍子記号
Century世紀を表す記号
オランダ cyaan青緑色を表す記号シアンの略。
衣料品の,胸囲あるいはチェストを表す記号

c

centi
単位冠する接頭語で,10-2倍を表す。

AB(C)ロール 【AB(C)rolls】


炭素(C)

炭素(Carbon)は、元素記号 C で表され、原子番号は6、原子量は約12.01比重は2.25(g/cc)である。炭素族属する。同位体存在し、炭素12原子量基準とされるダイヤモンド黒鉛無定形炭素三種同素体天然産する化学的安定通常の溶媒に溶けず、酸・アルカリにもおかされない。
ステンレス鋼添加されると、オーステナイト結晶粒界Cr炭化物析出し、粒界腐食起こす種々の元素化合物をつくり、硬さ強度を増す。

ダイアモンド

分子式C
その他の名称:ダイアモンド、Diamond


アセチレンブラック

分子式C
その他の名称:炭素動物性,植物性】、カーボンブラックエキストラクト、Carbon black extractCarbon、C、活性炭Activated carbon活性炭素、Graphitized carbon blackCarbon blackAcetylene blackせきぼく、Grapite、カーボンブラック、アセチレンブラック、黒鉛化カーボンブラック、Activeated carbonpowder】、活性炭粒状】、Activeated carbongranule】、活性炭粉末】、AST-120、クレメジン、Kremezin
体系名:炭素


システイン

同義/類義語:シスチン
英訳・(英)同義/類義語:Cys, cysteine, C , Cys , cysteien, cysteine

タンパク質を構成するアミノ酸一種で、残基部分SH基を持つためタンパク質分子中で立体構造保持活性部位として働くこともある。また、分泌タンパク質では2つのSH基結合されてーS-S-結合作りタンパク質立体構造安定化に働く場合もある。略号Cys , C

シチジン

英訳・(英)同義/類義語:cytidine, C , Cyd, cytidine

ピリミジン塩基シトシンリボースがグリコシル結合してできたヌクレオシド

シトシン

英訳・(英)同義/類義語:C, cytosine, , Cyt, cytosine

ウラシルチミンと共に核酸構成するピリミジン塩基

補体

英訳・(英)同義/類義語:C, complement

血清中に存在するタンパク群で、抗体働き助け標的細胞破壊することから補体とよばれる

C

C → シトシン (核酸)
C → システイン (アミノ酸)


シトシン

ピリミジン塩基であり、シトシンヌクレオチドの基本骨格

名前Cytosine
C

CC Attribution-Noncommercial-Share Alike 3.0 Unported
Bio Wikiの記事を複製・再配布した「分子生物学用語集」の内容は、特に明示されていない限り、次のライセンスに従います:
CC Attribution-Noncommercial-Share Alike 3.0 Unported


補体(Complement、略号=C)

動物血清中の約20種類蛋白構成される物質遺伝的な欠損症の研究もとづき補体第1成分C1)から第9成分C9)まで分類されている。補体系抗体細菌成分によって刺激されると連鎖反応起こし食細胞機能増強抗原抗体結合強化リンパ球からの活性物質放出促進、あるいは細菌溶解など多彩な働きをする。最近研究から、異種移植で起こる超急性拒絶反応でも補体系が重要な役割をはたしているといわれる

読み方:しー

  1. 軍団のことをいふ。独語Die Corp(ディーコープ)の頭字を取つたものである。〔軍隊語〕

分類 軍隊

隠語大辞典は、明治以降の隠語解説文献や辞典、関係記事などをオリジナルのまま収録しているため、不適切な項目が含れていることもあります。ご了承くださいませ。 お問い合わせ

C

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2017/08/18 06:11 UTC 版)

Cc Cc
ラテン文字
  Aa Bb Cc Dd  
Ee Ff Gg Hh Ii Jj
Kk Ll Mm Nn Oo Pp
Qq Rr Ss Tt Uu Vv
  Ww Xx Yy Zz  

Cは、ラテン文字アルファベット)の3番目の文字。小文字は c

字形

大文字、小文字とも半円形である。同形のキリル文字С сは別字で、ラテン文字のSに相当する文字である。

フラクトゥールではのようである。

歴史

C は、ギリシア文字のガンマ(Γ)が「く」の字の角度で書かれたものを丸めた形に由来する[1]。キリル文字のГは同系である。なおGを参照。

呼称

日本では「シー」と呼ぶことが多い。

音価

現代では多くの言語の正書法や音標記号などにおいて用いられるが、その流儀は大きく2つに分類できる。

Cの置かれた位置によって2種類の音を表す正書法

元々のラテン語c は常に [k] で発音されるものだった[2]が、俗ラテン語時代になると転訛しはじめ、c の直後に“前舌母音”( e · i · y · æ )が来る場合に限り、その影響を受けて、c[c]「ティ」と「キ」の間のような子音)や [ʧ]「チャチュチョ」のような子音)で発音するようになった。これを軟音化と呼ぶ。

時代が下りロマンス諸語が分化するにつれ、この音はさらに多様な音へと分化した。現在のロマンス諸語の正書法は、こうした自然の音変化を受け継いだものである。また、フランス語の影響を大きく受けた英語でも、同様の読み方をする[3]

どの言語においても、a · o · u · l · r などの前の c はラテン語時代と変わらない [k] 音を保っている[5]。 また、フランス語やルーマニア語などでは語末に c を置く単語がいくらかあり、これらも [k] で発音する[6]

(例) フランス語: lac [ラック] 「湖」 (同上)、ルーマニア語: bec [ベック] 「電球」 (同上)

英仏語のCとヨーロッパの言語

上記以外のヨーロッパ圏の言語では c をこのように使い分けることはないが、ラテン語やフランス語、英語などから c を含む単語を借用する場合、e · i · y ( · ä [7] ) の前の cz, c, s などに、a · o · u · l · r の前の ck に、それぞれ置き換えて用いるのが伝統的であった。一例を挙げれば:

いずれも英語やフランス語の concert 「コンサート、演奏会」の借用で、各言語の規則にしたがって字を置き換えたものである。

ベトナム語

ベトナム語の正書法「クオック・グー」では c はつねに [k] を表すが、その位置は a, o, u などの前[8]や音節末[9]に限られる。 その他の場所では [k] 音に kq を用いる。 わかりやすく言うと、ka, kê, ki, kô, ku, kwôk などと書けば済みそうなところ、わざわざ cq を持ち込んで、ca, kê, ky, cô, cu, quôc などと表記するルールだが、もともとクオック・グーはフランス人宣教師によって考案されたものであり、考案の際にロマンス諸語的な表記法を大いに参考にしたことがこうした部分にもよく表れているといえる。

Cの位置にかかわらず破擦音などを表す用法

インドネシア風かき氷 es campur を売るジャカルタ市内の屋台。「エス・チャンプル」と発音する。

正書法

その他

  • 国際音声記号では、[c]無声硬口蓋閉鎖音を表す。
  • ラテン文字による正書法のない言語などで音素寄りの音標文字としてラテン文字を使う場合は、c は [c][ʧ] の音に当てることが多い。主要な例としてサンスクリットがある。また日本人になじみの深い例として、アイヌ語のラテン文字表記を挙げることができる。
    (例) サンスクリット: candraḥ [チャンドラ] 「月」、アイヌ語: cise [チセ] 「家」

記号付き文字、多重音字などについて

  • 各種ダイアクリティカルマークの付いた c については、#関連項目を参照。
  • 二重音字としては、ゲルマン系の言語で ck [k] が広く定着しているほか、多くの言語で ch が様々に使われている。 後者については ch を参照のこと。
  • 国際音声記号で用いる ɔɕ については、それぞれの項目を参照。

C の意味

学術的な記号・単位

  • ラテン語で100を意味するcentum、ないしその派生語の略。
    • 1/100 を表すSI接頭辞センチ(小文字)。
    • ¢は英語ではセントと読み、基本通貨単位(ユーロドルなど)の1/100を表す単位として多くの国で使われる(国によって呼び名は異なる)。
  • ローマ数字の100。
  • circa (c.)
  • 十六進数二十進数において、十二十進数での12)を一(一文字)で表すために用いられる。
  • 炭素元素記号
  • 電荷の単位クーロンのシンボル。
  • 温度を示すセルシウス度(摂氏)で用いられる記号(℃)。
  • 数学では一般に既知の数、集合、行列等を示す、A, Bに次ぐ文字として用いられる。
  • 大文字太字の Cは、数学において複素数 (Complex number) 全体の集合を表す。
  • 中心化群 CG(S)
  • 関数の滑らかさ Ck
  • 定数 (constant) を表す。特に積分定数を表す時は通例大文字。
  • nCm組合せ (Combination) の総数。
  • 対称操作のひとつである回転を表現する記号。具体的な使用例は分子対称性を参照。
  • 実数連続体の基数
  • 光速度を表す(小文字)。
  • 自然科学では熱容量電気容量Capasity、大文字だが比熱容量を表す際は小文字)、濃度( Concentration)、光度カンデラ:candela)を示す文字に用いる。電気容量を表すことから、回路素子のコンデンサ (Condenser, Capacitor) を表す際にも用いる
  • 加熱を示すときに用いられる場合がある。加熱を表すフランス語「Chauffage」の略。
  • トランジスタの端子の1つ。コレクタ (Collector)
  • C言語。プログラミング言語の1つ。ここから派生した言語であるC++と組み合わせてC/C++と表記されることもある。
  • 虫歯を表す。また C1 - C4 (CはCariesの頭文字。)でその進行度を表す。
  • 文法で、補語 (complemant)、可算名詞 (countable) の略号。
  • 音楽で用いられる拍子の1つ、4 分の 4 拍子の記号は大文字の C に似ているが、起源的に関係がない。
  • カラー印刷などで使われる基本色 YMC, YMCK の中のシアン (Cyan)。
  • 音楽で用いられる音名の1つ(英米式、ツェー(独式))。イタリア式で「do」(ド)、日本式では「」に相当。 → ハ (音名)
    • 音階の1番目の音であることから、日本の音楽・芸能関係者の間で1を表す隠語として使われる。例:C(ツェー)万=1万(円)
  • 写真印画紙の面種が光沢仕上げ (crystal) であることを意味する。対する絹目はS (silk) で示す。
  • 視力検査で用いられるランドルト環は、Cを基にしている。
  • ケッペンの気候区分温帯を表す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
半角
U+FF23 1-3-35 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

他の表現法

関連項目

脚注

[ヘルプ]
  1. ^ ギリシア文字のガンマ(Γ)は元々様々な角度で書かれていた。
  2. ^ ただし、G が発明されるより前の最初期のラテン語では、[k · g] の両音兼用だった。
  3. ^ オランダ語も同様。ただしラテン語やフランス語由来の語彙自体が英語よりはずっと少ない。
  4. ^ a b c フランス語・英語以外では cy の組み合わせは稀。
  5. ^ ただし cl の組み合わせは言語によって変形を被っていることが多い。例: ラテン語: clavis 「鍵」 [クラヴィス] > フランス語: clef [クレ] / イタリア語: chiave [キァーヴェ] / スペイン語: llave [リャベ] / ポルトガル語: chave [シャヴィ]
  6. ^ フランス語では無音の場合もある。 (例) blanc [ブラン] 「白い」。
  7. ^ ドイツ語ではラテン語の æä に置き換える。
  8. ^ 正確には、a · o · ô · u · ơ · ư · ă · â の前。
  9. ^ 正確には音節末では若干違った音になる。

C言語

(c から転送)

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2017/09/21 07:27 UTC 版)

C言語
パラダイム 手続き型
登場時期 1972年
設計者 デニス・リッチー
開発者 ベル研究所
型付け 弱い静的型付け
主な処理系 GCC, Clang, Visual C++
方言 C89, C99, C11
影響を受けた言語 B言語ALGOLアセンブリ言語pascal
影響を与えた言語 awkcshC++Objective-CD言語JavaJavaScriptLimbo

C言語(シーげんご)は、1972年AT&Tベル研究所デニス・リッチーが主体となって開発したプログラミング言語である。英語圏では単に C と呼んでおり、日本でも文書や文脈によっては同様に C と呼ぶことがある。

特徴

  • 汎用性が高い。プログラムの自由度や、目的に応じた拡張が容易であるため、パソコンソフトからゲームの作成、機械制御やシステム管理など、あらゆる分野に適応している。
  • 対応する機器の範囲が広い。パソコンはもちろん、自動車や家電の組込み用マイコンからスーパーコンピュータまで、C言語を使用できるハードウェアは多様である。多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、C言語で対応可能である。
  • 商用・非商用を問わず、採用ソフトウェア分野が広い。作成や使用のための補助的なソフトウェアが豊富である。
  • 機械語に変換するソフトなどの開発環境がCPUに付属していたり無償だったりするものもあるため、ライセンス料の支払いをしなくても使用が始められる。
  • 開発時期が古く、文法に機械語の影響が強く、複雑である。この欠点を補正するためのちに開発された新言語に比較し、記述することが多く、面倒で習得しにくい低級[1]言語である。
  • アマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。C言語は使用者の多さから、正負の両面含め、プログラミング文化に大きな影響を及ぼしている。
  • 言語の適用先であるUNIXの場合、大抵のことがスクリプト言語マクロプロセッサフィルタやそれらの組み合わせで処理できるため、うまく分野の棲み分けができていた面があった。仕様規格・派生言語も多く幅広い領域への移植の結果、適切でない分野にC言語が使われている場合もある。
  • C言語は手続き型言語の側面と関数型言語の側面がある。コンパイラ言語とOSを念頭に設計している。アセンブラのコードと同じことを実現できるようなコンピュータ寄りの言語仕様になっている。低水準な記述が出来る高級言語とも、高級言語の顔をした低級言語と言うことがある。
  • C コンパイラは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。セキュリティーの脆弱性や潜んだバグによる想定外の動作、コンパイラによる最適化の難しさがある。最適化するとコンパイル速度が遅くなるなどの欠点が生じることがある。自動車分野ではMISRA CというC言語部分集合(subset)を定義して、C言語の弱点を補っている。
  • UNIXおよび C コンパイラの移植性を高めるために開発してきた経緯から、オペレーティングシステムカーネルおよびコンパイラ向けの低水準記述ができる。

自由度

  • 文の区切りを終端記号 セミコロン;」で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。
    • 記述作法についてはしばしば議論の対象となり、書籍も多数出版されている。
  • ALGOL の思想を受け継いで構造化に対応している。手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐goto)を使用する必要はなく、MISRA Cでは当初goto文を禁止していた。goto文を使わなければ、スパゲティプログラムと呼ばれる読みにくいプログラムになりにくい。
  • モジュール化ファイルを単位として可能。モジュール内だけで有効な名前を使うことが出来るスコープを持っている。
  • プログラムを戻り値つきのサブルーチンに分離できる。C言語ではこれを関数と呼び、関数内のプログラムコードでは、独立した変数が使用できる。これにより、データの流れがブロックごとに完結し、デバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提としたホスト環境と、割り込み制御のようなOSを前提としないフリースタンディング環境とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を main という名前の関数として定義する[2]。プログラム中で再帰的に main 関数を呼ぶことも可能。(C++ では不可能[3][4])フリースタンディング環境では、エントリポイントと呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しは、スタックオーバフローの原因となるため、MISRA Cでは禁止している。
  • C言語では、main関数と、標準ライブラリのprintf, scanf 関数(およびその類型の関数)は、引数が可変という特殊な性格の関数である。K&Rでは、この特殊な関数mainとprintfを使った例を最初に示している。
  • システム記述言語として開発されたため、高級言語であるがアセンブラ的な低水準の操作ができる。ポインタ演算ビットごとの論理演算、シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはオペレーティングシステムやドライバなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
  • 配列とポインタとでは、宣言の仕方と領域確保の仕組みは異なっているが、配列アクセスそのものは、ポインタ演算および間接参照と同等である。
    • ポインタを配列表記でアクセスすることや、配列をポインタ表記でアクセスすることができる糖衣構文がある。
    • MISRA 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型とみなす仕様は、自由な発想を促すプログラミングの視点で好ましいが、型検査・型証明の仕組みが十分にないと不具合の原因になることがある。後継言語では記述によって先読みが必要になりうる。
  • マクロ記述やコンパイル条件の指定などが出来る前処理指令が標準化されている。前処理指令の解釈をするプリプロセッサを持っている。プリプロセッサ(preprocesser)は、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。

処理系の簡素化

ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施しても実行速度の低下が無視できる程度であることも多く、欠点とみなされることも少なくない。

配列参照時の自動的な添字のチェックをしない
これを要因とする代表的なバグがバッファオーバーフロー(固定長のバッファをはみだして上書きが行われてしまう)である。標準ライブラリにはバッファオーバーフローを考慮していない関数があり、かつ多用されがちなため、しばしば脆弱性の原因となる。また、プログラムにより制御する事で可変長配列を可能にしている。
文字列を格納するための特別な型が存在しない
文字列にはchar型の配列を利用する。言語仕様上に特別な扱いはないが、ヌル文字\0)を終端とする文字列表現を使い、その操作をする標準ライブラリ関数がある。これは実質的にメモリ領域のポインタアクセスそのもので、固定長バッファに対して、それより長い可変長の文字列を書き込んでしまうことがあり、バッファオーバーランの元凶の1つとなっている。後継言語では文字列処理を特に強化している場合が多い。
自動変数の自動的な初期化をしない
自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合、値は不定となるが、不定な値へのアクセスは未定義の動作英語版であるので、コンパイラ最適化の過程で想定しない形に改変することもある[5]。変数宣言・初期化の仕様による制限から、変数宣言の時点で初期化せず後で代入することで初期化に代えることが日常的で、誤って不定の値の変数を読み出すバグを作り込みやすい。なお自動変数の自動とは変数の領域の確保と開放が自動であるという意味であり、自動的に初期化されるという意味ではない。

その他

  • 文字の大文字・小文字を区別する。
  • 入出力を含めほとんどの機能が、C言語自身で書かれたライブラリによって提供される。このことは、C言語の機種依存性が低く、入出力関係ライブラリをのぞいた部分は移植性(ポータビリティ)が高いことを意味する[要出典]。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
  • プログラムの実行に必要とするハードウェア資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの組み込みシステムでも使用されている。
  • 組込み向けの場合は、プログラミング言語として、アセンブラ以外では、CとC++しか用意していないことがある。その場合、他のプログラミング言語は、CやC++で書かれた処理系が存在すれば、コンパイルすることにより利用可能となることもあるが、メモリ制約などで動作しないことがある。

コード例

Hello worldプログラム

C言語のHello worldプログラムには、ホスト環境を前提とするか、フリースタンディング環境を前提とするかで、方向性が異なる。入門書によって趣が異なるいくらかの方向性が存在する。ホスト環境を前提とする場合には、入出力の利用により、動作をすぐに確かめることができる。標準Cライブラリ (stdio.h)のprintf関数を利用したものを例示する場合、以下のようなものがある。

#include <stdio.h>

int main(void)
{
    printf("Hello, world!\n");
    return 0;
}

ここでサンプルソース中の「\n」は改行を表す。なお、printf 関数は変数や書式化された文字列などが表示できる比較的高機能な出力関数である。C言語として可変引数である特殊なmainとprintfを使っていることにより、C言語の関数プログラミングに対する誤解を生む原因にもなっている。

主な制御構造

主な標準ライブラリ関数

歴史

誕生

C言語は、AT&Tベル研究所のケン・トンプソンが開発したB言語の改良として誕生した(#外部リンクの「The Development of the C Language」参照)。

1973年、トンプソンとUNIXの開発を行っていたデニス・リッチーはB言語を改良し、実行可能な機械語を直接生成するC言語のコンパイラを開発した。UNIXは大部分をC言語によって書き換え、C言語のコンパイラ自体も移植性の高い実装のPortable C Compilerに置き換わったこともあり、UNIX上のプログラムはその後にC言語を広く利用するようになった。

UNIX環境とC言語

アセンブラとの親和性が高いために、ハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述の K&R といった解説文書が存在していたことなど、さまざまな要因からC言語は業務開発や情報処理研究での利用者を増やしていった。特にメーカー間でオペレーティングシステムやCPUなどのアーキテクチャが違う UNIX環境では再移植の必要性がしばしば生じて、プログラムをC言語で書いてソースレベル互換[6]を確保することが標準となった。

パソコンとC言語

1980年代に普及し始めたパーソナルコンピュータは当初、8ビットCPUでROM-BASICを搭載していたものも多く、BASICが普及していたが、1980年代後半以降、16ビットCPUを採用しメモリも増えた(ROM-BASIC 非搭載の)パソコンが主流になりだすと、2万円前後の安価なコンパイラが存在したこともあり、ユーザーが急増した。8ビットや8086系のパソコンへの移植は、ポインタなどに制限や拡張を加えることで解決していた。

現在のC言語

1990年代中盤以降は、最初に学ぶプログラミング言語としても主流となった。GUI環境の普及とオブジェクト指向の普及により JavaObjective-CC++PHPVisual Basic、などの言語の利用者も増加したため、広く利用されるプログラミング言語の数は増加傾向にある。現在でもJava, C#, C++などC言語の後続言語を含めて、C言語は比較的移植性に優れた言語であり、業務用開発やフリーソフトウェア開発、C++ などの実装が困難な組み込みなどの小規模のシステムで、幅広く利用されている。

C言語の規格

K&R

リッチーとカーニハンの共著である「The C Programming Language[7]1978年を出版。その後標準ができるまで実質的なC言語の標準として参照。C言語は発展可能な言語で、この本の記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。C言語が普及するとともに、互換性のない処理系が数多く誕生した。これはプログラミング言語でしばしば起こる現象であり、C言語固有の現象ではない。

C89/C90

そこで、ISO/IEC JTC1とANSIは協同でC言語の規格の標準化を進め、1989年12月にANSIANSI 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 X3010-1993 プログラム言語C』として、1993年10月に制定した。

最大の特徴は、C++と同様の関数プロトタイプ[8]を導入して引数の型チェックを強化したことと、voidenumなどの新しい型を導入したことである。一方、処理系に依存するとするに留めた部分も幾つかある(int型のビット幅、char型の符号、ビットフィールドエンディアン、シフト演算の挙動、構造体などへのパディング等)。

16ビット/32ビットCPUの両方に対応できるようにするため、定義しないことを決めている未定義、定義したもののどれにするかを決めていない未規定、処理系ごとに決めて文書化する処理系定義など、CPUとの相性による有利不利が生じないような規定になっている 型の大きさは16ビット/32ビットCPUの両方に対応できるように決めている。バイト数はsizeof演算子で取得し、最大最小値はlimits.hで参照することとしている。多くの処理系ではchar型は8ビット、short型は16ビットである。intlongはCPUのレジスタの幅などによって決めている。またAPIなどの呼び出しには、ヘッダでBYTEWORDなどとtypedefで定義した型を使用して回避することがある。char型以外で符号を明示しない場合はsigned(符号付き)にするかどうかも処理系。

規格上には、BCPL・C++タイプの一行コメント(「//…」)は無いが、オプションで対応した処理系も多く、gccやClangはGNU拡張-std=gnu89でサポートしている。

GNU Cコンパイラ や Clang では、-std=c89 (または-ansiもしくは-std=c90)をつけることにより、GNU拡張を使わないC89規格に準拠したコンパイルを行うことができる[9]。加えて、-pedanticをつければ診断結果が出る。商用のコンパイラではWatcom Cコンパイラが規格適合の比率が高いと言われていた。現在Open Watcomとして公開している。

C89には、下記の追加の訂正と追加を行った。

  • ISO/IEC 9899/COR1:1994
  • ISO/IEC 9899/AMD1:1995 - 英語圏での利用を想定して制定したC89に対して、国際化のためワイド文字版ライブラリを追加した Amendment11995年に発行された。
  • 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と呼ぶ。Intel C++ CompilerはC99に完全準拠していると公称している。GNU Cコンパイラ(gcc)はC99にほとんど対応しているが一部未対応部分も残っている[10]

日本では、日本工業規格 JIS X 3010:2003「プログラム言語C」がある。

主な追加機能:

  • 変数宣言がブロックの先頭でなくても良くなった。
  • ブール代数を扱うための_Bool型が予約語に追加され、標準ライブラリとしてstdbool.hを追加した。
  • 複素数を扱うための_Complex型や_Imaginary型を予約語に追加し、標準ライブラリとして complex.h を追加した。
  • 64ビット整数値を保持できる long long int 型の追加。
  • // による1行コメント。
  • インライン関数(inlineキーワード)。
  • 可変長配列alloca関数の代替)[11]

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)が現在の最新規格である。gccやClangなどが部分的に対応している。改定による変更・追加・削除機能の一部を以下に記述する。

C11はUnicode文字列(UTF-32UTF-16UTF-8 の各符号化方式)に標準で対応している。そのほか、type-generic 式、C++ と同様の無名構造体・無名共用体、排他的アクセスによるファイルオープン方法、quick_exitなどのいくつかの標準関数などを追加した。

また、_Noreturn関数指示子を追加した。_Noreturnは従来各処理系毎に独自に追加していた(たとえばgccでは__attribute__((__noreturn__)))ものを共通化したもので、「呼び出し元に戻ることがない」という特殊な関数についてその特性を示すためにある。return 文を持たない関数という意味ではなく(規格ではreturn文を持たなくとも、関数の最後の文の実行が終われば制御は呼び出し元に戻る)、この指示が意味するものは、当該の関数、ないしその内部から呼び出している関数の実行中に、必ず_exitexecveを実行したり、例外などで終了する、あるいは、longjmpによる大域ジャンプで抜け出す[12]継続渡しスタイル変換されたコードである、などのために、絶対に制御が呼び出し元に戻らない、という関数を指示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。

アラインメント機能、_Atomic型やC言語ネイティブの原始的なスレッド機能などを省略可能な機能として規格に組み込んだ。また、C99では規格上必須要件とされていた機能のうち、複素数型と可変長配列を省略可能なものに変更した。これらの省略可能な機能はC11規格合致の必須要件ではないので、仮に完全に規格合致の処理系であっても、対応していないかもしれない。C11規格では、省略可能な機能のうちコンパイラがどれを提供しているかを判別するために利用できる、テスト用のマクロを用意している。

gets関数は廃止。

主なC言語処理系

gcc、clang、Visual C++、C++Builderなど著名な4つがC言語とC++を一つの処理系で対応している。C言語とC++の共通部分を明確にし、二つの言語の違いに矛盾が生じないようにすることが課題になっている。

LinuxWindowsUNIX

C++ Builder
Windows用のx86用C言語・C++のコンパイラ。RAD。前身は DOSWindows用の Borland C/C++。さらに前身としてTurbo C/C++がある。
clang
LLVMをバックエンドとして用いるオープンソースのC言語・C++Objective-Cコンパイラ。多数のCPUに対応。
GNUコンパイラコレクション (GCC)
C・C++以外の言語もサポートし、多数の CPU やオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われるオープンソースのコンパイラ。
Microsoft Visual C++
Windows系プラットフォーム用のC言語・C++コンパイラ。2013からC99におおむね対応。x86・x64が主だが Xbox 360Windows CE等向けに PowerPCARMMIPSItanium等に対応した版もある。前身としてMS-DOSWindows用のMicrosoft C Compilerがある。またその廉価版としてQuick Cがあった[13]
Intel C++ Compiler
インテル製のx86・x64用のC言語・C++コンパイラ。WindowsLinuxmacOS向けがある。gcc互換。
Open Watcom C/C++
WindowsLinuxOS/2MS-DOSDOSエクステンダを対象とするx86用C言語・C++コンパイラ。商用だったWatcom C/C++がオープンソース化したもの。
Portable C Compiler
gccが普及する以前のUNIXにおける標準的C言語コンパイラ。現在はオープンソース
Digital Mars C/C++
WindowsMS-DOSDOSエクステンダを対象とする x86用のC言語・C++コンパイラ。無料版もある。ウォルター・ブライト作でDatalight CZorland CZortech 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++
armCPU用C言語・C++コンパイラ。
IAR C/C++
新旧の組み込み向けCPU各種を広くカバーする。現在は統合開発環境EW・SWに移行。armCPU用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
Z80PICなど。
Lattice C
1980年代に、日本で高い普及率を見せたコンパイラ。解説書も多く出版されていた。日本での発売はライフボート。初期版はマイクロソフトCコンパイラ1.0として発売された。商用利用のできない個人向けの「personal」版も販売されており、これの価格は19,800円であった[14][15]
LSI C
8080Z80用の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 でのグラフィック処理用に特化させたもの(シェーダー言語、シェーディング言語)。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シェーダー言語であるGLSLDirectXDirect3D)シェーダー言語であるHLSLOpenCLカーネル記述言語である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プログラミングの芸当を示し、読み書きを推奨しない例を示している。

脚注

  1. ^ IT用語における低水準、低級、低レベルという表現は、機械語アセンブリ言語のように、ハードウェアの動作をより直接的に記述できる(あるいはしなければならない)ことを指す。C言語に関しては、ポインタを通じて直接的にメモリ操作を行うことができる点などで、Javaなどに比べて低級であると言える(反対にJavaはC言語に対して高レベルな言語である)。通常、低級言語と高級言語は動作環境や生産性などに応じて使い分けられている。低級、高級という表現は誤解を招きがちだが、プログラミング言語としての質を指す言葉ではないことには注意が必要である。
  2. ^ 他の言語、例えば、BASICPascal ではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。
  3. ^ ISO/IEC 14882:2003 3.6.1 「The function main shall not be used within a program.
  4. ^ JIS X 3014:2003 3.6.1 「関数mainは、プログラムの中で挙用してはならない。」
  5. ^ EXP33-C. 未初期化のメモリを参照しない JPCERT/CC、2014年3月25日(2014年8月22日閲覧)。
  6. ^ http://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
  7. ^ K&R」という通称がある
  8. ^ C89においては関数プロトタイプは必須ではない。
  9. ^ C89規格に準拠しないソースコードをGNU Cコンパイラでコンパイル失敗させるには、
    gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c
    
    とすれば良い(→エイリアシング)。
  10. ^ Status of C99 features in GCC
  11. ^ 6.19 Arrays of Variable Length
  12. ^ setjmp.hを参照。
  13. ^ Microsoft Releases C Program Wares, Provides Rebates. InfoWorld: p. 29. (1987年11月9日). http://books.google.pl/books?id=Sj0EAAAAMBAJ 
  14. ^ 脇英世(監修)、1987、『パソコンの常識事典』、日本実業出版社 - 普及率、解説書の多さについて。
  15. ^ 長沢英夫(編)、1988、『パソコンベストソフトカタログ』、JICC出版局 - Personal版、解説書の多さについて。

外部リンク


著作権表示

(c から転送)

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2016/01/28 12:51 UTC 版)

この項目には、一部のコンピュータや閲覧ソフトで表示できない文字(丸の中にCなど、丸付き文字)が含まれています詳細
万国著作権条約の著作権表示に必要な©記号

著作権表示(ちょさくけんひょうじ)は、著作物の複製物につける著作権者や著作物の発行年等に関する表示である。著作者が著作権を取得するため、著作物の創作のほか、何らかの手続き等(方式)が必要な法域においては、著作権表示は重要な意味があるが、現在は、ほぼ全ての法域で著作権は、著作物の創作とともに発生するので、重要性は失われている。

法的背景

著作権の発生要件については、無方式主義方式主義の二つの法制が存在するが、前者は大陸法圏に由来する法制であるのに対し、後者は英米法圏に由来する法制であるといわれる。

無方式主義
著作物を著作もしくは発表した時点で自動的に著作権が発生し、それ以外には何らの方式(又は手続)の履行を要求しない法制
方式主義
納入、登録、表示、官庁への納入、登録、登録手数料の支払い、自国内における製造もしくは発行などといった「方式」を履行することにより著作権の発生要件とする法制

無方式主義は、著作権を著作者の自然権としてとらえる大陸法系の思想に合致する。ヨーロッパ諸国は無方式主義を採っており、それらの国々は1886年ベルヌ条約を締結した。ベルヌ条約は無方式主義と内国民待遇を定めており、加盟国は他の加盟国の著作物も、自国の著作物同様に(当然、無方式主義でということになる)保護しなければならない。日本など後発加盟国も、これらに従うことになる。

これに対し、著作権の保護目的を功利主義的にとらえる英米法圏の思想からは、著作権を発生させるために、官庁への登録などの手続を求め、方式主義を採ることは自然である。アメリカ合衆国などアメリカ大陸のいくつかの国は方式主義を取っており、1902年にパンアメリカン条約を締結し、加盟国間で方式主義による著作権を保護した。

こうして、著作権の国際的な保護について世界に二つの陣営が並立し、相手陣営では著作権の保護が受けられなくなった。この問題を解決するため、1952年万国著作権条約が締結された。この条約の3条1項により、加盟国間ならば、無方式主義国で作られた著作物は方式主義国内では著作権表示が方式とみなされ、著作権表示があれば保護されるようになった。

なお、逆に、方式主義国の国民が無方式主義国で保護を受けるには、著作権表示は必要ない。万国著作権条約も内国民待遇を定めているので、加盟国間ならば自国の著作物同様、無方式主義に基づき保護される。

条約上の根拠

条約では、万国著作権条約3条1項に著作権表示に関する規定があり、その内容は、 1952年条約、1971年改正条約とも同一である。

締約国は、自国の国内法令に基き著作権の保護の条件として納入、登録、表示、公証人による証明、手数料の支払又は自国内における製造若しくは発行のような方式に従うことを要求するときは、この条約に基いて保護を受ける著作物で、自国外で最初に発行され、かつ、その著作者が自国民でないものについて、著作者又は著作権を有する他の者の許諾を得て発行された著作物のすべての複製物にその最初の発行の時から©の記号が著作権を有する者の氏名及び最初の発行の年とともに表示されている限り、これらの要求が満たされたものと認めなければならない。ただし、その記号、氏名及び発行の年は、著作権が留保されていることを表示するのに適当な方法で、かつ、適当な場所に掲げなければならない。

書式

万国著作権条約に基づく著作権表示には、次の3つの表示が必要である。

  • ©(丸の中にC、丸C、マルシー)の記号 (symbol ©)
  • 著作権者の氏名 (name of the copyright proprietor)
  • 最初の発行の年 (the year of first publication)

順序は定められておらず、この順序でなくてもいい。慣習的に「©」を最初に書くことが多いが、氏名と年の順序はさまざまである。

使用する文字紀年法も特に定められていないが、国外での著作権保護のためという目的上、ラテン文字西暦を使うのが普通である。

©記号

ベルヌ条約加盟前のアメリカ合衆国の国内法では、「©」以外に「Copyright」や「Copr.」も認められていた(現在も米国著作権法第401条に規定がある)。ただし、国際的に通用することが万国著作権条約で保障されているのは「©」のみである。

コンピュータタイプライターの文書では、文字として登録されていない場合があるので、慣習的に「(c)」や「(C)」も使われる。

著作権者の氏名

著作者ではなく著作権者の氏名を表示する。つまり、著作者が著作権を譲渡売却等した場合は、譲渡等された者の氏名を表示する。

氏名は、周知の変名ペンネーム等)でもかまわない。ただし、周知でない変名(著名でないということではなく、誰のことかわからないということ)は認められない。

複数の著作権者がいる場合は、全ての名を書く。法的にはどんな順序でもいいが、慣習的に、二次著作物原作者と二次著作物の作者を表示する場合は、原作者を先に書く。

最初の発行の年

複数のバージョンがある著作物は最初のバージョンの最初の発行年を表示する。例えば、1990年に最初のバージョンを発行し、2000年に改定したバージョンにつける著作権表示では「1990」となる。これ以外を表示してはいけないということはないので「1990-2000」は問題ないが、「2000」だけでは間違いである。

必要性

ベルヌ条約加盟国

著作権表示が有効な国

著作権表示は、国内での著作権保護に対しては、本国が方式主義か無方式主義か、相手国が方式主義か無方式主義かに関わらず、不要である。必要なのは、万国著作権条約に加盟している無方式主義国の著作物が、方式主義の国で著作権保護を受けたい場合である。

かつてはアメリカ合衆国や一部の中南米諸国が方式主義の万国著作権条約加盟国であり、著作権表示はそれらの国で著作権保護を受けるために必要であった。しかし、アメリカは1988年10月31日に著作権法を改正して無方式主義に切り替え、1989年3月1日に改正が発行し同日にベルヌ条約に加盟した。中南米諸国もまもなくそれに倣った。その後は、方式主義のサウジアラビア1994年7月13日に万国著作権条約に加盟したが、2004年3月11日にはベルヌ条約にも加盟した。

現在では、ほとんどの国はベルヌ条約加盟国(したがって無方式主義)である。わずかな非加盟国もほとんどは、そもそも万国著作権条約にも加盟しておらず、著作権表示は(著作権が認められるか認められないかはともかく)意味がない。なお、双方に非加盟の国(地域)として台湾が有名だが、TRIPS協定加盟国なのでベルヌ条約相当の条約義務を負っている。

著作権表示が有効な国があるとしたら、

  • 方式主義(したがってベルヌ条約に非加盟)で、かつ、次のいずれか。
    • 万国著作権条約加盟国。なお、これに当てはまる可能性がある、ベルヌ条約に非加盟(方式主義とは限らない)の万国著作権条約加盟国は、ラオスカンボジアである[1]
    • 万国著作権条約にも非加盟だが、万国著作権条約とは無関係に著作権表示を認めている国。

ということになるが、現在も存在するかどうかはっきりしない。

副次的な目的

そのため現在は、本来の目的とは異なる、次のような副次的目的が主となっている。

  • 著作者が氏名表示権を行使できる。
  • 著作物の利用者が、著作権消滅の時期や、利用許諾を得るための連絡先を知ることができる。
  • 善意の著作権侵害を予防できる(後述)。

もちろん、著作権表示は著作権という財産権の帰属主体を示しているので、必要がないからといって事実と異なる表示をすると違法行為となる可能性がある。

善意の侵害者

アメリカ合衆国では、著作権者による著作権表示が全く無意味というわけではない。

1988年の改正著作権法は、ベルヌ条約に従い著作権表示の有無に関わらず著作権を認めてはいるが、著作権表示がない場合の「善意の侵害者 (innocent infrigers)」も認めている。この「善意」とは法律用語であり、「ある事実を知らずに何かをすること」を意味する。

善意で著作権を侵害した、つまり、著作権があることを知らずに侵害してしまった場合、法的責任を問われない。つまり、損害賠償責任がない(利益は返還を要求されることがある)。

しかし、著作権表示があった場合、善意の侵害者であるとは認められない。そのため、著作権表示をしていたほうが法的には無難である。

万国著作権条約以外の表示

通常著作権表示と言われるのは、万国著作権条約で定められた「©」表示だが、他の著作権表示や類似の表示もある。

なお、「®」(マルR)はその直前の語が登録商標であることを示す表示で、著作権とは無関係である。

℗(マルP)

「℗」(マルP)表示は、「許諾を得ないレコードの複製からのレコード製作者の保護に関する条約」(レコード保護条約)第5条で定められている[2]原盤権」による保護を受けるための表示である。なお、「レコード」には、CDカセットなどのあらゆる音楽用メディアが含まれる。

原盤権とは、著作権法上の用語では「著作隣接権」のうちの「レコード製作者の権利」であり、いわゆる「マスター音源」の製作者が有する権利である。著作権とは異なる内容の権利である(ただし、アメリカ合衆国著作権法には著作隣接権という概念はなく、原盤権は copyright として扱われる)が、日本では著作権法の中でその権利内容が規定されている。

「©」同様、無方式主義国のレコードが方式主義国で保護を受けるための表示である。ただし、原盤権についても現在ではほとんどの国が無方式主義である。

「℗」記号と、最初の発行年を、レコードまたはその容器包装(ジャケットなど)に表示する。「©」表示と違い、レコードまたはその容器包装の表示から原盤権者が明らかなときは、「℗」表示自体に名前は必要ない。

著作権者と原盤権者が同一である場合には、「℗&© ……」とまとめて表示することもある。

All rights reserved

しばしば著作権表示に書かれる「All rights reserved英語版」は、著作権の保護を受けるための「著作権表示」ではあるが、万国著作権条約とは無関係である。1910年にアメリカ合衆国など方式主義諸国が調印したブエノスアイレス条約(英語: Buenos Aires Convention)第3条で、

The acknowledgement of a copyright obtained in one State, in conformity with its laws, shall produce its

effects of full right, in all the other States, without the necessity of complying with any other formality, provided always there shall appear in the work a statement that indicates the reservation of the property right.[3]

要約: 他の加盟国で著作権保護を受けるには「権利を留保する」という趣旨の表示が必要

と定められていたことによる。この表示により、ブエノスアイレス条約加盟国間で著作権が保護される。

そのため、アメリカのような万国著作権条約加盟国かつブエノスアイレス条約加盟国では、「© 権利者名 発行年 All rights reserved」などという著作権表示がされる。これにより、万国著作権条約加盟国とブエノスアイレス条約加盟国の双方で著作権の保護が受けられる。

ただし現在では、ブエノスアイレス条約加盟国も全てベルヌ条約に加盟しており、無方式主義により一切の著作権表示なしで著作権が保護される。したがって、「All rights reserved」は現在では意味がない。

もちろん、日本などブエノスアイレス条約の非加盟国の著作物には、過去・現在とも意味がない。

版権所有

日本の版権法(明治26年法律第16号)5条で定められていた表記。版権法では、版権(現行の出版権に相当)について保護を受けるためには、内務省に対する登録とともに、出版する複製物に「版権所有」の文字を記載する必要があった。

旧著作権法(明治32年法律第39号)により、著作権の発生要件に関して無方式主義に移行したため、この表記の意味は失われた。

出典

  1. ^ en:List of parties to international copyright agreements
  2. ^ 許諾を得ないレコードの複製からのレコード製作者の保護に関する条約(日本語)
  3. ^ ブエノスアイレス条約原文(英語)

C++

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2017/09/21 06:15 UTC 版)

C++
パラダイム マルチパラダイム手続き型プログラミングデータ抽象オブジェクト指向プログラミングジェネリックプログラミングの組み合わせ)
登場時期 1983年
設計者 ビャーネ・ストロヴストルップ
最新リリース ISO/IEC 14882:2014 / 2014年12月15日(2年前) (2014-12-15
評価版リリース ISO/IEC 14882:2014
型付け nominative, 安全でない強い静的型付け
主な処理系 GCC
Clang
Microsoft Visual C++
Intel C++ Compiler
C++ Builder
方言 C++98
C++03
C++TR1
C++11
C++14
影響を受けた言語 C言語SimulaAda
影響を与えた言語 JavaC#D言語PHP
ウェブサイト isocpp.org
拡張子 .cpp

C++シープラスプラス)は、汎用プログラミング言語の一つである。日本では略してシープラプラシープラなどとも呼ばれる。

概要

1983年にベル研究所のコンピュータ科学者のビャーネ・ストロヴストルップが、C言語の拡張として開発した。当時の名前は「C with Classes」(クラス付きのC言語)だった。拡張はクラスの追加に始まり、仮想関数多重定義多重継承テンプレート例外処理といった機能が続いていった。1990年代以降、C++は、最もよく利用される商用のプログラミング言語の一つとなっている。[要出典]

標準規格化がISOIEC共同で行われており、現在最新のバージョンは、2014年に制定されたISO/IEC 14882:2014、通称「C++14」である。

表現力と効率性の向上のために、手続き型プログラミングデータ抽象オブジェクト指向プログラミングジェネリックプログラミングの複数のプログラミングパラダイムを組み合わせている[1]アセンブリ言語以外の低水準言語を必要としない、使わない機能に時間的・空間的費用を要しないことが、言語設計の重要な原則となっている[2][3]。また、静的な型システムを持つ。

歴史

ストロヴストルップはプログラミング言語C with Classesの開発を1979年に開始した。彼は大規模なソフトウェアの開発に有用な特徴をSimulaが備えていることに気がついたが、Simulaは実行速度が遅く実用的ではなかった。一方でBCPLは実行速度こそ速かったものの、大規模なソフトウェア開発を念頭に置いた場合にあまりにも低級だった。

これらの事情を鑑みて、ストロヴストルップは当時既に汎用的な言語だったC言語にSimulaの特徴を取り入れることを試みた。この取り組みにあたってはALGOL68AdaCLUML等の言語の影響も受けている。最初はクラスと派生クラス、型検査機構の強化、インライン関数、デフォルト引数の機能を、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」である。

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
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年予定 C++17

長年にわたる作業の後、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) が投票で承認され[12]、2014年12月15日、公式に出版された。

現在、C++17の仕様策定が進められている。

将来

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言語FORTRANPascalBASICのような言語を用いて作成されたライブラリを利用できる。規格外のライブラリが利用できるかどうかはコンパイラに依存する。

C++標準ライブラリはC++向けに若干の最適化が施されたC言語標準ライブラリを含んでいる。C++標準ライブラリの大部分はSTLである。 コンテナ可変長配列リストなど)、コンテナを配列のように扱えるようにするイテレータ、検索やソートを行うアルゴリズムといった有用なツールが提供されている。さらにmapmultimapのような連想配列や、setmultisetのようなソート済みコンテナも提供され、これらは全てインターフェイスに互換性がある。テンプレートを用いることにより、あらゆるコンテナ(またはイテレータで定義したシーケンス)に適用できる汎用的なアルゴリズムを記述できる。C言語と同様にライブラリ機能には#include ディレクティブを使ってヘッダファイルを読み込むことによってアクセスする。C++には69本の標準ヘッダファイルがあるが、このうち19本については非推奨となっている。

STLは標準規格に採用される前は、ヒューレット・パッカードの(一時はシリコングラフィックスの)商用ライブラリだった。STLは標準規格の単なる一部分に過ぎず規格書にSTLという表記は見られないが、入出力ストリーム、国際化、デバッグ機能、C言語標準ライブラリ等の、STL以外の部分と区別するために、今でも多くの人がSTLという用語を使っている。

大半のC++コンパイラはSTLを含むC++標準ライブラリの実装を提供している。STLPortのようなコンパイラ非依存のSTLも存在する。様々な目的でC++標準ライブラリを独自に実装しているプロジェクトは他にもある。

C++の標準ライブラリは大きく次のように分けられる。多種多様な実行環境が存在することを考慮して、GUIに関するライブラリは標準に含まれていない。

外部ライブラリ

以下に、C++で広く使われていると思われるライブラリを挙げる。

Boost
次期C++標準とも言われる様々なライブラリの集合。正規表現を扱うBoost.Regexや無名関数(ラムダ計算)を簡潔に記述できるBoost Lambda Libraryなどがある。現標準であるC++11や次期標準であるC++14でも、Boostに存在するライブラリが標準ライブラリに採用されたり、標準ライブラリとして提案された項目がBoostで先行して実装されたりしている。これにより、実際に実装・使用することでの知見が得られ、標準ライブラリとして採用される際に活かされている。
Apache Xerces
C++での主要XMLパーサの一つ。Java版も存在する。
CppUnit
C++でのユニットテストフレームワーク。 クラス毎の動作確認に威力を発揮する。

特徴

C言語に、オブジェクト指向プログラミングをはじめとする様々なプログラミングパラダイムをサポートするための改良が加えられたものといえる。ただし、他のプログラミング言語と違い、旧来のCと同様に手続き型言語としても扱えるという特徴がある。このことから、C++をbetter Cというふうに呼ぶことがある。すなわち、基本的にC言語に対して上位互換性がある。初期のC++はCへのトランスレータとして実装され、C++プログラムを一旦Cプログラムに変換してからコンパイルしていた。

ただし、C++という名称が定まった当初の時期から、C言語とC++との間には厳密な互換性はない[13][14]。当時、Cとの互換性について議論の末、「C++とANSI Cの間には不正当な非互換性はない」という合意が形成されることとなった。そのため、正当な非互換性を巡って多くの議論が発生した[15]。ただし、まだANSIによるC言語の標準規格も策定途中の時期である。

その後、先祖であるC言語のANSIによる標準規格制定時には、関数のプロトタイプ宣言やconst修飾など、C++の機能がC言語に取り入れられることにもなった。C99の出現により、//コメントなどのC++で使われていた便利な機能が加わってCとC++の互換性が高まる一方、別々に審議し、別の時期に発行していることと、開発対象が必ずしも同じでないために利害関係者が異なることによる違いもある[要出典]​。

次のような多種多様な機能を持っており、言語仕様は大変複雑である。

ここから、よりオブジェクト指向を強化し、「なんでもあり」ではない代わりに分かりやすくスマートな設計を目指した新たな言語(JavaD言語など)が作られることとなった。

Hello, World!

C++はC言語およびそのプリプロセッサの構文をほぼ継承している。以下のサンプルはビャーネ・ストロヴストルップの書籍「The C++ Programming Language, 4th Edition」(ISBN 978-0321563842) の「2.2.1 Hello, World!」に記載されている標準C++ライブラリのストリーム機能を用いて標準出力に出力するHello worldプログラムである[16][17]

#include <iostream>

int main()
{
     std::cout << "Hello, World!\n";
}

書籍でも明記されているが、main()関数で意図的に返り値を返さない手法が使用されている。

演算子と演算子のオーバーロード

C++には四則演算、ビット演算、参照、比較、論理演算などの30を超える演算子がある。メンバーアクセス演算子(..*)のような一部の例外はあるが、大半の演算子はユーザー定義によるオーバーロードが可能である。オーバーロード可能な演算子が豊富に揃えられているためC++を一種のドメイン固有言語として利用できる。またオーバーロード可能な演算子はスマートポインタのような先進的な実装テクニックに欠かせないものとなっている。演算子をオーバーロードしても演算の優先順位は変化せず、また演算子のオペランドの数も変化しない。ただし指定したオペランドが無視される可能性はある。

テンプレート

C++には、ジェネリックプログラミングを実現する機能としてテンプレートが存在する。テンプレートにできる対象は、関数とクラスである。テンプレートは型、コンパイル時定数またはその他のテンプレートによってパラメタライズできる。テンプレートはコンパイル時にインスタンス化(実体化・具現化などとも)される。コンパイラは関数やクラスをインスタンス化するためにテンプレート仮引数を特定の値に置き換える。テンプレートはジェネリックプログラミングテンプレートメタプログラミング、コード最適化などのために利用される強力なツールであるが、一定のコストを伴う。各テンプレートのインスタンスはテンプレート仮引数毎にテンプレートコードのコピーを生成するためコードサイズが肥大化する。コンパイル時に型の情報を削除して単一のテンプレートインスタンスを生成するランタイム型のジェネリクスを実装したJavaなどの言語とは対照的である。

テンプレートとマクロはいずれもコンパイル時に処理される言語機能であり条件に基づいたコンパイルが行われるが、テンプレートは字句の置き換えに限定されない。テンプレートはC++の構文と型を解析し、厳密な型チェックに基づいた高度なプログラムの流れの制御ができる。マクロは条件コンパイルに利用できるが、新しい型の生成、再帰的定義、型の評価などは行えないため、コンパイル前のテキストの置き換えや追加・削除といった用途に限定される。つまりマクロは事前に定義されたシンボルに基づいてコンパイルの流れを制御できるものの、テンプレートとは異なり独立して新しいシンボルを生成することはできない。テンプレートは静的な多態(下記参照)とジェネリックプログラミングのためのツールである。

C++のテンプレートはコンパイル時におけるチューリング完全なメカニズムである。これはテンプレートメタプログラムを用いて実行する前にコンピュータが計算可能なあらゆる処理を表現できることを意味している。

概略すれば、テンプレートはインスタンス化に必要な引数を明確にしなくても記述できるコンパイル時にパラメタライズされる関数またはクラスである。インスタンス化した結果は、テンプレート仮引数に指定した型に特化した形で記述されたコードと全く等価になる。これによりテンプレートは、汎用的かつおおまかに記述された関数及びクラス(テンプレート)と特定の型に特化した実装(インスタンス化されたテンプレート)の依存関係を解消し、パフォーマンスを犠牲にすることなく抽象化できる手段を提供する。

オブジェクト

C++はC言語オブジェクト指向プログラミングをサポートするための改良を加えたものといえる。C++のクラスには、オブジェクト指向言語で一般的な抽象化カプセル化継承多態の4つの機能がある。オブジェクトは実行時に生成されるクラスの実体である。クラスは実行時に生成される様々なオブジェクトのひな形と考えることができる。

なお、C++はSmalltalkなどに見られるメッセージ転送の概念によるオブジェクト指向を採用していない。

カプセル化

カプセル化とは、データ構造を保証し、演算子が意図したとおりに動作し、クラスの利用者が直感的に使い方を理解できるようにするためにデータを隠蔽することである。クラスや関数はC++の基礎的なカプセル化のメカニズムである。クラスのメンバはpublicprotectedprivateのいずれかとして宣言され明示的にカプセル化できる。publicなメンバはどの関数からでもアクセスできる。privateなメンバはクラスのメンバ関数から、またはクラスが明示的にアクセス権を与えたフレンド関数からアクセスできる。protectedなメンバはクラスのメンバおよびフレンド関数に加えてその派生クラスのメンバからもアクセスできる。

オブジェクト指向では原則としてクラスのメンバ変数にアクセスする全ての関数はクラスの中にカプセル化されなければならない。C++ではメンバ関数およびフレンド関数によりこれをサポートするが、強制はされない。プログラマはメンバ変数の一部または全体をpublicとして定義でき、型とは無関係な変数をpublicな要素として定義できる。このことからC++はオブジェクト指向だけでなく、モジュール化のような機能分割のパラダイムもサポートしているといえる。

一般的には、全てのデータprivateまたはprotectedにして、クラスのユーザに必要最小限の関数のみをpublicとして公開することがよい習慣であると考えられている。このようにしてデータの実装の詳細を隠蔽することにより、設計者はインターフェイスを変更することなく後日実装を根本から変更できる [18] [19]

継承

継承を使うと他のクラスの資産を流用できる。基底クラスからの継承はpublicprotectedprivateのいずれかとして宣言する。このアクセス指定子により、派生クラスや全く無関係なクラスが基底クラスのpublicおよびprotectedメンバにアクセスできるかどうかを決定できる。普通はpublic継承のみがいわゆる派生に対応する。残りの二つの継承方法はあまり利用されない。アクセス指定子を省略した場合、構造体public継承になるのに対し、クラスではprivate継承になる。基底クラスをvirtualとして宣言することもできる。これは仮想継承と呼ばれる。仮想継承は基底クラスのオブジェクトが一つだけ存在することを保証するものであり、多重継承の曖昧さの問題を避けることができる。

多重継承はC++の中でもしばしば問題になる機能である。多重継承では複数の基底クラスから一つのクラスを派生できる。これにより継承関係が複雑になる。例えば"FlyingCat"クラスは"Cat"クラスと"FlyingMammal"クラスから派生できる。JavaC#では、基底クラスの数を一つに制限する一方で、複数のインタフェースを継承でき、これにより制約はあるものの多重継承に近い機能を実現できる。インタフェースはクラスと異なりメンバ関数を宣言できるのみであり、関数の実装やメンバ変数は定義できない。JavaとC#のインタフェースや抽象クラスはC++の抽象基底クラスと呼ばれる関数宣言のみを持つクラスに相当する。JavaやC#の継承モデルを好むプログラマは、非抽象クラスからのみクラスを派生させる方法を選択できる。この場合は抽象基底クラスのメンバ関数を必ず明示的に定義しなければならず、またこのクラスを継承することはできない。

多態

多態(ポリモーフィズム)はよく多用されているインターフェイスの機能であり、様々な状況下でオブジェクトに異なる振る舞いをさせることができる。

C++は静的な多態動的な多態の両方をサポートする。コンパイル時に解決される静的な多態は実行時には考慮されないのに対し、ランタイム時に解決される動的な多態はパフォーマンス的に不利である。

静的な多態

関数のオーバーロードは名称が同じ複数の関数を宣言できる機能である。ただし引数は異なっていなければならない。関数は引数の型や数で区別される。同名の関数はコードの文脈によってどの関数が呼ばれるのかが決まる。関数の戻り値の型で区別することはできない。

関数を宣言する際にプログラマはデフォルト引数を指定できる。関数を呼び出すときに引数を省略した場合はデフォルト引数が適用される。関数を呼び出すときに宣言よりも引数の数が少ない場合は、左から右の順で引数の型が比較され、後半部分にデフォルト引数が適用される。たいていの場合は一つの関数にデフォルト引数を指定するよりも引数の数が異なる関数をオーバーロードする方が望ましい。

C++のテンプレートではより洗練された汎用的な多態を実現できる。特にCuriously Recurring Template Patternにより仮想関数のオーバーライドをシミュレートした静的な多態を実装できる。C++のテンプレートは型安全かつ チューリング完全であるため、 テンプレートメタプログラミングによりコンパイラに条件文を再帰的に解決させて実行コードを生成させることにも利用できる。

動的な多態

派生

基底クラスへのポインタ変数及び参照は、正確に型が一致するオブジェクトだけでなく、その派生クラスのオブジェクトを示すことができる。これにより配列やコンテナは複数の型へのポインタを保持できる。ポインタ変数は実行時に値が割り当てられるためこれは実行時の話である。

dynamic_castは基底オブジェクトから派生オブジェクトへの変換を安全に行うための演算子である(派生オブジェクトから基底オブジェクトへの変換ではキャストは必要ない)。この機能は実行時型情報 (RTTI)に依存している。オブジェクトが特定の派生オブジェクトであることがあらかじめわかっている場合はstatic_castでキャストすることもできる。static_castは純粋にコンパイル時に解決されるため動作が速くRTTIを必要としない。

仮想関数

基底クラスの関数を派生クラスでオーバーライドした場合、実際に呼び出される関数はオブジェクトの型によって決定される。派生クラスによってオーバーライドでされるのは引数の数や型が同じ関数である。基底クラスのポインタのみが与えられた場合、コンパイラはオブジェクトの型をコンパイル時に特定できず正しい関数を呼び出せないため、実行時にこれを特定する。これをダイナミックディスパッチと呼ぶ。仮想関数やメソッド[20]により、オブジェクトに割り当てられた実際の型に従って、最上位の派生クラスで実装した関数が呼び出される。一般的なC++コンパイラは仮想関数テーブルを用いる。オブジェクトの型が判明している場合はスコープ解決演算子を利用して仮想関数テーブルを使わないようにバイパスすることもできるが、一般的には実行時に仮想関数の呼び出しを解決するのが普通である。

標準のメンバ関数に加え、オーバーロードした演算子やデストラクタも仮想関数にできる。原則的にはクラスが仮想関数を持つ場合はデストラクタも仮想関数にすべきである。コンストラクタやその延長線上にあるコピーコンストラクタはコンパイルされた時点でオブジェクトの型が確定しないため仮想関数にできない。しかし、派生オブジェクトへのポインタが基底オブジェクトへのポインタとして渡された場合に、そのオブジェクトのコピーを作らなければならない場合は問題が生じる。このような場合はclone()関数(またはそれに準じる物)を仮想関数として作成するのが一般的な解決方法である。clone()は派生クラスのコピーを生成して返す。

= 0を関数宣言の閉じ括弧とセミコロンの間に挿入することによりメンバ関数を純粋仮想関数にできる。純粋仮想関数を持つクラスは純粋仮想クラスと呼ばれ、このクラスからオブジェクトを生成することはできない。このような純粋仮想クラスは基底クラスとしてのみ利用できる。派生クラスは純粋仮称関数を継承するため、派生クラスのオブジェクトを生成したい場合は全ての純粋仮想関数をオーバーライドして実装しなければならない。純粋仮想関数を持つクラスのオブジェクトを生成しようと試みるようなプログラムは行儀が悪い。

テンプレート

型消去と呼ばれるテンプレートを活用して動的な多態性を実現する手法が存在する。この手法はC++の標準ライブラリでもstd::functionstd::shared_ptrの削除子で採用されている。いずれも、コンストラクタや代入演算子で(一定の条件を満たす)任意のオブジェクトを実引数として渡せるようにすることから多態性を実現している。

単一行コメント

かつてC言語とC++との分かりやすい差異として、// で始まり改行で終わる、単一行コメントの有無があった。

単一行コメントはもともと、C言語の祖先にあたるBCPLに含まれていた仕様である。現在のC++のコンパイラの多くがC言語のコンパイラとしても使えるようになっているのと同様に、C言語が生まれて間もない頃は、C言語に加えB言語やBCPLのコンパイルができるコンパイラが用いられていた。それらコンパイラは、C言語のソースであってもBCPLと同様に単一行コメントが使用できるよう独自の拡張がなされていたため、BCPLの単一行コメントに慣れ親しんでいたプログラマ達は、C言語でも単一行コメントを使い続けた。その慣習がC++の誕生時まで生き残っていたため、C++では単一行コメントを「復活」させることになった。

そのためもあって、C言語での仕様外の単一行コメントの使用は半ば常習と化し、現在ではC99によって、C言語でも正式に単一行コメントがサポートされるようになった(//に対応していない古い仕様のCコンパイラでもcppを対応したものに変更することにより使用可能)。

C++ソースコードの処理とパーサ

LALR(1)のような旧式のパースアルゴリズムを用いてC++のパーサを記述することは比較的難しい[21]。その理由の一つはC++の文法がLALRではないことである。このため、コード分析ツールや、高度な修正を行うツール(リファクタリングツールなど)は非常に少ない。この問題を取り扱う方法としてLALR(1)でパースできるように改良されたC++の亜種(SPECS)を利用する方法がある。GLRパーサのようにより強力でシンプルなパーサもあるが処理が遅い。

パースはC++を処理するツールを作成する際の最も難しい問題ではない。このようなツールはコンパイラと同じように識別子の意味を理解しなければならない。従ってC++を処理する実用的なシステムはソースコードをパースするだけでなく、各識別子の定義を正確に適用し(つまりC++の複雑なスコープのルールを正確に取り扱い)、型を正しく特定できなければならない。

いずれにせよC++ソースコード処理ツールが実用的であるためには、GNU GCCVisual C++で使われているような、様々なC++の方言を取り扱えなければならず、適切な分析処理やソース変換やソース出力などが実装できなければならない。GLRのような先進的なパースアルゴリズムとシンボルテーブルを組み合わせてソースコードを変換する方法を利用すればあらゆるC++ツールを開発できる。

互換性

その言語文法の複雑さゆえ、C++規格に準拠したコンパイラを開発するのは一般的に難しい。20世紀末から何年にも渡りC++に部分的に準拠した様々なコンパイラが作られ、テンプレートの部分特殊化などの部分で実装にばらつきがあった。 中でも、テンプレートの宣言と実装を分離できるようにするためのexportは問題のキーワードの一つだった。exportを定義したC++98規格がリリースされてから5年後の2003年前半にComeau C/C++が初めてexportを実装した。2004年にBorland C++ Builder Xexportを実装した。これらのコンパイラはいずれもEDGのフロントエンドをベースにしていた。大半のコンパイラで実装されていないexportは多くのC++関連書籍(例えば"Beginning ANSI C++", Ivor Horton著)にサンプルが記されているが、exportが記載されていることによる問題は特に指摘されていない。GCCをはじめとするその他のコンパイラでは全くサポートしていない。Herb SutterはC++の標準規格からexportを削除することを推奨していたが[22]、C++98では最終的にこれを残す決定がなされた[23]。結局、C++11では実装の少なさ・困難さを理由に削除された。

コンパイラ開発者の裁量で決められる範囲を確保するため、C++標準化委員会は名前修飾例外処理などの実装に依存する機能の実装方法を決定しないことに決めた。この決定の問題は、コンパイラが異なるとオブジェクトファイルの互換性が保証されない点である。特定の機種やOSでコンパイラの互換性を持たせ、バイナリレベルでのコード再利用性を高めようとするABI[24]のような非標準の規格もあり、一部のコンパイラではこうした準規格を採用している。

2015年現在のメジャーなC++コンパイラ(gcc, Clang, Intel C++ Compiler, Microsoft Visual C++など)の最新版はC++11規格にほぼ準拠しており、特にClangは2013年4月時点で全機能を実装完了した [25] [26]。ただしマイナーアップデートとなるC++14を含めると、処理系間でのばらつきは依然として存在する。

C言語との互換性

C++は基本的にC言語の上位互換であるが、厳密には異なる[27]。C言語で記述された大半のプログラムはC++でコンパイルできるように簡単に修正できるが、C言語では正当でもC++では不正になる部分や、C++とは動作が異なる部分が若干存在する。

例えば、C言語では汎用ポインタ void* は他の型へのポインタに暗黙的に変換できるが、C++ではキャスト演算子によって変換を明示する必要がある。またC++では newclass といった数多くの新しいキーワードが追加されたが、移植の際に元のC言語のプログラムでそれらが識別子(例えば変数名)として使われていると、問題になる。

C言語の標準規格である C99 やその後継 C11 ではこうした非互換性の一部が解決されており、//形式のコメントや宣言とコードの混在といったC++の機能がC言語でサポートされている。その一方でC99では、可変長配列、複素数型の組み込み変数、指示初期化子、複合リテラルといった、C++でサポートしていない数多くの新機能が追加された[28]。C99で追加された新機能の一部はC++11に反映され、次期C++1yに対してもC99やC11との互換性を向上される提案が行われている。また、可変長配列や複素数型などの C99 に追加された機能の一部は C11 でオプションとなった[29]

C++で書かれた関数をC言語で書かれたプログラムから呼び出す、あるいはその逆を行なう場合など、C言語のコードとC++のコードを混在させるためにはCリンケージを利用する必要があり、関数をextern "C"で個別に修飾するか、extern "C" { ... }のブロックの中で宣言しなければならない。また、関数引数や戻り値などのインターフェイスはC言語互換形式に合わせる必要がある。Cリンケージを利用した関数については、C++名前修飾がされず、名前修飾に依存している関数オーバーロード機能は利用できない。

C/C++の相互運用性が確保されていることで、慣れ親しんだC言語標準ライブラリ関数の大半をC++でもそのまま利用し続けることができるということはC++の大きなメリットのひとつである。

主なC++処理系

脚注

[ヘルプ]
  1. ^ 『プログラミング言語C++』第4版、pp.12-13。
  2. ^ 『C++の設計と進化』、pp.152-153。
  3. ^ 『プログラミング言語C++』第4版、p.11。
  4. ^ Bjarne Stroustrup's FAQ - When was C++ invented?” (English). 2006年5月30日閲覧。
  5. ^ Bjarne Stroustrup; Margaret A. Ellis (1990). The Annotated C++ Reference Manual. Addison-Wesley Professional. ISBN 978-0201514599. 
  6. ^ Bjarne Stroustrup; Margaret A. Ellis 『The Annotated C++ Reference Manual』 足立高徳、小山裕司、シイエム・シイ、2001年ISBN 978-4901280396
  7. ^ ISO/IEC 14882:1998
  8. ^ ISO/IEC 14882:2003
  9. ^ ISO/IEC TR 19768:2007
  10. ^ ISO/IEC 14882:2011
  11. ^ ISO/IEC 14882:2014
  12. ^ We have C++14! : Standard C++
  13. ^ Koenig, Andrew; Bjarne Stroustrup (1989年5月11日). “C++: as close as possible to C – but no closer (PDF)” (英語). 2016年11月19日閲覧。
  14. ^ Stroustrup, Bjarne. “Stroustrup: FAQ Is C a subset of C++?” (英語). 2016年11月19日閲覧。
  15. ^ 『C++の設計と進化』、pp.124-125。
  16. ^ Bjarne Stroustrup (2000年). The C++ Programming Language (Special Edition ed.). Addison-Wesley. pp. 46. ISBN 0-201-70073-5. 
  17. ^ Open issues for The C++ Programming Language (3rd Edition) - このコードはストロヴストルップ自身による訂正文からの引用(633ページ)。std::endl'\n'に改めている。またmain関数がデフォルトで0を返す件についてはwww.research.att.com及びwww.delorie.com/djgpp/ を参照されたし。このデフォルト仕様はmain関数のみであり他の関数にはない。
  18. ^ Sutter, Herb; Alexandrescu, Andrei (2004). C++ Coding Standards: 101 Rules, Guidelines, and Best Practices. Addison-Wesley. 
  19. ^ Henricson, Mats; Nyquist, Erik (1997). Industrial Strength C++. Prentice Hall. ISBN ISBN 0-13-120965-5. 
  20. ^ 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. (仮想関数のことをメソッドと呼ぶ場合がある)" 
  21. ^ Andrew Birkett. “Parsing C++ at nobugs.org”. Nobugs.org. 2009年7月3日閲覧。
  22. ^ Why We Can’t Afford Export (PDF, 266 KB)
  23. ^ Minutes of J16 Meeting No. 36/WG21 Meeting No. 31, April 7-11, 2003” (2003年4月25日). 2006年9月4日閲覧。
  24. ^ C++ ABI”. 2006年5月30日閲覧。
  25. ^ 後藤大地 (2013年4月22日). “LLVM Clang、C++11にフル対応”. マイナビニュース. 2013年9月7日閲覧。
  26. ^ GCC 4.8.1 - C++11全実装バージョン”. Faith and Brave - C++で遊ぼう (2013年6月7日). 2013年9月7日閲覧。
  27. ^ Bjarne Stroustrup's FAQ - Is C a subset of C++?”. 2008年1月18日閲覧。
  28. ^ C9X -- The New C Standard”. 2008年12月27日閲覧。
  29. ^ C言語の最新事情を知る: C99の仕様 - Build Insider

参考文献

関連項目

外部リンク


C Sharp

(c から転送)

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2017/09/18 17:48 UTC 版)

本来の表記は「C#」です。この記事に付けられた題名は、技術的な制限により、記事名の制約から不正確なものとなっています。
C#
C#のロゴマーク。テキスト上では#と代替表記されるが、正式には♯と描く。
パラダイム 構造化, 命令型, オブジェクト指向, 関数型, イベント駆動型, ジェネリック, リフレクション, 並行計算
登場時期 2000年 (2000)
設計者 マイクロソフトアンダース・ヘルスバーグ率いるチーム)
開発者 マイクロソフト
最新リリース 7.0 / 2017年3月7日(6か月前) (2017-03-07
型付け 強い静的型付け(4.0から動的型導入)
主な処理系 CLR, Mono
方言 1.0, 1.5, 2.0 (ECMA), 3.0, 3.5, 4.0, 5.0, 6.0, 7.0
影響を受けた言語 C++, Delphi, Eiffel, Java, LISP
影響を与えた言語 D言語, F#, Java, Nemerle, Vala
プラットフォーム Windows, macOS, Linuxなど
ライセンス Apacheライセンス (Roslyn)
ウェブサイト www.visualstudio.com

C#(シーシャープ)とは、マイクロソフトが開発したマルチパラダイムプログラミング言語。強い型付け命令型宣言型手続き型関数型ジェネリックオブジェクト指向の要素を持つ。

マイクロソフトのソフトウェアフレームワークである.NET Frameworkとともに作られ、Ecma International[1]および国際標準化機構 (ISO)[2] によって標準化されており、日本においても日本工業規格 (JIS)[3]によって採択された。

概要

開発にはボーランド社のTurbo PascalDelphiを開発したアンダース・ヘルスバーグを筆頭に多数のDelphi開発陣が参加している。

C#は共通言語基盤共通言語ランタイムなど)が解釈する共通中間言語コンパイルされて実行される。基本的な書式がC言語風になっているため、初見の構文はサン・マイクロシステムズ社によるJavaに近いと言われるが、実際の構文はDelphiに準じており、C言語風ということもありC++ Builderの独自拡張構文に極めて近い内容となっている。またプロパティデリゲートなどDelphiの構文そのまま、もしくは名称変更しただけの機能となっているものが多い。

自動ボックス化デリゲートプロパティインデクサカスタム属性ポインタ演算操作、構造体(値型オブジェクト)、多次元配列可変長引数、などの機能を持つ。また、Javaと同様に大規模ライブラリプロセッサ・アーキテクチャに依存しない実行形態、ガベージコレクションJITコンパイルによる実行の高速化、などが実現されている(もっともこれらはC#の機能というより.NET Frameworkによるものである)。

.NET構想における中心的な開発言語であり、XML WebサービスASP.NETの記述にも使用される。他の.NET系の言語でも記述可能だが、生産性・機能においてC#が最も優れるとされる。マイクロソフトの統合開発環境では、Microsoft Visual C#がC#に対応している。

共通言語仕様のCLSによって、他のCLS準拠の言語(Visual Basic .NETVisual C++ (C++/CLI)など)と相互に連携することができる。他言語で記述されたクラス継承することも、またその逆も可能である。

リリース時期

  • 1.0  2002年4月
  • 1.1  2003年5月
  • 2.0  2005年12月
  • 3.0  2007年12月
  • 4.0  2010年4月
  • 5.0  2012年8月
  • 6.0  2015年7月
  • 7.0  2017年3月

言語仕様

さまざまな意味において、基盤であるCLIの機能をもっとも反映している言語であるといえる。C#にある組み込み型のほとんどは、CLIフレームワークに実装されている値型と対応している。しかし、C#の言語仕様はコンパイラのコード生成については何も言及していない。つまり、CLRに対応しなければならないとか、共通中間言語 (CIL) などの特定のフォーマットのコードを生成しなければならないとかいうことは述べられていない。そのため、理論的にはC++FORTRANのように環境依存のマシン語を生成することも可能である。しかし、現在存在するすべてのC#コンパイラはCLIをターゲットにしている。

CやC++からの改良点

C#では、CやC++と比較してさまざまな制限や改良が加えられている。その例を次に挙げる。

  • グローバル変数やグローバルメソッドは存在しない。すべてのメソッドとメンバはクラスの一部として宣言されなければならない。
  • 外のブロックで宣言した変数名を、内のブロックで再宣言してはいけない。これはC++ではしばしば混乱や曖昧のもととされているが、C#では禁止されている。
  • Cのprintf()関数のように関数をグローバルで公開するのではなく、すべての関数はクラス内で宣言されなければならない。ほとんどの場合クラスは名前の衝突を避けるために名前空間に所属する。
  • 名前空間は階層構造をもつ。つまり、名前空間は他の名前空間の中に宣言することができる。
  • 原始型を含めたすべての型は、objectクラスの派生クラスである。つまりobjectクラスのもつすべてのプロパティやメソッドを継承する。例えば、すべての型はToString()メソッドをもつ。
  • C#にはブール型boolが存在する。whileifのように条件をとるステートメントには、bool型の式を与えなければならない。CやC++にもブール型が存在するが、これは整数型と相互に変換可能で、while文やif文に与える式として整数やポインタも許容していた。C#ではミスを防止するために、このブール型と整数が可換であるという仕様を禁止している。
  • ポインタをサポートする。ポインタはunsafeスコープ内のみで使用することができ、適切な権限をもつプログラムのみがunsafeとマークされたコードを実行することができる。オブジェクトへのアクセスの大部分は管理された安全な参照によってなされ、大部分の算術演算はオーバフローのチェックがなされる。unsafeポインタは値型や文字列を指すことができる。セーフコードでは、必ずしもそうする必要はないものの、IntPtr型を通してポインタをやりとりすることができる。
  • マネージドなメモリを明示的に解放する方法は存在せず、参照されなくなったメモリはガベージコレクタによって自動的に解放される。ガベージコレクタは、メモリの解放忘れによって起こるメモリリークを解消する。C#は、データベース接続のようなアンマネージドなリソースに対しても明示的に制御する方法を提供している。これはIDisposableインタフェースとusingステートメントによってなされる。
  • クラスは複数のインタフェースを実装することができるが、多重継承はサポートされない。
  • C#はC++に比べて型安全である。既定の暗黙変換は、整数の範囲を広げる変換や、派生クラスから基底クラスへの変換といった、安全な変換のみに限定される。これは、コンパイル時、JITコンパイル時、そして一部の動的なケースでは実行時に強制される。ブール型と整数型、列挙型と整数型、の間は暗黙変換はできない。暗黙変換をユーザ定義する際は、明示的にそのように指定しなければならない。これはC++のコンストラクタとは違った仕様である。
  • 列挙型のメンバは、列挙型の名前空間の中におかれる。また、列挙型の定数名を取得することができる。さらに、列挙型の定数名から動的に定数値を得ることができる。
  • プロパティと呼ばれるアクセサは、C++におけるメンバフィールドのような構文でオブジェクトにアクセスすることができる。C++では、publicとしてメンバを宣言することでメンバを読むことも変更することもできるようになるが、C#ではプロパティによってメンバアクセスやデータの正当性チェックを制御することができる。
  • switch文で、基本型のみならず、定数文字列によって分岐することができる。

C# 2.0からの仕様

部分型

部分型 (Partial Type) が導入された。以下のようにクラスや構造体の宣言にpartial修飾子をつけることで、その宣言を分割することができる。

partial class MyClass { int a; }
partial class MyClass { int b; }

これは以下と同義である:

class MyClass { int a; int b; }

これによって、巨大なクラスを分割したり、自動生成されたコードを分離したりすることができる。partial 修飾子はすべての宣言につける必要がある。

ジェネリクス

ジェネリクスが導入された。これは.NET Framework 2.0の機能である。クラス、構造体、インタフェース、デリゲート、メソッドに対して適用することができる。.NETのGenericsはC++のテンプレート、あるいはJavaにおけるそれとも異なるもので、コンパイルによってではなく実行時にランタイムによって特殊化される。これによって異なる言語間の運用を可能にし、リフレクションによって型パラメタに関する情報を取得することができる。また、where節によって型パラメタに制約を与えることができる。一方、C++のように型パラメタとしてを指定することはできない。なお、ジェネリックメソッドの呼び出し時に引数によって型パラメタが推論できる場合、型パラメタの指定は省略できる。

静的クラス

静的クラスが導入された。static属性をクラスの宣言につけることで、クラスはインスタンス化できなくなり、静的なメンバしか持つことができなくなる。

yieldキーワード

yieldキーワードによるコルーチンを使うことで、イテレータを楽に実装できるようになった。

匿名デリゲート

クロージャの機能を提供する匿名デリゲートが導入された。

プロパティに対する個別のアクセス制御

プロパティのget もしくは setアクセサのどちらかにアクセス修飾子を指定することでアクセス制御が別個にできるようになった。次の例では、getアクセサはpublicsetアクセサはprivateである。

public class MyClass
{
  private string status = string.Empty;
  public string Status
  {
    get { return status; }
    private set { status = value; }
  }
}

Null許容型とnull結合演算子

nullを保持できる値型、Nullableが導入された。

int? i = 512;
i = null;

int? j = i + 500; //jはnullとなる。nullとの演算の結果はnullになる。

int?Nullable<int>糖衣構文である。また、nullを保持しているNull許容型のインスタンスをボックス化しようとすると、単に空参照 (null) に変換される[4]

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 キーワードが導入され、型推論を利用したローカル変数の宣言ができるようになった。

var s = "foo";
// 上の文は右辺が string 型であるため、次のように解釈される:
string s = "foo";
// 以下に挙げる文は誤りである(コンパイルエラーとなる):
var v; // 初期化式を欠いている (型を推論する対象が存在しない)
var v = null; // 型が推論できない (曖昧である)

拡張メソッド

拡張メソッドが導入された。既存のクラスを継承して新たなクラスを定義することなく新たなインスタンスメソッドを追加定義することができる。具体的には、独自の静的クラス内に 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 型に、文字列 (string 型のインスタンス)を指定した回数繰り返したものを返すメソッド Repeat を追加している。このメソッドは、以下のように呼び出すことができる:

// 静的メソッドとしての呼び出し
StringUtil.Repeat("foo", 4);
// 拡張メソッドとしての呼び出し
"foo".Repeat(4);
// (どちらの例も "foofoofoofoo" を返す)

また、列挙型やインターフェースなど本来メソッドの実装を持ち得ない型に、見かけ上インスタンスメソッドを追加することも可能である。以下に例を挙げる:

public enum Way
{
  None, Left, Right, Up, Down
}

public static 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

部分メソッド

部分メソッドが導入された。部分型(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. と表示される。

ラムダ式

匿名メソッドをより簡略化した記法として、ラムダ式が導入された。この名前はラムダ計算に由来する。

以下の匿名メソッド

// 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 と命名している。実際はプログラマはこの変数にアクセスすることはできない。

自動実装プロパティ

プロパティをより簡潔に記述するための自動実装プロパティが導入された。プロパティの定義に 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 と命名している。実際はプログラマはこのフィールドにアクセスすることはできない。

匿名型

一時的に使用される型を簡単に定義するための匿名型が導入された。以下に例を挙げる:

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 をサポートするために、クエリ式が導入された。これは 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キーワードが導入され、動的型付け変数を定義できるようになった。dynamic型として宣言されたオブジェクトに対する操作のバインドは実行時まで遅延される。

// xはint型と推論される:
var x = 1; 
// yはdynamic型として扱われる:
dynamic y = 2; 

public dynamic GetValue(dynamic obj)
{
  // objにValueが定義されていなくとも、コンパイルエラーとはならない:
  return obj.Value;
}

オプション引数・名前付き引数

VBC++に実装されているオプション引数・名前付き引数が、C#でも利用できるようになった。

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修飾子を指定することにより、ジェネリクスの共変性・反変性を指定できるようになった。

IEnumerable<string> x = new List<string> { "a", "b", "c" };
// IEnumerable<T>インターフェイスは型引数にout修飾子が指定されているため、共変である。
// したがって、C# 4.0では次の行はコンパイルエラーにならない
IEnumerable<object> y = x;

C# 5.0からの仕様

  • 非同期処理 (await, async)
  • Caller Info 属性
  • foreach の仕様変更

C# 6.0からの仕様

  • 自動実装プロパティの初期化子
  • get のみの自動実装プロパティおよびコンストラクタ代入
  • パラメータなしの struct コンストラクタ
  • 静的 using ステートメント
  • Dictionary 初期化子
  • catch/finally での await
  • 例外フィルタ
  • Expression-bodied メンバ
  • null条件演算子
  • 文字列補間(テンプレート文字列)
  • nameof 演算子
  • #pragma
  • コレクションの初期化子での拡張メソッド
  • オーバーロード解決の改善

静的 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引数で値を受け取る場合、その場所で変数宣言可能となった。

total += int.TryParse("123", out var num) ? num : 0;

パターンマッチング

is 式の拡張

is式の構文が拡張され、型の後ろに変数名を宣言できるようになった。 拡張された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ラベルの処理が実行される。 [5]

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;
    }
}

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)型が認められた。

static Task Main()
static Task<int> Main()

default式

型推論可能な場面では、defaultの型指定は省略可能となった。

int number = default;
string name = default;

実装

C#の言語仕様は標準化団体Ecma Internationalを通じて公開・標準化されており、第三者がマイクロソフトとは無関係にコンパイラや実行環境を実装することができる。 現段階で、C#コンパイラの実装は次の5つが知られている。

  • マイクロソフト製
    • Visual Studio 2015 以降で使用されている、.NET コンパイラ プラットフォーム(開発名Roslyn)。ApacheライセンスオープンソースプロジェクトでGitHubで公開されている[6]WindowsmacOSLinuxで動作する。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 4th edition によると、C# は「C Sharp」(シーシャープ)と発音し、「C#」 (LATIN CAPITAL LETTER C (U+0043) の後にNUMBER SIGN # (U+0023)) と書く [7]。 音楽のシャープ (♯, MUSIC SHARP SIGN (U+266F)) ではなくナンバーサイン (#) を採用したのは、フォントやブラウザなどの技術的な制約に加え、標準的キーボードには前者の記号が存在しないためである。
  • "#"接尾辞は、既存言語から派生した多くの.NET言語にも使用されている。これには、J#(Javaのマイクロソフトによる実装)、A#(Adaから)、F#(おそらくMLファミリに使われた型システムのSystem Fから[要出典])が含まれる。この接尾辞はGtk#GTK+などのGNOMEライブラリの.NETラッパ)、Cocoa#(Cocoaのラッパ)などのライブラリにも使用されている。
  • C#という名称の解釈として、「(A~Gで表された)直前の音を半音上げる」という音楽記号の役割に着目し、「C言語を改良したもの」を意味したのではないか、というものがある。これは、C++の名称が「C言語を1つ進めたもの」という意味でつけられたことにも似ている。
  • アンダース・ヘルスバーグは、「C#」が「C++++」(すなわち「C++をさらに進めたもの」)にみえるのが由来である、と語っている。[8][9]

脚注

  1. ^ Standard ECMA-334 C# Language Specification
  2. ^ ISO/IEC 23270:2003 C# Language Specification
  3. ^ JIS X 3015 プログラミング言語C#
  4. ^ null 許容型のボックス化 (C# プログラミング ガイド) MSDNライブラリ
  5. ^ https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/switch
  6. ^ dotnet/roslyn - GitHub
  7. ^ Standard ECMA-334 C# Language Specification
  8. ^ レポート:コミュニティスペシャルセッション with Anders Hejlsberg in Microsoft Developers Conference 2006
  9. ^ C#への期待。アンダースからの返答

関連項目

外部リンク






cと同じ種類の言葉


固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

cに関連した本

「c」に関係したコラム

  • FXやCFDの三角形移動平均とは

    FXやCFDの三角形移動平均とは、移動平均の移動平均のことです。つまり、移動平均値を算出して、さらにその数値の移動平均値を算出します。なお、移動平均には単純移動平均を用います。三角形移動平均は、三角移...

  • FXの三尊とは

    FX(外国為替証拠金取引)の三尊とは、釈迦三尊の並びのようにローソク足が並んでいる状態のことをいいます。ヘッドアンドショルダー(head and shoulder)ともいいます。三尊は、三尊天井と逆三...

  • FXでダウ理論を用いるには

    ダウ理論(Dow Theory)とは、ダウ・ジョーンズの創設者のチャールズ・ダウ(Charles Henry Dow)が提唱した相場理論のことです。ダウ理論には以下の6つの基本法則があります。ファンダ...

  • FXの口座明細の証拠金や維持率とは

    FX(外国為替証拠金取引)の口座明細には、証拠金や維持率のような専門用語が使われています。ここでは、それらの用語の意味や計算方法について解説します。建玉可能金額(たてぎょくかのうきんがく)新規に建玉(...

  • FXのダブルトップでのエントリーポイントを見つけるには

    ダブルトップとは、チャートが「W」の字を上下反転したように形成されていることです。ダブルトップが形成されると、2つのエントリーポイントが発生します。下の図は、ダブルトップを形成したチャートです。ダブル...

  • FXやCFDのシャンデモメンタムとは

    FXやCFDのシャンデモメンタムとは、相場の売られ過ぎや買われ過ぎを判断するためのテクニカル指標のことです。シャンデモメンタムは、0を中心に-100から100までの値で推移します。シャンデモメンタムで...

辞書ショートカット

カテゴリ一覧

全て

ビジネス

業界用語

コンピュータ

電車

自動車・バイク

工学

建築・不動産

学問

文化

生活

ヘルスケア

趣味

スポーツ

生物

食品

人名

方言

辞書・百科事典

すべての辞書の索引

「c」の関連用語

cのお隣キーワード

   

英語⇒日本語
日本語⇒英語
   
検索ランキング

画像から探す

libretto W100

パーシモン

Windows Me

ティー マーカー

IBM System z10

ラテラル・ウォーターハザード

iPhone 7 Plus

グラファイト シャフト





cのページの著作権
Weblio 辞書情報提供元は参加元一覧にて確認できます。

  
三省堂三省堂
Copyright (C) 2001-2017 Sanseido Co.,Ltd. All rights reserved.
株式会社 三省堂三省堂 Web Dictionary
社団法人日本映像ソフト協会社団法人日本映像ソフト協会
Copyright © 2000-2017 Japan Video Software Association
丸ヱム製作所丸ヱム製作所
© 1998-2017 Maruemu Works Co,. Ltd. All rights reserved.
独立行政法人科学技術振興機構独立行政法人科学技術振興機構
All Rights Reserved, Copyright © Japan Science and Technology Agency
JabionJabion
Copyright (C) 2017 NII,NIG,TUS. All Rights Reserved.
Bio WikiBio Wiki
Bio Wikiの記事を複製・再配布した「分子生物学用語集」の内容は、特に明示されていない限り、次のライセンスに従います:
CC Attribution-Noncommercial-Share Alike 3.0 Unported
トランスプラント・コミュニケーション [臓器移植の情報サイト]トランスプラント・コミュニケーション [臓器移植の情報サイト]
© 1996-2008 Transplant Communication All Rights Reserved (Unless otherwise noted.)
皓星社皓星社
Copyright (C) 2017 株式会社皓星社 All rights reserved.
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのC (改訂履歴)、C言語 (改訂履歴)、著作権表示 (改訂履歴)、C++ (改訂履歴)、C Sharp (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2017 Weblio RSS