日記・コラム・つぶやき

2013年5月23日 (木)

C言語のお勉強 ポインタ編 第3回

先生

ポインタ変数も変数だ

生徒

そうですね

先生

ポインタ変数にもとうぜん識別番号が振られている。識別番号は喩えだが

生徒

そういうことになりますね

先生

ポインタ変数の識別番号を格納する変数もまたポインタ変数だ

生徒

あれ?そこはポインタへのポインタとか言うんじゃないですか?

先生

違うぞ。ポインタ変数はポインタ変数だ

生徒

どういうことですか?

続きを読む "C言語のお勉強 ポインタ編 第3回"

| | コメント (2)

2013年5月21日 (火)

C言語のお勉強 ポインタ編 第2回

生徒

ポインタは関数呼び出しの実引数を書き換えるのに使うと習いました

先生

ああ、うん、そうだね

生徒

何ですか?その煮え切らない感じ

先生

どうしてポインタを使わないと実引数を書き換えられないのか説明できるかい?

生徒

話を逸らしましたね。ええと、仮引数は実引数のコピーなので仮引数を書き換えても実引数に影響しない…ですよね

先生

そうだ。そのように実引数のコピーが仮引数に代入される仕組みを値渡しと呼ぶ

生徒

そこがポインタだと違うわけですね

先生

違わない

生徒

へ?

先生

違わないのだよ。引数の型がポインタであっても値渡しだ

生徒

どういうことですか?

続きを読む "C言語のお勉強 ポインタ編 第2回"

| | コメント (0)

2013年5月20日 (月)

C言語のお勉強 ポインタ編 第1回

先生

変数は値を入れる箱だという喩えを聞いたことがあるかい?

生徒

ええ、よくある喩えですね

先生

その箱にアクセスするとき変数名を使うね。例えばこんな具合だ

int i;
i = 100;
printf("%d\n", i);
先生

実はその箱には必ず識別番号が振られている。識別番号は喩えだが

生徒

識別番号ですか?何のために?

先生

もちろん箱にアクセスするためだ

生徒

変数名を使えばいいじゃないですか

先生

名前の無い変数もあるのさ。名前の付いた変数は寿命が決まっているが名前の無い変数にはそのような縛りがない

生徒

何ですか?それ

先生

いまは知らなくていいよ。名前に縛られないメリットは他にもある。要するに便利なのさ

続きを読む "C言語のお勉強 ポインタ編 第1回"

| | コメント (0)

2012年6月30日 (土)

ポインタの理解を妨げるもの 第4回

1年ほど前に、「ポインタは変数」という誤解の刷り込みがポインタの理解を妨げる原因だということを書いたのだが、実のところ、いまいち本質を表していないなあと思いながら書いていた。

あれからずいぶん経つが、本質を理解できた気がするので投稿しておく。

続きを読む "ポインタの理解を妨げるもの 第4回"

| | コメント (0)

2012年4月22日 (日)

フレーム表示遅延が操作遅延の要因であるという謂れなき罪

Windows Vistaから搭載されたAeroにはデバイス画面の更新をキューイングする機能が採用されている。それがゲームの操作性を悪くする要因だとする説がまことしやかに囁かれ巷に蔓延しているようだ。

先日メインストリームサポートが終了し延長サポートに入ったWindows Vistaは発売から既に5年が経っている。とうの昔から解消手段が用意されているというのにいまだにしばしばテアリングを我慢することを強いられるのはこのような噂が原因なのだろうか。腹立たしいことこの上ない。

続きを読む "フレーム表示遅延が操作遅延の要因であるという謂れなき罪"

| | コメント (0)

2011年5月27日 (金)

ポインタの理解を妨げるもの 第3回

「ポインタ」をあいまいにすると値渡しという基本的なことも忘れてしまいがち。

#include <stdio.h>
void twice(int *n) {
	*n *= 2;
}
int main(void) {
	int i;
	int *p;
	i = 12;
	p = &i;
	twice(&i);
	twice(p);
	printf("%d\n", *p);
	return 0;
}

アドレス演算子を使って得たアドレスを引数にしてtwice関数に渡すのは直接的だから直感的に理解できるのではないだろうか(そうでもないか?)。

9行目と12行目の関係と同じだし。

ポインタ型の変数を引数にしたとき、変数に格納されている値が関数に渡るということを忘れてはいけない。

10行目と11行目でtwice関数の仮引数nが受け取る値は等しい。

関数twiceには値のコピーが渡るのだから、関数twiceを実行しているとき、変数nと(関数twiceからは見えないけど)変数pは同時に変数iを指していることになる。

| | コメント (0)

ポインタの理解を妨げるもの 第2回

既に世に出てる文章を変えるのは無理だから、慣れないうちは「ポインタ」の意味をきちんと判断して、「(ポインタ)型の変数」「(ポインタ)型の値」あるいは「(ポインタ)型」を脳内で補完しながら注意深く読んでいくしかない。

自分は、どのように慣れてない他人に説明するかを、考えてみる。

続きを読む "ポインタの理解を妨げるもの 第2回"

| | コメント (0)

2011年5月26日 (木)

ポインタの理解を妨げるもの 第1回

つい最近とある質問掲示板で回答したのをきっかけに改めて書いてみようと思う。

十年近く前に『C言語 ポインタ完全制覇』の著者のサイトで、『C言語 ポインタ完全制覇』の補足として書かれた、『K&Rにおけるポインタの定義(2001/1/29)』という文章を目にしたことで意識して考えるようになったこと。

「ポインタ」というのは、文脈によって『変数』『値』『型』のいずれかを意味するあいまいな単語なんだけど、いろんなところに「『変数』だけを意味するんだ」という誤解を刷り込む罠がある、ということ。

自分はアセンブラを経験していたにもかかわらず間接参照演算子を使う際、型の不一致にさんざん悩んだ経験があるのだけど、いまだに罠にハマってしまうひとが少なからずいるんだろうなと思った。

| | コメント (0)

2011年2月 7日 (月)

ビデオゲームプログラムのワークフロー

特別なことではないが、わたしはずいぶん前からメインループを切り離し、サブルーチンをコールバックする構造でプログラムを作っている。

内部状態を1フレーム分進行させるUPDATEルーチンと呼び出された時点の内部状態で画面描画するRENDERルーチンが基本的に1フレームに1回ずつ呼び出されて動く構造だ。

ふと、いつからこんなふうに作っていたのかと思い返してみたら、20年ほど昔、ハードウェアで実装されたスプライト機能を搭載したパソコンで必要に迫られたものだったと思い出した。

数少ないスプライトに動的にキャラクタを割り付けたり、テアリングを避けるために垂直同期の帰線期間内に設定しなければならなかったから描画処理をまとめる必要があった。

その後、世の中はPC/AT互換機一色に。フレームバッファ方式になってさほど描画処理をまとめることに神経質になる必要が無くなった。ところがポリゴンの登場で再び描画処理をまとめる必要が出てきた。

パソコン以外では、マルチスレッドが使えない協調型マルチタスク環境とか、描画イベントのコールバック以外で描画用のコンテキストを取得できない環境とか、制限の厳しいプラットフォームが現役だが、この構造はあらゆるプラットフォームに容易に対応できる。

ビデオゲームプログラミングを始めて間もないひとの中には、1フレームごとに呼び出し元に戻るプログラミングを受け入れ難いというひとが大勢いるようだが、複数のキャラクターを並行して動かすときには、同様の入れ子の構造のコードを書くことになる。

けっきょく入れ子のレベルがひとつ増えるだけの違いなのだから、メイン『ループ』などという先入観を植え付けられる前にコールバックを受け入れてしまえば良いと思うのだ。

| | コメント (5)

2010年11月29日 (月)

十二年前のプログラム

十二年前に作った、デスクトップが16ビットモードじゃないと動かないプログラムを、SDLを使って画面モードに依存しないように書き直してみた。

ひどいコードだ。

C++のクラスの使い方などいろいろと勘違いしている。演算子のオーバーロードも知らなかったようだ。

異なるソースファイルで相互に外部参照している変数があるなど滅茶苦茶だ。

固定小数点数を使った拡大縮小・回転処理や半透明合成処理は当時必死に考えて実装したものだが、いま見ると無駄が多いことや正確でないことがはっきり分かる。

あちこち弄りたくなる衝動を抑えてとりあえず最低限の描画周りだけに手を入れる。

PCの性能が上がって動作速度も段違い。高速化のために描画を省略する処理を組み込んであったけど省略なしで十分に余裕がある。

このプログラムはゲーム業界と繋がるきっかけのひとつ。

良くも悪くもいろんな思い出が詰まっている。

【2010/11/30 追記】

共通のモジュールを使ったプログラムがいくつかあるのだがひととおり動くようになった。

致命的なバグがいくつも見付かった。当時はこれで動いていたのだから驚きだ。

| | コメント (0)

より以前の記事一覧