目的
C言語にforeachはない
なら作るしかない
とりあえずforeachもどきができたのでまとめる
foreachとは
リストや配列の値を最初から順番に見ていく関数
Pythonのforはそもそもこの形
for x in array:
#xにリストの最初から値が入る
Javaでは拡張for文という名前で亜種のように扱われている
for(int x : array){
//xにリストの最初から値が入る
}
この関数が__C言語にはない__
あるのは普通のfor文のみ
C++やC#にはある
方針
実装にあたって__define文__を使い、マクロ関数で実装する
配列の最初から最後までを走査するような動作
なるべくシンプルに、他の言語と使用感があまり変わらないように
実装
以下のようなdefine文を考えた
# define foreach(x, list) for(x=list; x-list<sizeof(list)/sizeof(list[0]); x=x+1)
要するにforeach()と書かれた部分を置き換えるだけ
この1文だけ挿入することで実行可能
以下実行例
# include<stdio.h>
//foreach定義
# define foreach(x, list) for(x=list; x-list<sizeof(list)/sizeof(list[0]); x=x+1)
void main(){
int array2[5]={2,5,3,7,2};
int* y;
foreach(y, array2){
printf("%d\n", *y);
}
return;
}
//2
//5
//3
//7
//2
変数としてあらかじめ宣言したポインタを使用する
ので値を見るときはアスタリスクをつける必要あり
一行追加するだけで使えるなかなか便利なものに
追加したdefine文も割とシンプルに書けた
ここで気づいた
他の言語のforeachは__値渡し__である
上で作ったのは__参照渡し(のようなポインタ渡し)__である
参照渡しでもいい気はするがなるべく近づけたい
元の値が変わる恐れがあるのもやはり良くないのではないかと考えた
改めて実装
値渡しになるよう色々考えて次のようにした
# define foreach(x, list) for(x=list[0], foreachcounter=0; foreachcounter<sizeof(list)/sizeof(list[0]); x=list[++foreachcounter])
int foreachcounter;
defineで置き換える考えは変えず
ファイル名の通りヘッダファイルとして読み込んで使用する形式に
実行は以下の通り
# include<stdio.h>
//foreach読み込み
# include "foreach.h"
void main(){
int array[5]={2,5,3,7,2};
int x;
foreach(x, array){
printf("%d\n", x);
}
return;
}
//2
//5
//3
//7
//2
・ポインタを使う必要がない
・導入が簡単
・ヘッダファイルとして秘匿されている
・使用感は他の言語に結構近い
・値渡しになっている
方針に沿ったものになったはず
型を揃えればdoubleやcharでも問題ない
所感
色々と納得いかない
以下理由
・変数宣言を行っている
わざわざ配列の長さをカウントするための変数を宣言したのが目立つ
別の方法でカウントできないか思いつかなかった
結果的にグローバル変数と化している
・内部で宣言できない
他の言語(上記のJavaなど)ではfor内のみのスコープの変数を宣言できる
変数の宣言と引数指定を同時に行える
// ↓ここで宣言できるようにしたい
for(int x : array){
//xにリストの最初から値が入る
}
今回は外部で宣言しなければならない
単純にやり方が分からなかった
まとめ
使えるには使えるはず
もう少し改良したい