見出し画像

プログラミング学習の記録 #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次元より大きな次数で用いることは、おそらくないだろうが、知識としては知っておきたいところである。

-----

動け!タイムライン

いいなと思ったら応援しよう!

flowes_oyr
動物園か水族館にいきたいですね。

この記事が参加している募集