C 言語手習い

作成日 : 2001-12-19
最終更新日 :

C 言語を勉強するページを公開する。

C MAGAZINE を読む

C MAGAZINE を読んだ記録を残す。2003 年 5 月号以降は講読を中止した。

1989年 10月 11月
1994年 3月 8月
1995年 1月
2000年 4月 5月 6月 7月 8月 9月 10月 11月 12月
2001年 1月 2月 3月 4月 5月 9月 10月 11月 12月
2002年 4月 7月 11月
2003年 3月

処理系

覚書

データ構造

C 言語がもともと持っているデータ構造は、配列ぐらいしかない。 他の言語にある、辞書とかハッシュとか連想配列とかという構造は言語仕様としては存在せず、 また標準ライブラリにもない。 LINUX (ほか、POSIX 準拠の処理系)では、 hcreate, hdestroy, hsearch というハッシュ表を扱う関数がある。 同じく LINUX では、tsearch, tfind, tdelete, twalk, tdestroy 2分木(binary tree) を扱う関数がある。

規格の推移

C11

C11 とは、ISO/IEC 9899:2011 の通称で、ISO で定められた C 言語の規格である。 その前の規格は C99 であった。C11 の後継は C18 である。

主な変更点は次の通りである。

制御が戻らない関数

制御が戻らない関数は下記のディレクティブを宣言する。

#include <stdnoreturn.h>

また、関数の戻り値の型に次のような修飾語 noreturn を付与する

noreturn void func()
{
	printf("noreturn func\n");
	abort();
}

のように関数に noreturn で修飾する。

制御が戻らない関数があるのだろうかと不思議に思うことがあるかもしれない。 ここでは、無条件で exit や abort 関数を呼び出して終了する関数が想定されているのだろう。 またこのような関数は、スケジューラのルーチンなどでありうる。 noreturn の修飾を付与することで、 関数が呼び出し元に戻るために必要ないくつかの処理を、 コンパイラで省略したり簡略化したりすることができる可能性がある。 コンパイラはそれらの省略・簡略化のヒントとして noreturn を使うことができる。 参考:「noreturn」関数が戻るのはなぜですか (code-examples.net)

型ジェネリック式

_Generic キーワードを利用して、関数インターフェースを統一的に処理できる。 ただし、C++ ほどの柔軟性はないので、使うとしても限定的であろう。 WEB で散見されるのは、三乗根を返す関数を定義するとき、同じ機能の関数でも 引数に float をとる関数、double をとる関数、long double をとる関数の3種類がすでに定義されていて、 かつそれらを同じ名前で処理したいとき、_Generic を使ってうまく処理することができる、というものだ。 下記の例を見る通り、それほど訳立つ場面はないと思われる。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define sin(X) _Generic((X), long double: sinl,       \
     default: sin,  \
     float: sinf)(X)

int main(void)
{
	float   f = 3.1416; // M_PI は std11 では定義されない。 
	double  d = 3.1416; 
	long double ld = 3.1416;
	
	printf("%f\n", sin(f));        // sinf
	printf("%f\n", sin(d));        // sin
	printf("%Lf\n", sin(ld));      // sinl
}	

C18

C18 (または C17)は、現在 (2020 年) での C 言語の標準である。 C18 は C11 に対して報告された多くの問題点に対応している。 また C18 は技術正誤表(Technical Corrigenda)が組み込まれている。 C18 で新たな言語機能は導入されていない。

まりんきょ学問所コンピュータの部屋 > C 言語手習い


MARUYAMA Satosi