UWSCという開発ソフトを使って作り上げる作業を実際にやってみるカテゴリ。準備した自作関数や使い方、トラブルを記事にしていきます。得るものがあれば幸いです。
記事の内容
○配列の再構築のやり方
関数への値渡しと参照渡し
配列の要素の削除
配列の要素の挿入・追加
配列の要素の削除
配列の要素の挿入・追加
ポク太郎です。
以前、下のような記事を書きましたが、すごく面倒な方法だったので作り直しします。
配列変数を使いこなすために、さっと配列の指定要素を削除したり、挿入・追加して配列を再構築してしまう方法を考えています。
関数への値渡しと参照渡し
図を二つ載せます。
プログラムの処理の順番と変数が更新されるタイミングを書いた図です。左側のメインから右側の関数へ引数を渡すのですが渡し方に“値渡し”と“参照渡し”(C++と同じものと思ってもいいのかな?)があります。
○値渡し
○参照渡し
通常は値渡しを使用すればよいのですが、都合の悪い場合があります。戻り値が配列、かつ、要素数が関数内で変化してしまった場合です。
配列の要素数が関数を通る前後で変化しない場合は、UWSCでは下のように一文書いてやると、関数の戻り配列が全要素コピーされますが、
hairetu = 関数(hairetu)
関数内で配列の要素数が変わったときには、上のように書くと「要素数が違うよ」とエラーが出て止まってしまいます。
今回やろうとしているのは、配列の再構築。要素を削除、挿入・追加ですので、要素数が関数を通る前後で変わってしまいます。
そこで、この“参照渡し”を使用して、呼び出し側が一行で済むよう作り直します。
プログラムの処理の順番と変数が更新されるタイミングを書いた図です。左側のメインから右側の関数へ引数を渡すのですが渡し方に“値渡し”と“参照渡し”(C++と同じものと思ってもいいのかな?)があります。
○値渡し
関数へはメインのローカル変数Aの値を教えてあげて、関数内のRESULTの値をにメインのローカル変数Bに代入します。
このとき、関数は変数Aの値を教えてもらってるだけなので、関数内ではメインの変数Aを一切更新することができません。
このとき、関数は変数Aの値を教えてもらってるだけなので、関数内ではメインの変数Aを一切更新することができません。
○参照渡し
関数へはメインのローカル変数Aそのものを渡してあげて、関数内のRESULTの値をにメインのローカル変数Bに代入します。
このとき、関数はメインのローカル変数Aそのものを預かっているので、関数内で引数Cを更新すると、メインのローカル変数である変数Aを更新することができます。
この参照渡しを実現するには、関数の宣言文FUNCTIONで、引数の定義を“var 引数”とします。
このとき、関数はメインのローカル変数Aそのものを預かっているので、関数内で引数Cを更新すると、メインのローカル変数である変数Aを更新することができます。
この参照渡しを実現するには、関数の宣言文FUNCTIONで、引数の定義を“var 引数”とします。
通常は値渡しを使用すればよいのですが、都合の悪い場合があります。戻り値が配列、かつ、要素数が関数内で変化してしまった場合です。
配列の要素数が関数を通る前後で変化しない場合は、UWSCでは下のように一文書いてやると、関数の戻り配列が全要素コピーされますが、
hairetu = 関数(hairetu)
関数内で配列の要素数が変わったときには、上のように書くと「要素数が違うよ」とエラーが出て止まってしまいます。
今回やろうとしているのは、配列の再構築。要素を削除、挿入・追加ですので、要素数が関数を通る前後で変わってしまいます。
そこで、この“参照渡し”を使用して、呼び出し側が一行で済むよう作り直します。
配列の要素の削除
1 2 3 4 5 6 7 8 9 10 11 12 | FUNCTION remove(var a[],rn) IF rn<0 or rn>LENGTH(a)-1 PRINT "ポクエラー(remove関数):無効な要素番号が削除指定されました。" RESULT=0 ELSE FOR i=rn TO LENGTH(a)-1-1 a[i]=a[i+1] NEXT RESIZE(a,LENGTH(a)-1-1) RESULT=1 ENDIF FEND |
1,12行目 | 1 12 | FUNCTION remove(var a[],rn) FEND |
remove関数宣言:引数rnの要素番号を渡された配列から削除する関数 引数a[]: 再構築する配列 引数rn: 削除する要素番号 | ||
2,5,11行目 | 2 5 11 | IF rn<0 or rn>LENGTH(a)-1 ELSE ENDIF |
引数rnが配列の有効な要素数を指定しているかを判定。 無効な要素番号(-値や最大要素番号より大)⇒3、4行目へ 有効な要素番号⇒6~10行目へ | ||
3,4行目 | 3 4 | PRINT "ポクエラー(remove関数):無効な要素番号が削除指定されました。" RESULT=0 |
エラーを表示し、関数の戻り値は0を返す。 | ||
6~10行目 | 6 7 8 9 10 | FOR i=rn TO LENGTH(a)-1-1 a[i]=a[i+1] NEXT RESIZE(a,LENGTH(a)-1-1) RESULT=1 |
引数rnから最大要素番号の一つ手前までをループし、一つ上の要素番号の内容を配列a[i]に代入していきます。 済んだら配列を最大要素番号より一つ小さくリサイズします。 RESIZE(a,現在の最大要素番号-1) 関数の戻り値として1を返します。 |
配列の要素の挿入・追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | FUNCTION append(var a[],an,dt) RESIZE(a,LENGTH(a)-1+1) IF an<0 or an>LENGTH(a)-1 a[LENGTH(a)-1]=dt ELSE FOR i=LENGTH(a)-1 TO an step -1 IF i=an a[i]=dt ELSE a[i]=a[i-1] ENDIF NEXT ENDIF RESULT=1 FEND |
1,15行目 | 1 15 | FUNCTION append(var a[],an,dt) FEND |
append関数宣言:引数anの要素番号位置に配列要素を挿入・追加する関数(引数anに-値や最大要素番号より大を指定された場合は最後に追加する仕様) 引数a[]: 再構築する配列 引数an: 挿入する位置の要素番号 引数dt: 要素番号anの位置に入れたい内容 | ||
2行目 | 2 | RESIZE(a,LENGTH(a)-1+1) |
まず、配列の最大要素番号を現在より一つ大きくリサイズします。 RESIZE(a,現在の最大要素番号+1) | ||
3,5,13行目 | 3 5 13 | IF an<0 or an>LENGTH(a)-1 ELSE ENDIF |
引数anが配列の有効な要素数を指定しているかを判定。 無効な要素番号(-値や最大要素番号より大)⇒4行目へ 有効な要素番号⇒6~12行目へ | ||
4行目 | 4 | a[LENGTH(a)-1]=dt |
現在の最大要素番号の位置(2行目で既に一つ大きくしているので)に引数dtを代入します。 | ||
6~12行目 | 6 7 8 9 10 11 12 | FOR i=LENGTH(a)-1 TO an step -1 IF i=an a[i]=dt ELSE a[i]=a[i-1] ENDIF NEXT |
最大要素番号から小さい方である引数anまでをループします。 引数anのときは引数dtを代入、違うときは一つ下の要素番号の内容を配列a[i]に代入していきます。 | ||
14行目 | 14 | RESULT=1 |
関数の戻り値として1を返します。 |
動作確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | DIM test[10] FOR i=0 TO LENGTH(test)-1 test[i]=i*2 PRINT test[i] NEXT PRINT "--最大要素番号は"+LENGTH(test)-1 rn=8 remove(test,rn) PRINT "--要素"+rn+"を削除" FOR i=0 TO LENGTH(test)-1 PRINT test[i] NEXT PRINT "--最大要素番号は"+LENGTH(test)-1 an=5 dt=51 append(test,an,dt) PRINT "--要素"+an+"に"+dt+"を追加" FOR i=0 TO LENGTH(test)-1 PRINT test[i] NEXT PRINT "--最大要素番号は"+LENGTH(test)-1 |
1~6行目 | 1 2 3 4 5 6 | DIM test[10] FOR i=0 TO LENGTH(test)-1 test[i]=i*2 PRINT test[i] NEXT PRINT "--最大要素番号は"+LENGTH(test)-1 |
配列test[10]を準備し、要素番号x2の値を代入してテスト用配列を作成、表示します。最後に最大要素番号を表示しておきます。 | ||
8~14行目 | 8 9 10 11 12 13 14 | rn=8 remove(test,rn) PRINT "--要素"+rn+"を削除" FOR i=0 TO LENGTH(test)-1 PRINT test[i] NEXT PRINT "--最大要素番号は"+LENGTH(test)-1 |
変数rnを設定して、作成したremove()関数を呼び出した後、完成したテスト用配列を表示します。 | ||
16~23行目 | 16 17 18 19 20 21 22 23 | an=5 dt=51 append(test,an,dt) PRINT "--要素"+an+"に"+dt+"を追加" FOR i=0 TO LENGTH(test)-1 PRINT test[i] NEXT PRINT "--最大要素番号は"+LENGTH(test)-1 |
変数anと変数dtを設定して、作成したappend()関数を呼び出した後、完成したテスト用配列を表示します。 |
0 2 4 6 8 10 12 14 16 18 20 --最大要素番号は10 --要素8を削除 0 2 4 6 8 10 12 14 18 20 --最大要素番号は9 --要素5に51を追加 0 2 4 6 8 51 10 12 14 18 20 --最大要素番号は10 |
要素8を削除すると、test[8]の16が無くなり最大要素番号が一つ小さくなります。要素5に51を追加すると、test[5]に51が代入、以降は後ろへ一つづつずれて、最大要素番号が一つ大きくなってくれました。
8、16行目の値を変更して試してみてください。
記事の内容
記事の内容は伝わりましたでしょうか。
○配列の再構築のやり方
○配列の再構築のやり方
関数への値渡しと参照渡し
配列の要素の削除
配列の要素の挿入・追加
配列の要素の削除
配列の要素の挿入・追加
【関連記事】 | |
人気! | [UWSC]配列変数と関数[使い方まとめ] |
[UWSC]配列の最大要素を返す関数 |
0 件のコメント:
コメントを投稿