C言語:extern

全ファイル中のどこかに定義してある、という意味です。複数ファイル構成で分割コンパイルする場合に必要で、一般的には共通ヘッダファイルに記述します。

ファイルが一つだけのプログラムでは、あまり使い道がありません。しかし厳密には、ファイルが一つでもライブラリ内の関数や変数を参照する場合にextern宣言が必要です。ライブラリはコンパイル済みCファイルの集合体だからです。
1. 関数のプロトタイプ宣言

関数のプロトタイプ宣言にexternを付ける付けないは、あまり問題になりません。

----------- a.c -----------
       int func_A( int n );    /* OK */
extern int func_A( int n );    /* OK */

int func_A( int n )
{
}

----------- b.c -----------
       int func_A( int n );    /* OK */
extern int func_A( int n );    /* OK */

int func_C( int n )
{
    /* a.c の func_A を呼んでいる */
    func_A( n );
}

externは「全ファイル中のどれかに定義されている」ですから、 extern int func_A(int n); は、a.c でも、b.c でも同じように宣言できます。

staticではない関数は、ファイル外部から見えると解釈されるので、関数のexternは省略できます。

2. 変数

2.1 正しい使い方

まずは正しい使い方です。a.c 内で定義された int a; を b.c 内で使っています。

----------- a.c -----------
int    a;

func_A()
{
    a = 1;
}
----------- b.c -----------
extern int    a;

func_B()
{
    a = 2;
}

2.2 コンパイルエラー

この例では、a = 2; の a は、b.c内では定義されていないよ!とコンパイルエラーになります。

----------- b.c -----------
/* extern int    a; */

func_B()
{
    a = 2;
}

2.3 リンクエラー(1)

----------- b.c -----------
/*extern*/ int    a;

func_B()
{
    a = 2;
}

コンパイルはOKです。しかしリンクで、変数 a が、a.cとb.cの2箇所で定義されています?とリンクエラーになります。一つのプログラム内では、同じ名前のグローバル変数は複数使えません。(グローバル変数とは、関数の外で定義した変数)

似たような例を紹介しますが、一つの関数内では、同じ名前のローカル変数を複数使えません。(ローカル変数とは、関数の中で定義した変数)

func_A()
{
    int    x;
    int    x;    /* エラー */
}

2.4 リンクエラー(2)

----------- a.c -----------
/* int a; を定義しない */

----------- b.c -----------
extern int    a;    /* どこかにあるはず */

func_B()
{
    a = 2;
}

b.c のコンパイルはOKです。b.cの変数aの扱いは「別ファイルにあるはず」と、変数aに関する問題を先送りにします。しかしリンクのとき、全ファイルを見渡しても変数a はどこにもない、とリンクエラーになります。

(2000年頃の記事)

MS-DOS:ESCシーケンス

WindowsのMSDOS窓では、一部はサポートされていません。この資料は(おそらく)NECのPC9801用MS-DOSリファレンスからの引用です。

エスケープシーケンス 機能
ESC [pl;pcH Direct cursor
addressing
カーソルを指定位置に移動します。
pl=mのときはm行目でmが最終行の値より大きい場合は最終行に位置付けます。
pl=0あるいはplが省略された場合は1行目に位置付けます。
pc=nのときはnカラム目でnが最終カラムより大きい場合は最終カラムに位置付け、pc=0あるいはpcが省略された場合は1カラム目に位置付けます。
ESC [pl;pcf ESC[pl;pcHと同様の処理を行います。
ESC =lc ESC[pl;pcHと同様の処理を行います。
この場合パラメータ lc
は2進数で20Hのオフセットが加えられた値です。
l
は行位置の指定であり1行目に位置付けるには20Hとなります。
c はカラム位置の指定であり1カラム目に位置付けるには20Hとなります。
l
c のパラメータは省略できません。
ESC [pnA Cursor up
カーソルをおなじカラム位置で上にn行(pn=n)移動します。カーソルが先頭行にある場合、あるいは先頭行を越えた場合には先頭行に位置します。pnが省略されるかpn=0の場合はpn=1として処理します。
ESC [pnB Cursor down
カーソルをおなじカラム位置で下にn行(pn=n)移動します。カーソルが最終行にある場合、あるいは最終行を越えた場合には最終行に位置します。pnが省略されるかpn=0の場合はpn=1として処理します。
ESC [pnC Cursor
foreward
カーソルを右にn文字(pn=n)移動します。カーソルが行の右端にある場合、あるいは右端を越えた場合には右端に位置します。pnが省略されるかpn=0の場合はpn=1として処理します。
ESC [pnD Cursor
backward
カーソルを左にn文字(pn=n)移動します。カーソルが行の左端にある場合、あるいは左端を越えた場合には左端に位置します。pnが省略されるかpn=0の場合はpn= 1として処理します。
ESC [0J Clear from cursor to end of screen
カーソル位置から最終行の右端までクリアします。カーソル位置はそのままです。パラメータ0は省略できます。
ESC [1J Clear from beginning of screen to cursor
先頭行の左端から、カーソル位置までをクリアします。カーソル位置はそのままです。
ESC [2J Clear screen
CRT画面をすべてクリアします。カーソル位置はホーム位置となります。
ESC * ESC[2Jと同様の処理を行います。
ESC [0K Clear from cursor to end of line
カーソル位置から、行の右端までをクリアします。カーソル位置はそのままです。パラメータ0は省略できます。
ESC [1K Clear from beginning of line to cursor
行の左端から、カーソル位置までをクリアします。カーソル位置はそのままです。
ESC [2K Clear entire line containing cursor
カーソルが位置している行の左端から右端までをクリアします。カーソル位置はそのままです。
ESC [pnM Delete line
カーソルの位置する行から下にn行(pn=n)削除し、以降の行を上に詰めます。カーソルの位置は詰められた行の左端になります。最終行を越えての削除は行われません。pnが省略されるかpn=0の場合はpn=1として処理します。
ESC [pnL Insert line
カーソルの位置する行以降をn行(pn=n)下に移動し、空白のn行を挿入します。カーソルは先頭の挿入行の左端に位置します。挿入行が最終行を越えた場合、移動する行が最終行を越えた場合は、その越えた行は失なわれますpnが省略されるかpn=0の場合はpn=1として処理します。
ESC D Index
カーソルと同じカラム位置で1行下に移動します。カーソルが最終行にある場合は1行スクロールアップします。
ESC E Next line
カーソルを1行下の行の左端に移動します。カーソルが最終行にある場合は1行スクロールアップします。
ESC M Reverse index
カーソルを同じカラム位置で1行上に移動します。カーソルが先頭行にある場合は1行スクロールダウンします。
ESC [s Save cursor position
カーソル位置(行、カラム)とその表示文字の属性をセーブします。
ESC [u Set cursor position
ESC[sでセーブした内容を戻します。以前にESC[sが実行されていない場合は、カーソルはホーム位置に移動し、属性は規定値となります。
ESC [6n Cursor position report
カーソル位置を直後のコンソール入力呼出しにて知らせます。その形式はESC[pl;pcRです。
ESC )0 Select kanji mode
ESC )3 Select graph mode
ESC[>5l Enable cursor display
ESC[>5h Disable cursor display
ESC[>1h Enable bottom line
ESC[>1l Disable botttom line
ESC[>3h Select 20 line
ESC[>3l Select 25 line mode
ESC [ps;...;psm Character attribute

ps
0 規定の属性
1 ハイライト(モノクロのみ)
2 バーティカルライン
4 アンダーライン
5 ブリンク
7 リバース
16 8 シークレット30 黒 淡(暗)
18 34 青
17 31 赤
19 35 紫
20 32 緑
22 36 水色
21 33 黄色
23 37 白 濃(明)
40 リバース黒
41 リバース赤
42 リバース緑
43 リバース黄色
44 リバース青
45 リバース紫
46 リバース水色
47 リバース白

(2000年頃の記事)

MS-DOS:ASCII制御コード

WindowsのMSDOS窓では、一部はサポートされていません。この資料は(おそらく)NECのPC9801用MS-DOSリファレンスからの引用です。

記号 16進数 機能
BEL 07 Sound bell
ブザーを約1秒鳴らします。
BS 08 Cursor backward
カーソルを1文字左に移動します。カーソルが行の左端にある場合は1行上の右端に移動し、カーソルがホーム位置にある場合は何もしません。
HT 09 Skip to next tab stop.
カーソルを次のタブ位置に移動します。
タブ位置は次のように決められています。
08, 16, 24, 32, 40, 48, 56, 64, 72
カーソルが72カラム目より右側にある場合は1行下の左端に移動し、最終行の場合は1行スクロールアップします。
LF 0A Cursor down
カーソルをおなじカラム位置で1行下に移動します。カーソルが最終行にある場合は何もしません。
VT 0B Cursor up
カーソルをおなじカラム位置で1行上に移動します。カーソルが先頭行にある場合は何もしません。
FF 0C Cursor foreward
カーソルを1文字右に移動します。
カーソルが行の右端にある場合は1行下の左端に移動し、カーソルが最終行の右端にある場合は1行スクロールアップして左端に移動します。
CR 0D Cursor to left margin
カーソルを行の左端に移動します。
SUB 1A Clear screen. (and Cursor HOME)
CRT画面をすべてクリアします。カーソルはホーム位置となります。
ESC 1B Introduce on ESC sequence
エスケープコードです。
RS 1E Cursor HOME
カーソルをホーム位置に移動します。

(2000年頃の記事)