高等学校におけるアルゴリズムやプログラムに関する教育では、採用されるプログラミング言語は多様で、プログラミングの実習時間も異なります。このような事情を考慮し、DNCL、DNCL2を踏まえた、手順記述言語「DNCL3」を定義します。(ソースファイルの拡張子は .dncl、MIMEタイプは text/dncl とします。)
- ブラウザで動作する実行環境 DNCL3実行環境
- HTML内で組み込んで動かす例 DNCL on web
<script type="module" src="https://code4fukui.github.io/DNCL3/web.js"></script>
<script type="text/dncl">
sum = 0
for i = 1 to 10 {
sum = sum + i
}
print i
</script>
- CLI(Command Line Interface)での実行例: BMI計算 examples/bmi.dncl
deno -A https://code4fukui.github.io/DNCL3/cli.js examples/bmi.dncl
- DNCL3実装デバッグ環境 dncl2js
※ TODO: 下記は未実装です
変数名は、英字で始まる英数字と「_」や日本語の並びです。ただし、予約語(print, input, and, or, not, if, else, while, do, until, for, to, step, break, function, return)は変数名として使用できません。
- 例: n, sum, points, 得点
すべて大文字の英字による変数は実行中に変化しない値を表します。
- 例: A, BMI
配列の要素は、0から始まる要素の番号を添字で指定します。
- 例: array[3]
数値は10進法で表します。文字列は、文字の並びを「"」でくくって表します。
- 例: 100
- 例: 99.999
- 例: "見つかりました"
- 例: "It was found."
文字列に0から始まる要素番号を添字で指定すると、先頭が0とした文字を文字列として返します。もし、添字が文字列の範囲外の場合、空文字列「""」を返します。
s = "ABC"
print s[0],s[2] # A C と表示される
「print」を使って、表示文で数値や文字列や変数の値を表示します。複数の値を表示する場合は「,」で区切って並べます。何も指定しないと1行空きます。
- 例: print n (nが15のとき「15」と表示されます。)
- 例: print "整いました" (「整いました」と表示されます。)
- 例: print n, "個見つかった" (nが3のとき、「3 個見つかった」と表示されます。)
- 例: print "(", x, ",", y, ")" (xが5、yが−1のとき、「( 5 , -1 )」と表示されます。)
- 例: print (1行空きます。)
代入文は変数に値を設定します。「=」の左辺に変数または添字付きの配列を、右辺に代入する値を書きます。
- 例: n = 3
- 例: points[4] = 100
使用されている配列の要素に同じ値をまとめて代入することができます。(未実装です)
- 例: points = 0
「[」「]」と「,」を使用し、要素のの値をまとめて指定することで、置き換えることができます。
- 例: points = [87, 45, 72, 100]
複数の代入文を、「,」で区切りながら、横に並べることができます。この場合は、代入文は左から順に実行されます。
- 例: sum = n, point = n * (n + 1)
外部から入力された値を代入するために、次のように記述することができます。
- 例: x = input()
- 例: x = input("0から100までの好きな数を入力してください")
この節では、算術演算と比較演算、そして論理演算について説明します。比較演算やそれを組み合わせる論理演算は、条件分岐文(5.1節)や条件繰返し文(5.2節)の〈条件〉で使うことができます。
加減乗除の四則演算は、「+」、「-」、「*」、「/」で指定します。
整数の除算では、商を「//」で、余りを「%」で計算することができます。
- 例: val = 7 / 2 (valには3.5が代入されます。)
- 例: quo = 7 // 2 (quoには3が代入されます。)
- 例: remain = 10 % 3 (remainには1が代入されます。)
複数の演算子を使った式の計算では、基本的に左側の演算子が先に計算されますが、「*」、「/」、「//」、「%」は、「+」、「-」より先に計算されます。また、丸括弧「(」と「)」で式をくくって、演算の順序を明示することができます。
- 例: x = a - b - c は、x = (a - b) - c と同じです。
- 例: n = 1 + a // 3 は、n = 1 + (a // 3) と同じです。
- 例: ave = (a + b) // 2 は、ave = a + b // 2 と異なります。
文字列の算術演算は「+」のみ使用することができます。前後のいずれかが文字列の場合、文字列として連結します。
数値の比較演算は、「==」、「!=」、「>」、「>=」、「<=」、「<」で指定します。演算結果は、真か偽の値となります。
- 例: n > 3 (nが3より大きければ真となります。)
- 例: n * 2 <= 8 (nの2倍が8以下であれば真となります。)
- 例: n != 0 (nが0でなければ真となります。)
文字列の比較演算は、「==」、「!=」を利用することができます。「==」は、左辺と右辺が同じ文字列の場合に真となり、それ以外の場合は偽となります。「!=」は、左辺と右辺が異なる文字列の場合に真となり、それ以外の場合(同じ文字列の場合)は偽となります。
- 例: "あいうえお" == "あいうえお" (真となります。)
- 例: "あいうえお" == "あいう" (偽となります。)
- 例: "ABC" == " ABC" (真となります。)
- 例: "ABC" == "abc" (偽となります。)
- 例: "あいうえお" != "あいうえお" (偽となります。)
- 例: "あいうえお" != "あいう" (真となります。)
- 例: "ABC" != "ABC" (偽となります。)
- 例: "ABC" != "abc" (真となります。)
論理演算は、真か偽を返す式に対する演算で、「and」、「or」、「not」の演算子で指定します。「not」、「and」、「or」の順で、同一の演算子の場合は左が優先されますが、丸括弧「(」と「)」で、演算の順序を指定することができます。
「〈式1〉 and 〈式2〉」は、〈式1〉と〈式2〉の結果がいずれも真である場合に真となり、それ以外の場合は偽となります。
「〈式1〉 or 〈式2〉」は、〈式1〉と〈式2〉の結果のどちらかが真である場合に真となり、それ以外の場合は偽となります。
「not 〈式〉」は、〈式〉の結果が真である場合に偽となり、偽の場合は真となります。
- 例: n >= 12 and n <= 27 (nが12以上27以下なら真となります。)
- 例: n % 2 == 0 or n < 0 (nが偶数か負の値なら真となります。)
- 例: not n > 75 (nが75 より大きくなければ真となります。)
- 例: n > 12 and not n < 27 は、n > 12 and (not n < 27) と同じです。
- 例: not n > 12 and n < 27 は、(not n > 12) and n < 27 と同じです。
- 例: n == 0 or n > 12 and n < 27 は、n == 0 or (n > 12 and n < 27) と同じです。(「and」が先に実行されるため。)
条件分岐文(5.1節)や条件繰返し文(5.2節)、順次繰返し文(5.3節)をまとめて制御文と呼びます。制御文の中の〈処理〉として、表示文(2節)、代入文(3節)、値を返さない関数(6.2節)、条件分岐文、順次繰返し文、条件繰返し文を、一つ以上並べて使うことができます。また、条件分岐文や条件繰返し文の中の〈条件〉として、比較演算(4.2節)と論理演算(4.3節)を使用することができます。
条件分岐文は、〈条件〉が真かどうかによって、実行する処理を切り替えます。
〈条件〉の値が真のときにある処理を実行し、〈条件〉の値が偽のときに実行する処理がない場合は、次のように指定します。
《一般形》
if 〈条件〉 {
〈処理〉
}
例:
if x < 3 {
x = x + 1
y = y - 1
}
〈条件〉の値が真のときにある処理を実行し、〈条件〉の値が偽のときに別の処理を実行する場合は、次のように「else」を組み合わせて指定します。
《一般形》
if 〈条件〉 {
〈処理 1〉
} else {
〈処理 2〉
}
例:
if x < 3 {
x = x + 1
} else {
x = x - 1
}
条件分岐の中で複数の条件で実行する処理を切り替えたい場合は、次のように「else if」を使って条件を追加します。
《一般形》
if 〈条件 1〉 {
〈処理 1〉
} else if 〈条件 2〉 {
〈処理 2〉
} else {
〈処理 3〉
}
例:
if x == 3 {
x = x + 1
} else if y > 2 {
y = y + 1
} else {
y = y - 1
}
条件繰返し文には、「前判定」と「後判定」の2種類があります。
〈条件〉が真の間、〈処理〉を繰り返し実行します。
〈処理〉を実行する前に〈条件〉が成り立つかどうか判定されるため、〈処理〉が1回も実行されないことがあります。
《一般形》
while 〈条件〉 {
〈処理〉
}
例:
while x < 10 {
sum = sum + x
x = x + 1
}
〈条件〉が真になるまで、〈処理〉を繰り返し実行します。
〈処理〉を実行した後に〈条件〉が成り立つかどうか判定されるため、〈処理〉は少なくとも1回は実行されます。
《一般形》
do {
〈処理〉
} until 〈条件〉
例:
do {
sum = sum + x
x = x + 1
} until x >= 10
順次繰返し文は、〈変数〉の値を増やしながら、〈処理〉を繰返し実行します。
《一般形》
for 〈変数〉 = 〈初期値〉 to 〈終了値〉 step 〈差分〉 {
〈処理〉
}
順次繰り返し文は、以下の手順で実行されます。
- 〈変数〉に〈初期値〉が代入されます。
- 〈変数〉の値が〈終了値〉よりも大きければ、繰り返しを終了します。
- 〈処理〉を実行し、〈変数〉の値に〈差分〉を加え、手順2に戻ります。
例:
for x = 1 to 10 step 1 {
sum = sum + x
}
〈差分〉が1の場合、step以降を省略できます。
例:
for x = 1 to 10 {
sum = sum + x
}
〈差分〉にマイナスの値を指定すると、〈変数〉の値を〈初期値〉から減らしながら、その値が〈終了値〉よりも小さくなるまで、〈処理〉を繰り返し実行します。
例:
for x = 10 to 1 step -1 {
sum = sum + x
}
繰返し文中で、「break」を使用すると繰返しを中断します。
《一般形》
for 〈変数〉 = 〈初期値〉 to 〈終了値〉 step 〈差分〉 {
if 〈条件〉 {
break
}
〈処理〉
}
関数には、値を返すものと値を返さないものがあります。
問題文の中で
- 指定された値xの二乗の値を返す関数「二乗(x)」を用意する
- 値mのn乗の値を返す関数「べき乗(m, n)」を用意する
- 値m以上値n以下の整数をランダムに一つ返す関数「乱数(m, n)」を用意する
- 値nが奇数のとき真を返し、そうでないとき偽を返す関数「奇数(n)」を用意する
のように定義された関数を、表示文(2節)、代入文(3節)、算術演算(4.1節)、比較演算(4.2節)、あるいは論理演算(4.3節)の中で使うことができます。関数を呼び出すときは、関数名に続き、「(」と「)」の間に引数を書きます。複数の引数を指定する場合は、「,」で区切ります。
- 例: y = 二乗(x) # yにxの二乗が代入されます。
- 例: z = 二乗(x) + べき乗(x, y) # zにxの二乗とxのy乗の和が代入されます。
- 例: r = 乱数(1, 6) # rに1から6までの整数のうちいずれかが代入されます。
問題文の中で
- 指定された値nを2進法で表示する関数「二進法で表示する(n)」を用意する
のように値を返さない関数が定義されることがあります。
- 例: 二進法で表示する(11) #「1011」と表示されます。
新しい関数の定義は、DNCL3を用いて次のように記述します。
《一般形》
function 〈関数名〉( 〈引数列〉 ) {
〈処理〉
}
関数が呼び出される時に引数として与えられる値は、引数列に記述した変数名で利用します。複数の引数を指定する場合は、「,」で区切ります。定義した関数は、用意された関数の呼び出し(6節)と同じ記法で呼び出すことができます。
引数列の変数や、関数内で新たに代入された変数は、その関数内でのみ使用できます。
基本的に関数内で関数外の変数も使用できますが、引数列の変数と同名の関数外の変数は、関数内で使用できません。
例: 1から正の整数nまでの和を表示する関数「和を表示する(n)」の定義例
function 和を表示する(n) {
sum = 0
for i = 1 to n {
sum = sum + i
}
print sum
}
例: 値mのn乗の値を表示する関数「べき乗を表示する(m, n)」の定義例
function べき乗を表示する(m, n) {
p = 1
for i = 1 to n {
p = p * m
}
print p
}
「return」を使用して値を返す関数を定義することができます。値を指定せずに「return」を使用すると値を返さず関数内の処理を終えることができます。
例: 値mのn乗の値を返す関数「べき乗(m, n)」の定義例
function べき乗(m, n) {
p = 1
for i = 1 to n {
p = p * m
}
return p
}
atai = 乱数() # 0以上1未満のランダムな小数をataiに代入する
- ※1行内において#以降の記述は処理の対象とならない
#=
複数行に渡る
コメントの記述方法
=#
- 「#=」から「=#」までの記述は処理の対象とならない。「=#」がない場合はファイル終端までがコメントとなる。