2021.01.18 QA プログラム関連

asir glib3.rr で描いた図を C 言語と glib4.c で描くための注意点

glib_draw 函数に描画の手続きを書きますがこれが長い時には分割したいかも. C 言語では同じ名前の函数は一つしか定義できないので, 無論 glib_draw を複数書くことはできませんが, glib_draw の中から函数を呼ぶことで 分割して描画手続きを書くことができます. 本日のサンプルの lorentz.c も参照.
例:
void glib_draw() {
  glib_window(-1,-1,1,1);
  glib_clear();
  mypic1();
  mypic2();
  mypic3();
  glib_flush();
}
void mypic1() {
  /* glib_line や glib_putpixel による描画 */
}
void mypic2() {
  /* glib_line や glib_putpixel による描画 */
}
void mypic3() {
  /* glib_line や glib_putpixel による描画 */
}

次のエラーは何ですか? stray-err.c:4:1: error: stray ‘\343’ in program

stray と出たら全角文字がコメント文以外にあります. 全角空白などがプログラムに含まれていないか確認. この例では4行目付近に全角空白あり.

C言語版の方が早いわけは

C言語ではプログラムを cc によるコンパイルにより, 機械語に変換してから実行します. 一方 asir ではプログラムをインタプリタで解釈しながら逐次実行しますし, 変数にどのようなデータ型のものが入っているかはデータを検査するまで わかりません. たとえば A+1 の計算では C 言語では A のデータ型 (char, int や double) が確定 しているため, A+1 はほぼ最小の機械語に変換されて実行されます. たとえば A が int 型なら inc A という1クロックサイクルで実行される機械語に 変換されて実行されます. 一方 asir では, まず A に入っているデータの型を調べます. その後, A に整数がはいっている判明すれば, 整数の足し算のための asir の内部函数を呼び出します. int 型のように有限桁の数を mod 計算するわけでないので, この整数の足し算函数も複雑な内部構造を持ちます (詳しい説明(5/21を見よ)). というわけで A+1 の計算にもはるかに多くの実行時間がかかります.

Bezier 曲線の端点を for 文で変化させたい

bezier.c の glib_draw の変更例.
void glib_draw(){
  double p1[2]={-3,0};
  double p2[2]={1,1};
  double p3[2]={3,0};
  double e;
  glib_window(-4,-4,4,4);
  glib_clear();

  for (e=0; e<3; e = e+0.1) {
    p3[1]=e; /* p3 の y 座標を変化させる */
    draw_bezier2(p1,p2,p3); /* [-3,0] などはC言語では使えず */
  }
  glib_flush();
}

報告にあった便利な技

printf("Line%d\n",__LINE__);
と書いておくと実行中に何行目を実行してるかが print される. emacs では esc x でミニバッファの命令待ちにして, ミニバッファに goto-line 行番号 の入力, でプログラムの該当の行にジャンプできる.