for文について
MATLABでのfor文とC言語でのfor文は、構文は良く似ているが、発想自体が異なるため、注意して使わないと、互換性の無いプログラムになってしまう恐れがある。その違いとは、C言語でのfor文は、ループ回数が何回であるか決まるのは、ループしている最中に逐次評価するのに対し、MATLABでは、実行時にループ回数を確定し、そのループ回数に基づいて行っている点が異なる。
では、具体的な例を見ながら解説していく。
C言語でのfor文の定義
|
MATLABでのfor文の定義
|
for(初期化式;条件式;増減式)
|
for 変数=初期値:増分:最終値
|
|
ループ内に条件式がない。for文を実行する時点で、ループベクトルを生成し、その順序どおり実行する。
|
for i=0:3
i
end
i
|
実行結果は、
i =
0
i =
1
i =
2
i =
3
i =
3
|
つまり、ループ後のiの値は、for文最後の値と同じ3になっている。ところがこれと同じ用にC言語で記述すると、
#include <stdio.h>
void main(void) {
int i;
for(i = 0;i <= 3;i++) {
printf("i=%d\n",i);
}
printf("i=%d\n",i);
}
|
結果は、
i=0
i=1
i=2
i=3
i=4
|
となる。つまりループから出た後の変数iの値が、MATLABとC言語では異なる。これは、MATLABでのfor文は、ループ回数などをベクトルとして扱うのに対し、C言語では、単なる変数として扱うための違いである。つまり、MATLABでのfor文とC言語のfor文を対応させると、
MATLAB
|
C言語
|
for i=0:N
i
end
|
for (i=0;i <=N;i++) {
printf("%d\n",i);
}
i--; |
とする必要がある。逆にMATLAB言語からC言語に変換する場合には、
C言語
|
MATLAB
|
for (i=0;i <N;i++) {
printf("%d\n",i);
}
|
for i=0:N-1 i
end
i=i+1; |
とすると良い。一般には、for文は、ループの回数を指定するために使うため、ループ後の変数の値などはあまり考慮しなくてもよいが、C言語などのfor構文は、フレキシビリティが大きいため、考慮しなければならない場合もあるので注意を要する。
Example1
MATLABでのfor文
N=4;
for i=N:-1:2,
i
end
i
|
実行結果は、
i =
4
i =
3
i =
2
i =
2
|
となる。これをC言語に変換する。この場合には、デクリメントなので、
#include <stdio.h>
void main(void) {
int N=4;
int i;
for (i = N;i > =2 ;i--) {
printf("i=%d\n",i);
}
i++; printf("i=%d\n",i);
}
|
実行結果は、
i=4
i=3
i=2
i=2
|
となる。
example2
ちょっと困った例題を実行してみよう。
以下の問題を考えてみる。これは、ソーティングプログラムである。
d=[4,6,7,9];
N = length(d);
for i=N:-1:2,
for j=1:i-1
d([j,j+1])=d([j+1,j]);
[j,j+1]
end
end
[i,j]
|
これを実行すると、
ans = 1 2 ans = 2 3 ans = 3 4 ans = 1 2 ans = 2 3 ans = 1 2
ans = 2 1
>> |
となる。
これを上記の例を踏まえC言語に変換すると以下の用になる。
#include <stdio.h>
void main(void) {
int N=4;
int i,j;
for (i = N;i >=2 ;i--) {
for (j = 1;j <= i - 1;j++) {
printf("%d %d\n",j,j+1);
}j--; } i++; printf("i=%d,j=%d\n",i,j); }
|
実行結果は、
1 2
2 3
3 4
1 2
2 3
1 2
i=2,j=1
|
と同じになる。
ところが同様の計算をするMATLABスクリプト
d=[4 6 7 9];
n=length(d);
for i=1:n-1
for j=1:n-1
[j,j+1]
end
n=n-1;
end
[i,j,n]
|
実行結果は、
ans = 1 2 ans = 2 3 ans = 3 4 ans = 1 2 ans = 2 3 ans = 1 2
ans = 3 1 1
|
を同様にC言語に変換してみると、
#include <stdio.h>
void main(void) {
int n=4;
int i,j;
for (i = 1;i <= n - 1;i++) {
for (j = 1;j <= n - 1;j++) {
printf("%d %d\n",j,j+1);
}j--; n--; } i--; printf("i=%d,j=%d,n=%d\n",i,j,n); }
|
実行結果は、
1 2
2 3
3 4
1 2
2 3
i=2,j=2,n=2
|
となり、振る舞いが異なってしまう。C言語では、変数iのfor文の判断式にあるnの評価が逐次行われるのに対し、MATLABでは、for文を作成した時点でループ回数が決まってしまうことに依存する。つまり、ループ内でfor文に書かれた変数の値を変更してもその結果は反映されない。もし、C言語でMATLABと等価なプログラムを書くと、
#include <stdio.h>
void swap(int *a,int *b) {
int c;
c=*a;*a=*b;*b=c;
}
void main(void) {
int n,n1;
int i,j;
int d[]={1,2,3,4};
n = n1 = sizeof(d)/sizeof(int);
for (i = 1;i <= n - 1;i++) {
for (j = 1;j <= n1 - 1;j++) {
swap(&d[j-1],&d[j+1-1]);
printf("%d %d\n",j,j+1);
}j--; n1--; } i--; printf("i=%d,j=%d,n=%d\n",i,j,n1); for(i = 0;i < n;i++) printf("%d ",d[i]);
}
|
とし、ループ内評価変数を別々に定義すればよい。
1 2
2 3
3 4
1 2
2 3
1 2
i=3,j=1,n=1
|
以上のように配慮すれば、MATLABでもC言語のfor文で書かれたアルゴリズムを実装できるが、もっと、システマテックに簡単にやるには、MATLABのfor文を使わず、while文を使った方が簡単である。以下にその具体例を示す。
C言語
|
MATLAB
|
#include <stdio.h>
void main(void) {
int i;
for(i = 0;i < 4;i++) {
printf("i=%d\n",i);
i++;
}
printf("i=%d\n",i);
}
|
i=0; while(i < 4) disp(['i=',num2str(i)]); i=i+1; i=i+1; end disp(['i=',num2str(i)]); |
i=0
i=2
i=4
|
i = 0 i = 2 i = 4 >> |
つまり、
C言語で for(A;B;C) {D} と書いたものを
MATLABでは、システマテックにそのまま
A
while(B)
D;
C;
end
とすれば等価な構文となる。
C言語で for(A;B;C) {D} と書いたものを
MATLABでは、システマテックにそのまま
A
while(B)
D;
C;
end
とすれば等価な構文となる。