プログラミング学習の記録 #011(C)
卒業研究で扱う論文を読んでいると、想定していたことだが、知識が増えるばかりで、研究手法がまるでわからない。おそらく、研究手法は、既にその分野の常識となっていて、わざわざ論文に記載するほどでもないという判断なのだろう。しかし、その分野の定番の和文教科書があるわけでもなく、初心者には厳しいものがある。思ったよりも早いが、そろそろ日本語を超えるしかないのだろうか。
前回の復習
練習問題 7.1(角谷予想)
整数に関する以下の性質が予想されている。
任意の正の整数$${n}$$は、以下の操作によりいずれ必ず$${1}$$になる。
1.
$${n}$$が奇数ならば$${3n+1}$$を新しい$${n}$$とする。
$${n}$$が偶数ならば$${n/2}$$を新しい$${n}$$とする。
2.
「1.」へ戻る。
これを確かめるために、正の整数$${n}$$をキーボードから入力し、上の操作を行って$${1}$$になるまでの過程を表示するプログラムを作成せよ。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
int x ;
printf("Input x: ");
scanf("%d",&x);
if(x <= 0)
{
printf("Error in x.\n");
exit(1);
}
printf("\n");
while(x != 1)
{
printf("%d,",x);
if(x % 2 != 0)
{
x = 3 * x + 1 ;
}else
{
x = x / 2 ;
}
}
printf("%d\n",x);
printf("HAPPY SMILE (^_^)v\n");
return 0;
}
配列
最小公倍数や最大公約数を求めるプログラムコードを書いたときに、既に使用していた。教科書を参考にして、Fibonacci数列を表示するプログラムコードを書いた。
#include <stdio.h>
#include <math.h>
int main()
{
int fibo[4], i ,max ;
max = 4 ;
fibo[0] = 1 ;
fibo[1] = 1 ;
printf("%d,%d",fibo[0],fibo[1]);
for( i = 2 ; i <= max ; i = i + 1 )
{
fibo[i] = fibo[i-1] + fibo[i-2] ;
printf(",%d",fibo[i]);
}
printf("\n");
max = sizeof(fibo) / sizeof(fibo[0]) ;
printf("%d\n", max);
printf("HAPPY SMILE (^_^)v\n");
return 0;
}
コードの最後に、配列の要素数を表示するようにした。このコードを実行すると、
% ./a.out
1,1,2,3,5
4
HAPPY SMILE (^_^)v
と表示された。配列の要素数が4であるのに対して、Fibonacci数列は、5項も表示されている。これは、なぜか。一方で、「fibo[4]」を表示させようとしたら、コンパイル時点でエラーとなった。教科書によると、たとえば、「x[4]」という配列を宣言すると、0番目から開始されて、x[0],x[1],x[2],x[3]が用意されるということであった。しかし、今回のコードでも、以前書いた最小公倍数や最大公約数を求めるコードでも、ここでいう「x[4]」に相当する要素が存在し、実際に正しく表示されていた。これは、いったいなぜだろうか。運用で特に問題がなければよいのだが、もし、理由がわかる方がいれば教えてほしい。
マクロ定義
プログラムの最初の部分(「#include <math.h>」などがある部分)に、
#define A B
のように書くことで、そのコード内では「A」を「B」に置き換えて実行させることができる。マクロ定義を用いて、以下のようなコードを書いた。
#include <stdio.h>
#define pri printf("Iced Tea.\n")
int main()
{
pri;
printf("HAPPY SMILE (^_^)v\n");
return 0;
}
これをTerminalで実行すると、
% ./a.out
Iced Tea.
HAPPY SMILE (^_^)v
と表示された。実用的かどうかはわからないが、こういった使い方もできるということがわかった。
多次元配列
配列は、ベクトルや数列のような1次元的な並びだけでなく、行列のような多次元的な並びも表現することができる。教科書を参考にして、2つの3次正方行列の積を計算するプログラムコードを書いた。
#include <stdio.h>
#include <math.h>
#define max 3
int main()
{
double a[max][max], b[max][max], c[max][max];
int i,j,k ;
char name1, name2 ;
for( k = 0 ; k < 2 ; k = k + 1 )
{
switch(k)
{
case 0 :
name1 = 'A' ;
name2 = 'a' ;
break;
case 1 :
name1 = 'B' ;
name2 = 'b' ;
break;
}
printf("Matrix %c\n",name1);
for( i = 0 ; i < max ; i = i + 1 )
{
for( j = 0 ; j < max ; j = j + 1 )
{
printf("Input %c[%d][%d]: ",name2,i+1,j+1);
if(k == 0)
{
scanf("%lf", &a[i][j]);
}else
{
scanf("%lf", &b[i][j]);
}
}
}
}
for( i = 0 ; i < max ; i = i + 1 )
{
for( j = 0 ; j < max ; j = j + 1 )
{
c[i][j] = 0 ;
for( k = 0 ; k < max ; k = k + 1 )
{
c[i][j] = c[i][j] + a[i][k] * b[k][j] ;
}
}
}
printf("Matrix A * Matrix B =\n");
for( i = 0 ; i < max ; i = i + 1 )
{
for( j = 0 ; j < max ; j = j + 1 )
{
printf("%12.4f",c[i][j]);
}
printf("\n");
}
printf("HAPPY SMILE (^_^)v\n");
return 0;
}
ループ構造がだんだんと複雑になってきた。ところで、多次元配列は、たいてい何次元でも可能らしい。3次元より大きな次数で用いることは、おそらくないだろうが、知識としては知っておきたいところである。
-----
動け!タイムライン