記憶域期間

#include<stdio.h>

int fx = 0;

void func(void){
        static sx = 0;
        int    ax  = 0;

        printf("%3d%3d%3d\n",ax++,sx++,fx++);
}

int main(void){
        int i;

        puts(" ax sx fx");
        puts("---------");
        for(i=0;i<10;i++){
                func();
        }
        puts("---------");
        return 0;
}

自動記憶域期間

関数の中で、記憶域クラス指定子staticをつけずに定義されたオブジェクトは自動記憶域期間をもち、次のような性質が与えられる。

「プログラムの流れが、宣言を通過する際に、そのオブジェクトが生成される。宣言を囲むブロックの終点(すなわち})を通過するときに、そのオブジェクトが消滅する。」

静的記憶域期間

関数の中でstaticをつけて宣言されたオブジェクトや、関数の外で宣言・定義されたオブジェクトは、次のような性質をもつ。

「プログラムの開始時、具体的にはmain関数を実行する前の準備段階においてオブジェクトが生成され、プログラムの終了時に消滅する。

多次元配列の受け渡し

2行3列の行列を加算するプログラム

#include<stdio.h>

void mat_add(const int ma[2][3],const int mb[2][3],int mc[2][3]){
        int i,j;
        for(i=0;i<2;i++){
                for(j=0;j<3;j++){
                        mc[i][j] = ma[i][j] + mb[i][j];
                }
        }
}

int main(void){
        int i,j;
        int ma[2][3] = {{1,2,3},{4,5,6}};
        int mb[2][3] = {{6,3,4},{5,1,2}};
        int mc[2][3] = {0};

        mat_add(ma,mb,mc);

        for(i=0;i<2;i++){
                for(j=0;j<3;j++){
                        printf("%3d",mc[i][j]);
                }
                putchar('\n');
        }
        return 0;
}
   

maとmbの和をmcに格納するので、mcはconstを与えずに宣言する。

演習6-10

明解C言語入門の演習。

#include<stdio.h>

void mul(const int ma[3][2],const int mb[3][2],int mc[3][2]){
        int i,j;

        for(i=0;i<3;i++){
                for(j=0;j<2;j++){
                        mc[i][j] = ma[i][j] * mb[i][j];
                }
        }
}
int main(void){
        int i,j;
        int ma[3][2] = {{1,2},{3,4},{5,6}};
        int mb[3][2] = {{6,5,},{4,3},{2,1}};
        int mc[3][2] = {0};

        mul(ma,mb,mc);

        for(i=0;i<3;i++){
                for(j=0;j<2;j++){
                        printf("%3d",mc[i][j]);
                }
                putchar('\n');
        }
        return 0;
}

番兵法を用いた遂次探索

番兵法を用いた遂次探索

#include<stdio.h>
#define NUMBER 5
#define FAILED -1

int search(int vc[],int key,int no){
        int i = 0;
        vc[no] = key;
    
        while(1){
                if(vc[i] == key){
                        break;
                }
                i++;
        }
        return(i == no ? FAILED:i);
}

int main(void){
        int i,ky,idx;
        int vx[NUMBER+1];
    
        for(i=0;i<NUMBER;i++){
                printf("vx[%d]:",i);
                scanf("%d",&vx[i]);
        }
        printf("探す値:");
        scanf("%d",&ky);

        idx = search(vx,ky,NUMBER);
    
        if(idx == FAILED){
                puts("探索に失敗しました。");
        }else{
                printf("%d%d番目にあります。\n",ky,idx+1);
        }
        return 0;
}

配列の末端に追加したデータを番兵とよび、それを用いた手続きを番兵法と呼ぶ。

C言語 〜遂次探索〜

遂次探索

#include<stdio.h>
#define NUMBER 5
#define FAILED -1

int search(const int vc[],int key,int no){
        int i = 0;

        while(1){
                if(i==no){
                        return (FAILED);
                }
                if(vc[i] == key){
                        return i;
                }
                i++;
        }
}

int main(void){
        int i,ky,idx;
        int vx[NUMBER];

        for(i=0;i<NUMBER;i++){
                printf("vx[%d]:",i);
                scanf("%d",&vx[i]);
        }
        printf("探す値:");
        scanf("%d",&ky);
        idx = search(vx,ky,NUMBER);

        if(idx == FAILED){
                puts("探索に失敗しました。");
        }else{
                printf("%d%d番目にあります。\n",ky,idx+1);
        }
        return 0;
}

配列の先頭から順になぞっていき、目的とするものと同じ値をもつ要素をみつける一連の手続きを遂次探索という。

関数に配列を受け渡す

#include<stdio.h> 
#define NUMBER 5 
 
int max_of(int vc[],int no){ 
        int i; 
        int max = vc[0]; 
        for(i=1;i<no;i++){ 
                if(vc[i] > max){ 
                        max = vc[i]; 
                } 
        } 
        return max; 
} 
 
int main(void){ 
        int i; 
        int eng[NUMBER]; 
        int mat[NUMBER]; 
        int max_e,max_m; 
 
        printf("%d人の点数を入力してください。\n",NUMBER); 
        for(i=0;i<NUMBER;i++){ 
                do{ 
                        printf("[%d] 英語:",i+1); scanf("%d",&eng[i]); 
                        if(eng[i] < 0 || eng[i] > 100){ 
                                puts("点数は0以上100以下で入力してください。"); 
                        } 
                }while(eng[i] < 0 || eng[i] > 100); 
                do{ 
                        printf("     数学:");     scanf("%d",&mat[i]); 
                        if(mat[i] < 0 || mat[i] > 100){ 
                                puts("点数は0以上100以下で入力してください。"); 
                        } 
                }while(mat[i] < 0 || mat[i] > 100); 
        } 
        max_e = max_of(eng,NUMBER); 
        max_m = max_of(mat,NUMBER); 
 
        printf("英語の最高点=%d\n",max_e); 
        printf("数学の最高点=%d\n",max_m); 
 
        return 0; 
} 

復習

最高点を求めるプログラム

#include<stdio.h>
#define NUMBER 5

int tensu[NUMBER];
int top(void);

int main(void){
        extern int tensu[];
        int i;

        printf("%d人の点数を入力してください。",NUMBER);
        for(i=0;i<NUMBER;i++){
                do{
                        printf("%d:",i+1);
                        scanf("%d",&tensu[i]);
                        if(tensu[i] < 0 || tensu[i] > 100 ){
                                printf("点数は0以上100以下で入力してください。");
                        }
                }while(tensu[i] < 0 || tensu[i] > 100);
        }
        printf("最高点=%d\n",top());
        return 0;
}

int top(void){
        extern int tensu[];
        int i;
        int max = tensu[0];
        for(i=1;i<NUMBER;i++){
                if(tensu[i] > max){
                        max = tensu[i];
                }
        }
        return max;
}

文字列を操作する

文字列の長さを調べる

#include<stdio.h>

unsigned str_length(const char str[]){
        unsigned len = 0;

        while(str[len]){
                len++;
        }   
        return len;
}

int main(void){
        char st[100];

        printf("文字列を入力してください。");
        scanf("%s",st);
        printf("文字列の長さは%uです。\n",str_length(st));

        return 0;
}