(有)未来検索ブラジルが運営するあらゆる言葉についての記事を閲覧・編集したり、コメントをしたりするサイトです。

単語記事: C言語

編集

C言語とは、プログラミング言語の一つである。単にCとも呼ばれる。

概要

AT&T社のベル研究所でB言語の後継として、UNIX移植性を高めるために作られた。

Bの次はアルファベットでCなのでCと命名されたとも、B言語のとなったBCPLの2番目の文字を採って命名されたとも言われる。

UNIXを記述する目的で内輪向けに作られた言語であるため、全性はあまり考慮されていない。配列の添字チェックが無かったり、ポインタが無効でもアクセスしようとしたり、整数とポインタを自由にキャストできたり。やりたい放題。

C言語に関する規格

C言語プログラミング言語の中でも比較的歴史が長く、何度か規格が改定されてきた。

K&R

K&Rとは、カーニハンとリッチーの共著『The C Programming Language』(邦題:プログラミング言語C)のこと。転じて、標準化以前のC言語を指す。K&Rは解説書であり規格書ではないため曖昧な記述も多く、これをに作られたコンパイラ同士の非互換性を生むこととなった。

プログラミング言語を学ぶ人が一番最初に出会う事の多いプログラム、「Hello, World!」はこの本に由来する。

C89

ANSIが1989年に策定した規格。ANSI Cとも呼ばれる。これにより、初めてC言語の標準化が行われた。

C90

ISO1990年に策定した規格。内容はC89と同一。

C95

ISO1995年に策定した規格。C90に際化のためワイド文字列関連のライブラリが追補として追加された。

C99

ISO1999年に策定した規格。複素数や可変長配列など様々な機が追加された。

現在、一部を除いて一般的に用いられている規格。 

こんなところで使われているよ

主なコンパイラ

サンプルコード

Hello, World!

Cを学ぶ上で避けては通れないコード

#include <stdio.h>

int main(void) {
printf("Hello, World!");
return 0;
}

よくある勘違い

void main

C言語でのmain関数

と定義するか、

  • int main(int argc, char** argv) { /* ... */ }

のような同等の定義か、処理系依存の定義をしなければならない。(C99 5.1.2.2.1)

よって、

は、C言語の規格上定義されていない。

また、return せずに main 関数の最後まで到達した場合、main 関数は 0 を返したことになる。
int と互換性の無いの値を返した場合には不定となる。(C99 5.1.2.2.3)

よく気付かれるので、C言語の解説動画などでvoid main(void)にすると荒れる因となる。

絶対に使ってはいけない関数

諸ヘッダファイルに定義はされているもののその関数自体に重大なバグを抱えている関数C言語には存在する。C言語プログラミングを学ぶ人のために、簡単にまとめておく(適宜追加してください)。

char *gets(char *s)

この関数は、標準ヘッダファイルstdio.hに宣言されており、 標準入(stdin,普通キーボードが該当)から改行文字かEOFまでの一行を受け取り、引数となるcharポインタ変数が指すバッファに格納する(末尾の改行文字'\n'やEOFは'\0'に置き換えられる)。

問題点は、例えば以下のような状況でバッファオーバーランを起こし、変な動作をする点である。

例えば、最初に変数として「char s[200];」を宣言し、「gets(s);」でキーボードから文字を入することを考える。ここで、入改行記号を除いた199バイトより大きい場合、その余剰分のデータが分け与えられたメモリ領域とは別のところを書き込んでしまう。AAにするとこんな感じである(正確に言うと違うが、簡単に述べている)。

↓あるデータ     ↓s[200]      ↓あるデータ
…0010001000][000000…0000][100010010010…

↓199バイトより大きい文字列をgetsで取得


↓あるデータ     ↓s[200]      ↓あるデータ
…0010001000][101110…1011][011010110010…

この右側の下線をつけたところが変に書き込まれたされたところである。ここに、たまたまウィンドウで開いてたお宝画像のデータがあったとしたら…?そのデータは壊れて変な画像になったり、開けなくなってゴミと化すかもしれない。また、ここにOSの重要なプログラムが入っていたとしたら…?PCの動作が不定になるのは明らかである。

対策は、fgets(s,sizeof(s),stdin)を使うこと。これも指定された数以上に入があったらプログラムの動作がおかしくなる場合があるが、少なくとも大事なデータを書き換えることはない。

関連動画

  

関連商品

 

 

関連項目

携帯版URL:
http://dic.nicomoba.jp/k/a/c%E8%A8%80%E8%AA%9E
ページ番号: 451144 リビジョン番号: 992117
読み:シーゲンゴ
初版作成日: 08/08/11 01:51 ◆ 最終更新日: 10/11/30 18:11
編集内容についての説明/コメント: syntaxえらいこっちゃである(int argc, char** argv)
記事編集 / 編集履歴を閲覧 /

C言語について語るスレ

37ななしのよっしん :2009/10/17(土) 23:42:47 ID: F0hXTMleIQ
ウーチェウーチェ

スィーゲンゴー
38ななしのよっしん :2010/01/02(土) 21:59:07 ID: mxXHVHF0AI
C言語でのHello World(x86&linux&glibc)

char main[]="`j X$@P[PYPPPPX4.4 PZUX, P^XH,=)F(P_X3F()8)8@)8@@)8)8@PYX@@@@CQBaGHello, world!¥n";

なん……だと……?
39ななしのよっしん :2010/01/05(火) 07:24:55 ID: dP1OqL9IcT
>>38

それはマシン言語を文字列としてコーデイングするという仕組みです。バッファオーバーフロー攻撃を行うときに使うShellcodeみたいなものだと思います。
40ななしのよっしん :2010/02/03(水) 23:24:12 ID: VHSjV5l01h
BASICやってCやったら配列チェックがないこと知らなくて・・・
41ななしのよっしん :2010/06/09(水) 18:18:05 ID: LmVR0aAM6g
ポインタ辺りで一度詰まるのはデフォだよな
Cに限った話じゃないけど
42Naohiro19 :2010/08/28(土) 21:23:25 ID: 9CJQI7n8JQ
「よくある勘違い」の部分でgcc
gcc -ansi -pedantic -o hoge.exe hoge.c
とやってもANSI規格でビルドされるので「mainがintではない」
と警告されます。
43ななしのよっしん :2010/09/04(土) 09:46:02 ID: e9jLsqbg7E
voidを良くvoldと入してしまう癖があるのはボクだけ?
44ななしのよっしん :2010/11/24(水) 20:56:20 ID: g6ADMx3SPr
int main(int argc char** argv) { /* ... */ }

これ、argcの後に,はいらないんだっけ?
普通に考えると必須なんだけど
45ななしのよっしん :2010/11/24(水) 21:04:53 ID: ExBWf62IsA
>>44
実際にコンパイルしてみれば分かるじゃない
構文エラー起こすから
46ななしのよっしん :2010/12/19(日) 19:19:33 ID: 8jWeIhOp+n
void main(void)は組み込み系では見かけるね。むしろOS無い場合main関数の返値はどこに飛ぶのかと
ページトップへ戻る