2008/8/13 - 2011/8/14
Pen Jr.D言語なんてやってみそWelcome Beginner文法
文法( Lexical
プログラム言語 の場合、文法 というのはあまり適切ではないかも知れません。

相手は CPU などで、機械語 が ネイティブ言語 なわけですから「数式の文法」ということで、

ネイティブ な言語ほど厳格になり、自然言語の 文法 ということから イメージ する寛容なところは、ほぼ 皆無 になります。

もちろん D言語 は厳格ですが、変に拡張された言語にはよくある 理不尽な特別ルール がありませんから、いくつかの基本ルールにさえ従えば、思惑と違う 未知の解釈 をされることもなく、必要なことをその都度学習することにが出来ます。

トークン( Tokens
ソースコードの中で、意味を持つ 最低単位トークン( 字句 ) と言います。

トークン の 分類は

  • 記号 や 記号 の組み合わせ
  • 識別子
  • 命令 などの キーワード
  • リテラル
字句解析( トークン解析 )が基本になるのは「自然言語」でも同じですが全角文字は NG ですし、曖昧なところはなく厳格です。
構文( Statements )
基本的な ソースファイル には、様々な 定義・宣言ブロック があり、プログラムは 任意 の ブロック を呼び出しながら処理を実行します。
ブロック( Block Statement
{ から } までが1つの ブロック です。

ブロック内の 各文 は ソースコード の 記述順( 上から下 )に実行されます。

行終端( End of Line
; が行終端です。

トークン の区切りには自由に 改行 を使えますから、ソースコード の見た目とは別に

コンパイラ から見た 行終端 を明示する必要があります。

宣言文( Declarations
式文( Expression Statement
制御文( Statement
フリーフォーマット
"半角空白、タブ、改行(CR&LF)" は全て 空白 で、連続する場合は1つ 空白 として扱われまから、区切りには自由に 改行 や タブ を挿入出来ます。

例えば

import std.stdio;

void
 main
 (
  char
  [
  ]
  [
  ]
   args
    )
{
  writeln
    (
    "Welcome Beginner"
    );
}

これでも、

D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Beginner

結果は同じです。

インデント や 空行 をうまく使って、見やすい ソースコード にすることが出来ます。

また、ブロック と 行終端 の記述さえちゃんとすれば、

import std.stdio;void main(char[][]args){writeln("Welcome Beginner");}

こんなコードでも、

D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Beginner

コンパイラ にすれば問題なしです。

D言語 は、記述さえ正しければ、ほとんど 改行 または 空白 の区切りは必須ではなく、また 空白 の入れ方で意味が変わったりすることがないようよく考えられています。
コメント( Comments
行コメント // から行の終わり(改行)まで
ブロックコメント(ネスト不可) /* から */ まで
ブロックコメント(ネスト可) /+ から +/ まで
通常 コメント 内は、その コメント の 終了文字(列)以外は 解釈(トークン分け)されませんから、自由な記述が出来ます。
  /*****************************
  %
  $       2011-03-05
  @           by
  !         Pen Jr.
  #
  */
  //  インポート Phobos
import std.stdio; // writeln のため

  /*----------------------------
  |
  |     エントリーポイント
  |
  */
void main( /* 引数省略  */ )
{
  //
  //   標準出力
  writeln( "Welcome Beginner" );
}
コメント は過剰なくらい書き込む癖を付けた方が後々のためになります。

記憶力が抜群なころ、立派な コメント にそぐわないアホなコードをバカにして コメント をおろそかにしたせいで、記憶力が アホ になり、数日前に書いた自分の コード の解読に苦労する 懲りない アホ になってしまってからでは手遅れだったりしますから・・・

全角文字に要注意!!!
日本語変換を使いながらプログラムコードを書いていると、

一見問題なさそうなコードですが、

import std.stdio;

void main()
{
  writeln( "Welcome Beginner" );
}

コンパイルすると、

D:\Pen-Jr\My Programs\Welcome>dmd test
test.d(4): unsupported char 0xff1b
test.d(5): found '}' when expecting ';' following statement
test.d(5): found 'EOF' when expecting '}' following compound statement

めちゃ叱られます。

原因は 全角記号 が混入しているからで、

混入してるやつは

writeln( "Welcome Beginner" );
writeln( "Welcome Beginner" );

下が正しいコードです。

並べて見ればわかりますが、日本語変換では時折見た目では区別がつかない間違った変換をすることもありますから、文字列やコメント以外の記述時は日本語変換を忘れず OFF にしまひょ!
識別子( Identifier
任意に定義できる トークン でシンボルも 識別子 です。
識別子はアルファベットか _、または普遍基本文字(Universal Alpha)で始まり、 アルファベット,_,数字,普遍基本文字の列が後ろに続いたものです。 普遍基本文字は ISO/IEC 9899:1999(E) Appendix D. (C99標準です) に定義されています。識別子は大文字小文字を区別します。 長さに制限はありません。 __ (2個のアンダースコア)で始まる識別子は処理系側に予約されています。

普遍基本文字とかは一般的ではありませんから無視して、

  • 英数字
  • 記号 は アンダーバー( '_') だけ使える
  • 先頭に数字は NG( リテラル
  • アルファベット は 大文字 と 小文字 が区別される
要するに単語( Word )のことですが「厳格な仕様」があり、違反が容認されることはありません。
予約語( Keywords
組み込み 定義 された 型 や 命令 など言語で予約された 識別子 で、任意の意味付けは出来ません。
サンプルコードでは

importvoidchar

が 予約語 です。

宣言文( Declaration Statement
予約語 以外の 識別子 には 宣言 で任意の意味を 定義 出来ます。
import std.stdio;  // 外部宣言の読み込み

void main() // 関数 main の宣言文
{
  int i;    // 変数 i の宣言文
}
リテラル
リテラル とは ソースコード に 文字列 や 整数値 などを 直接表記 したもので
  • 文字列
  • 文字
  • 整数
  • 浮動小数点数
  • 配列
  • 連想配列
  • 構造体
  • 関数

などの 型 を 表記 できます。

文字列リテラル( String Literals
二重引用符 "" で囲まれた 文字列 で、エスケープシーケンス が解析されます。

また、文字列 はコメント同様 トークン分け されません。

エスケープシーケンス( Escape Sequence
¥n 改行
¥r 先頭に戻る
¥t タブ
¥¥ ¥
¥" 二重引用符
¥‘ 一重引用符
¥0 ヌル
¥? ?

など他にもありますが、

¥ から始まる 文字 で、文字列リテラル ではそのまま使えない "制御コード などを記述するために使います。

import std.stdio;

void main()
{
  // 文字列内の改行は改行、空白は空白
  writeln(
    "Welcome
    Beginner"
    );
  // エスケープシーケンス
  writeln( "Welcome\nBeginner" );
  writeln( "\"Welcome Beginner\"" );
  writeln( "\\Welcome\\Beginner\\" );
  writeln( "\'Welcome\'\n\'Beginner\'" );
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome
    Beginner
Welcome
Beginner
"Welcome Beginner"
\Welcome\Beginner\
'Welcome'
'Beginner'
文字リテラル( Character Literals
1文字か エスケープシーケンス を '' で囲みます。
import std.stdio;

void main()
{
  writeln( "Welcome\nBeginner" );
  writeln(
    // 文字を順次出力
    'W', 'e', 'l', 'c', 'o', 'm', 'e',
    // エスケープシーケンスも
    '\n',
    'B', 'e', 'g', 'i', 'n', 'n', 'e', 'r'
    );
}
D:\Pen-Jr\My Programs\Welcome>test
Welcome
Beginner
Welcome
Beginner
整数リテラル( Integer Literals
整数値 はそのまま普通に記述出来ますが、一般的な ',' などの記号は使えません。

桁など見やすくしたい時には '_'(アンダーバー)を任意に挿入できます。

import std.stdio;

void main()
{
  // 基本 0-9 のみ
  writeln( 1234567890 );
  // _ は使える
  writeln( 1_234_567_890 );
  // 符号は普通に
  writeln( -1234567890 );
}
D:\Pen-Jr\My Programs\Welcome>test
1234567890
1234567890
-1234567890
浮動小数点数リテラル( Floating Literals
浮動小数点数 は 整数 と別扱いですが、整数値 同様普通に記述出来ます。
import std.stdio;

void main()
{
  //  . と 0-9
  writeln( 0.0001 );
  // _ は使える
  writeln( 0.000_1 );
  // e や E も
  writeln( 0.0001e+4 );
  writeln( 1E-4 );
}
D:\Pen-Jr\My Programs\Welcome>test
0.0001
0.0001
1
0.0001
モジュール( Modules
基本的には 「1つのソースファイル = モジュール」ということで、

std.stdio やサンプルコードなどの ファイル もモジュールです。

モジュール名
モジュール名 は ファイル名 ということになりますが、 Windows では ファイル名 の大文字と小文字の区別はしませんから、慣習に従って全て小文字で書きます。

また、予約語 をファイル名にしてもコンパイルは通り、実行も出来ますが、import 出来ない モジュール になってしまいますから、要注意です。

パッケージ名
std.stdio の場合 std が パッケージ名 で、stdio が モジュール名 です。

パッケージ名 は OS の ディレクトリー に対応していますから

¥std¥stdio
ということにもなります(同じ意味ではない)。
import宣言( Import Declaration
必要な モジュール を読み込むには、
import モジュールリスト;
モジュールリスト には読み込む モジュール を ',' 区切りで列挙します。
C、C++ の #include と違い、ソースコードをその場所に読み込むのではなく、必要な情報(宣言・定義)だけを読み込みますから、各モジュール に対して import は一度、出来るだけ モジュール の先頭付近に記述します。
関数( Functions
初めはちょっと難しいかも知れませんが、D言語 では初歩的なコード でも 関数 を使います。
  • 任意の 値 を受け取り 値 を返す処理に名前( 識別子 )を付けて、その名前で任意に呼び出せるもの
  • C、C++ や D言語 の場合、処理コードは全て 関数 で実行される
  • プログラムで最初に実行される 関数 を エントリーポイント と言い、D言語(コンソールアプリ)の エントリーポイント は C、C++ と同じ main 関数
宣言
基本的には 宣言 で 処理コード も記述します。
属性 返値型 関数名( 引数, ... )
{
  return 返値;
}
  • 属性 は 任意
  • 返値 がない時の 返値型 は void
  • 引数 がない時の void などは不要
import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^   返値なし、引数なしの関数
  ^
  */
void welcome()
{
  writeln( "Welcome Beginner" );
}

  // エントリーポイント
void main()
{
  welcome();    // 関数の呼び出し
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Beginner
C、C++ などでは プロトタイプ宣言 といって、返値と引数だけの 関数宣言 が別に必要ですが、D言語 では 不要 です。
引数(パラメタ)
呼び出し時に受け取る 値の型、数、並び を宣言します。
( 記憶クラス  引数名, ... )
記憶クラス 、引数名は省略可
import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^   文字列を受け取る関数
  ^
  */
void welcome( string s )
{
  writeln( "Welcome ", s );
}

  // エントリーポイント
void main()
{
  welcome( "Beginner" );
  welcome( "Everybody" );
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Beginner
Welcome Everybody

D:\Pen-Jr\My Programs\Welcome>
引数 の 型、数、並び の全てが宣言通りでないと、関数 の呼び出しは失敗します。
import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^   文字列と数値を受け取る関数
  ^
  */
void welcome( string, int )
{
  // 中身が空なのは問題ない
  // 使わない引数名は省略できる
}

  // エントリーポイント
void main()
{
  // 以下は全部コンパイルエラー
  welcome();
  welcome( "Pen Jr" );
  welcome( 1 );
  welcome( 0, "Everybody" );
}
コンパイルエラー
デフォルト引数
引数 に デフォルト値 を設定することも出来ます。
( 記憶クラス  引数名 = デフォルト値 )

デフォルト値 の設定された 引数 は省略して 関数 を呼び出すことが出来ます。

import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^   文字列を受け取る関数
  ^
  */
void welcome( string s = "Beginner" )
{
  writeln( "Welcome ", s );
}

  // エントリーポイント
void main()
{
  welcome( "Pen Jr" );
  // 引数を省略して呼び出す
  welcome();
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Pen Jr
Welcome Beginner

省略された 引数 の値は デフォルト値 になります。

デフォルト値 の設定された 引数 の後に デフォルト値 のない 引数 は宣言できません。

import std.stdio;

void welcome( string s = "Everybody", int n ){
  // 処理がなくても叱られないよ
}

void main(){
}

コンパイルすると

D:\Pen-Jr\My Programs\Welcome>dmd test
test.d(3): default argument expected for n

D:\Pen-Jr\My Programs\Welcome>

デフォルト値のない n が叱られます。

デフォルト値 の設定を続けるのは無問題。

import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^   文字列と数値を受け取る関数
  ^
  */
void welcome( string s = "Everybody", int n = 1 )
{
  writeln( "Welcome ", s );
  writeln( "Get Number", n );
}

  // エントリーポイント
void main()
{
  welcome( "Pen-Jr", 100 );
  welcome( "Pen-Jr" );  // OK
  // 後ろの引数から順に省略しないとだめよ
  /+
  welcome( 100 );   // これはエラー
  +/
  welcome();        // 引数なしでも呼べるだに
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Pen-Jr
Get Number100
Welcome Pen-Jr
Get Number1
Welcome Everybody
Get Number1
返値
返値は return 文で返します。
Return 文( Return Statement
return 返値;
返値 を決めてその 関数 を終了します。

返値 がない(void)関数 の場合は return または 返値 を省略出来ますが、返値 の宣言がある 関数 を正常に終了するためには return返値 が必要です。

返値 のある 関数 は 式 の中で呼び出すことが出来ます。

import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^     文字列を返す関数
  */
string welcome()
{
  return "Welcome Beginner";
}

  // エントリーポイント
void main()
{
  writeln( welcome() );
  writeln( welcome );     // 引数がない場合 () も省略出来るぜ
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
Welcome Beginner
Welcome Beginner
import std.stdio;

  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ^   引数 n1 * n2 を返す関数
  */
int getMul( int n1 = 10, int n2 = 100 )
{
  return n1 * n2;
}

  // エントリーポイント
void main()
{
  writeln( getMul( 123, 10 ) );
  writeln( getMul( 456 ) );
  writeln( getMul( 789, getMul ) );
}
D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
1230
45600
789000
main 関数(エントリーポイント)
エントリーポイント というのは、プログラムが実行されるとき最初に呼び出されるポイント(関数)のことを言います。

コンピューターの電源が入れられると CPU はある決まった番地(アドレス : 0番地とは限らない)から処理を始めます。その処理は普通そのシステム(基盤・マザーボード)に実装済みで、そこから呼び出される OS にも エントリーポイント があり、その OS から呼び出されるプログラムには全て エントリーポイント があります。

ただし、OS のアプリケーションなどはプログラム実行時に直接ユーザーが書いた エントリーポイント から処理が始まるわけではなく、必要な手続きを済ませてから呼び出され、必要な後処理をして終了しますが、その内容は知らなくて問題ありません。

式( Expressions
比較式
値 の 比較 をして、結果は truefalse のいずれかの 値( ブール値 )になります。
演算子
== 等しい
!= 等しくない
< 小さい
> 大きい
<= 以下
>= 以上
等値式 の ==!= 以外は一般的ですが、
以上 と 以下 を =>=< と書くのは エラー です。
import std.stdio;

void main()
{
  writeln(
    // 等価
    "0 == 0 -> ", 0 == 0,
    "\n0 == 1 -> ", 0 == 1,
    "\n0 != 0 -> ", 0 != 0,
    "\n0 != 1 -> ", 0 != 1,
    "\n\n0 < 1 -> ", 0 < 1,
    "\n0 > 1 -> ", 0 > 1
  );
}
D:\Pen-Jr\My Programs\Welcome>test
0 == 0 -> true
0 == 1 -> false
0 != 0 -> false
0 != 1 -> true

0 < 1 -> true
0 > 1 -> false
算術演算式
ほぼ一般的な算術式と同じ意味で、同様の記述が出来ます。
演算子
+ 加算
- 減算
* 乗算
/ 除算
% 余り
%( 余り )以外はテンキー通り。
import std.stdio;

void main()
{
  writeln(
    // 加算
    "1 + 1 = ", 1 + 1,
    // 減算
    "\n1 - 1 = ", 1 - 1,
    // 乗算
    "\n2 * 3 = ", 2 * 3,
    // 除算
    "\n10 / 3 = ", 10 / 3,
    // 余り
    "\n10 % 3 = ", 10 % 3,
    // () も一般的な演算同様に使える
    "\n\n2 + 3 * 4 = ", 2 + 3 * 4,
    "\n( 2 + 3 ) * 4 = ", ( 2 + 3 ) * 4
  );
}
D:\Pen-Jr\My Programs\Welcome>test
1 + 1 = 2
1 - 1 = 0
2 * 3 = 6
10 / 3 = 3
10 % 3 = 1

2 + 3 * 4 = 14
( 2 + 3 ) * 4 = 20
代入式
慣れてしまえば当たり前のことになりますが、
代入先 = ;
代入先 = リテラル;
一般的な 式 は 結果 を右側に書きますが、ほとんどの プログラム言語 の 代入式 は
結果 を 左側 に 代入 します。

代入式 には = を使います。

import std.stdio;

void main()
{
  // 初期化値を代入
  int i = 10;
  string s = "ABC";
  
  // 値を代入
  i = 3;
  s = "Welcome Beginner\n";
  
  // 計算結果を代入
  i = i + 2 * 3;
  
  writeln(
    // 代入も式( 代入後の結果 )
    s, i = i * 2
  );
}
D:\Pen-Jr\My Programs\Welcome>test
Welcome Beginner
18
= は 代入。

等値(比較)式 は == です。

単項演算式
ほとんどが プログラム言語独特 の 演算式 で、最初は意味不明でしょうが、わかりやすい 演算式 から憶えて行けば問題ないでしょう。
演算子前置後置
++ インクリメント
-- デクリメント
+ 符号
- 同上
& アドレス
* ポインタ参照 ポインタ
~ 反転
! 否定
. スコープ
前置 と 後置 で全く意味が違ったりもします。
インクリメント・デクリメント
よく出てきますし、慣れれば便利に使えるでしょう。
import std.stdio;

void main()
{
  int i;
  writeln(
    "i = ", i,
    // 前置
    "\n\n++i = ", ++i, ", i = ", i,
    "\n--i = ", --i, ", i = ", i,
    // 後置
    "\n\ni++ = ", i++, ", i = ", i,
    "\ni-- = ", i--, ", i = ", i
  );
}
D:\Pen-Jr\My Programs\Welcome>test
i = 0

++i = 1, i = 1
--i = 0, i = 0

i++ = 0, i = 1
i-- = 1, i = 0

前置 と 後置 で違いますから、

式の中で使う時には要注意です。

import std.stdio;

void main()
{
  int i;
  writeln(
    "i = ", i,
    // 前置
    "\n123 * ++i = ", 123 * ++ i,
    "\n123 * --i = ", 123 * --i,
    "\n123 * i = ", 123 * i,
    // 後置
    "\n\ni = ", i,
    "\n123 * i++ = ", 123 * i++,
    "\n123 * i-- = ", 123 * i--,
    "\n123 * i = ", 123 * i
  );
}
D:\Pen-Jr\My Programs\Welcome>test
i = 0
123 * ++i = 123
123 * --i = 0
123 * i = 0

i = 0
123 * i++ = 0
123 * i-- = 123
123 * i = 0
式の中での 前置 は インクリメント または デクリメント 後 の 値 になり、後置は インクリメント または デクリメント 前 の 値 になります。

また、こんぴゅーたー は 0 から数えますから、なおさら混乱すると思います。

慣れるまでは、出来るだけ分けて記述した方がよいでしょう。

否定
import std.stdio;

void main()
{
  writeln(
    "!true = ", !true,
    "\n!false = ", !false,
    "\n!( 0 == 0 ) = ", !( 0 == 0 )
    "\n!( 0 == 0 ) = ", !( 0 == 0 ),
    "\n\n!0 = ", !0,
    "\n!123 = ", !123
  );
}
D:\Pen-Jr\My Programs\Welcome>test
!true = false
!false = true
!( 0 == 0 ) = false

!0 = true
!123 = false
. ( Dot )
数値の後にある場合は小数点になりますが、それ以外の 後置式 はほとんどの場合、
に置き換えた意味になります。

例えば、std.stdio は「std stdio」。

よく出てきますし、統一されていて C++ のように -> だったり :: とかだったりしませんから、自然に憶えることが出来るでしょう。

Effect( 効果・影響・結果 )
「Effect のない 式」 は コンパイルエラー です。

Effect のない 式 というのは

import std.stdio;

void main()
{
  int i, j;
  
  i = i + j;  // OK
  
  ++i;  // ++ は i = i + 1 に置き換えられ OK
  
  --j;  // 同じく OK
  
  /+
  // 以下 "no effect" エラー
  i * 3;
  
  i + j * 3;
  
  // 途中効果は関係なく i + j としてエラー
  ++i + --j;
  +/
  
  /*
  *   結局 i、j は使わず、プログラム対して
  *     効果がないのはスルーだよ
  */
  writeln( "Welcome Beginner" );
}

Effect のない 式 は必要なく、ほとんどの場合 記述ミス ですし、不慣れだと犯し勝ちな ミス ですから、コンパイルエラー は修正の助けになるはずです。

また、Effect のない プログラムコード も作為的でなければ 設計ミス か 記述ミス ですが、

式 以外の no effect は、ほとんど スルー です。

int noEffect( in int n = 0 ){
  return n;
}

void main()
{
  int i;
  
  // 関数の呼び出しに効果がないのは OK
  noEffect( i );
  noEffect( 10 );
  noEffect;
  
  /+
  // 式文になるとエラーだな
  i + noEffect( 100 );
  +/
}

意味なしプログラムもスルー

D:\Pen-Jr\My Programs\Welcome>dmd test -w

D:\Pen-Jr\My Programs\Welcome>
式 には必ず 結果 がありますから、その 結果 の行き場所がない 式( 代入を除く )があれば エラー にするだけで、特別な解析 をしているわけではありません。

プログラムコード に Effect があることを判断するためには 特別な解析 が必要になりますし、それは コンパイラ の仕事にはなっていません。

また、Effect のない 式 が必要なら、

cast( void )( 1 + 1 );  // OK!
cast
必要ないとも思いますが、こんな手段が用意されてるのも D言語 らしいところです。
式の中の式の中の・・・
import std.stdio;

int getMul( in int n1, in int n2 )
{
  writeln( n1, " * ", n2 );
  return n1 * n2;
}

  // 途中結果を表示
int disp( in int n )
{
  writeln( "n = ", n );
  return n;
}

  // エントリーポイント
void main()
{
  int i = 3;

  writeln(
    "Final Answer = ",
    /*^^^^^^^^^^^^^^^^^^^^^^^^^^
    ^   以下1つの式だす
    */
    disp( i * 2 ) +
      disp( i = i-- + getMul( i = 3 * ++i, 10 ) ) /
        disp( ++i )
  );
}

ちゃんと実行出来まっせ。

D:\Pen-Jr\My Programs\Welcome>dmd test

D:\Pen-Jr\My Programs\Welcome>test
n = 6
9 * 10
n = 93
n = 94
Final Answer = 6

こんな コード は複雑な内には入らないくらい複雑怪奇な 式文 が存在するのは、数学 の 式 が複雑怪奇なのと同じです。

ちなみに最後の writeln は、

writeln("Final Answer = ",/*以下1つの式だす*/disp(i*2)+disp(i=i--+getMul(i=3*++i,10))/disp(++i));  

でも同じです。

特に 単項演算 など同じ記号が違う意味になってたりしますから混乱しそうですが、D言語 はよく考えられていて、空白のあるなしなどで 簡単 に違った意味になったりしません。

常に全部頭に入っていないとコードが書けないようなことはありませんから、必要になった時、その都度見直して使えば良いでしょう。

プログラミング に 数学の知識が要求されることは 常識 だったりしますが、専門の職業プログラマーとかでないなら、小学生の算数レベルでも 算数センス だけでなんとかなることは、筆者がそのサンプルに該当します。

もちろん、数学の知識が豊富にあれば、既存のアルゴリズムの応用でより正確な設計が「愚かな回り道」なしで出来ますから、その手の玄人達に小学生レベルで対抗するのは無謀以外の何者でもありませんが、職業でさえなければ「愚かな回り道」だって 面白い遊び になります。

2011年3月10日

E-Mail : open@pen-jr.org

ご意見やご指摘は大歓迎ですが、質問など返信は期待しないでください

pen jr.
D言語研究
わかったつもりになるD言語
D言語友の会
News&Days
はじめてのブログ選び