C言語(応用編)演習問題

1日目

「1日目」演習問題

【問1】

以下の機能をもつプログラムを作成してみましょう
(1) int, float, double型の変数a, b, cを宣言し,それぞれに,1, 1.2, 1.23を代入する
(2) また変数a, b, cへのポインタ変数pa, pb, pcを宣言する
(3) (2)で宣言した変数を使い、a, b,cの値を表示するプログラムを作成してみましょう

実行結果
pa=1
pb=1.200000
pc=1.230000

【問2】

以下の機能をもつプログラムを作成してみましょう
(1) 2つの整数の値を入れ替える関数を実装する
(2) 長さ5の整数型の配列変数を用意し、1から100までの乱数を代入し、代入した値を表示する
(3) (2)で作成した配列を降順(大きい値の順番)に並び替える

実行結果
前:91 57 46 67 44
後:91 67 57 46 44

「1日目」解答例

【問1】

#include <stdio.h>

int main(void){
    int a = 1;
    float b = 1.2;
    double c = 1.23;
    int *pa = &a;
    float *pb = &b;
    double *pc = &c;

    printf("pa=%d\n",*pa);
    printf("pb=%f\n",*pb);
    printf("pc=%lf\n",*pc);

    return 0;

}

【問2】

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void swap(int *a,int *b){
    int tmp;

    tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(void){
    int ary[5];

    srand((unsigned)time(NULL)); // 乱数の種を現在時刻で初期化する
    printf("前:");
    for(int i=0;i<5;i++){
        ary[i]=rand()%100+1; 
        printf("%3d ",ary[i]);
    }
    printf("\n");

    for(int i=0;i<5;i++){
        for(int j=i+1;j<5;j++){
            if(ary[j]>ary[i]){
                swap(&ary[i],&ary[j]);
            }
        }
    }
    printf("後:");
    for(int i=0;i<5;i++){
        printf("%3d ",ary[i]);
    }
    printf("\n");
}

C言語応用編 1日目へ戻る

2日目

「2日目」演習問題

【問1】

以下の機能をもつプログラムを作成してみましょう
(1) 長さ10の整数型の配列xを宣言し,各要素に初期値として,0から9までの値を順に代入する
(2) 次に,(1)で作成した配列の各要素をポインタ変数を使って読み出し表示する

実行結果
*(pt+0)=0
*(pt+1)=1
*(pt+2)=2
*(pt+3)=3
*(pt+4)=4
*(pt+5)=5
*(pt+6)=6
*(pt+7)=7
*(pt+8)=8
*(pt+9)=9

「2日目」解答例

【問1】

#include <stdio.h>

int main(void){
    int x[10] = {0,1,2,3,4,5,6,7,8,9};
    int *pt = x;

    for(int i=0;i<10;i++){
        printf("*(pt+%d)=%d\n",i,*(pt+i));
    }
    return 0;
}

C言語応用編 2日目へ戻る

3日目

「3日目」演習問題

【問1】

標準入力から文字列を取得し、その文字列の長さを表示するプログラムを作成してみましょう
ただし、標準関数のstrlen()は使用しないこと
また、文字列の大きさは最大256byteとし、半角文字列のみ入力するものとする

【問2】

“lemon”,”grape”,”apple”,”orange”,”banana” の5個の文字列をポインタの配列を用いて宣言し、ASCIIコードで降順に並び替えて表示する

 実行結果
 1:orange
 2:lemon
 3:grape
 4:banana
 5:apple

【問3】

以下の機能をもつプログラムを作成してみましょう
(1) 標準入力により文字列を取得する
(2) 文字列srcを渡すとsrcを逆向きに並べた文字列destを作成してみましょう
関数は次のように作成してみましょう

void reverse(char src[], char dest[])

(3) (2)の関数を使用し(1)で取得した文字列の逆向きの文字列を取得し表示する
※文字列の大きさは最大256byteとし、半角文字列のみ入力するものとする

実行結果
文字列を入力してください:Hello!
逆順にした文字列:!olleH

「3日目」解答例

【問1】

#include <stdio.h>
#include <string.h>

int main(void){
    char str[256];
    int len;

    printf("文字列を入力してください:");
    scanf("%s",str);

    len = 0;
    while(str[len]!'\0'){
        len++;
    }
    printf("\n文字列の長さ=%d\n",len);
    printf("strlen=%d",strlen(str)); // strlen()を使用した場合を表示

    return 0;
}

【問2】

#include <stdio.h>
#include <string.h>

void array_sort(char array[5][10]){
	char tmp[10];
	
	for(int i=0;i<5;i++){
		for(int j=i+1;j<5;j++){
			if(strcmp(array[i],array[j])<0){
				strcpy(tmp,array[j]);
				strcpy(array[j],array[i]);
				strcpy(array[i],tmp);
			}
		}
	}
}

int main(void){
    char str[5][10]={
        "lemon","grape","apple","orange","banana" 
    };

    array_sort(str);
	  for(int i=0;i<5;i++){
		  printf("%d:%s\n",i+1,str[i]);
	  }

    return 0;
}

【問3】

#include <stdio.h>
#include <string.h>

void reverse(char str[],char dest[]){
    int len = strlen(str);

    for(int i=0;i<len;i++){
        dest[i] = str[(len-1)-i];
    }
    //末尾にNULLを指定
    dest[len] = '\0';
}

int main(void){
    char str[256];
    char dest[256];

    printf("文字列を入力してください:");
    scanf("%s",str);

    reverse(str,dest);

    printf("逆順にした文字列:%s\n",dest);
}

C言語応用編 3日目へ戻る

4日目

「4日目:構造体」演習問題

【問1】

以下のプログラムを構造体を使用したプログラムに改変してみましょう

    #include <stdio.h>
    #include <string.h>

    #define NUM 5

    int main(void){
      char name[NUM][256];
      int grade[NUM]; //学年(1から4)
      int gender[NUM]; // 性別 1:男性 2:女性

      strcpy(name[0],"Yamada Taro");
      strcpy(name[1],"Suzuki Ichiro");
      strcpy(name[2],"Sato Hanako");
      strcpy(name[3],"Takahashi Jiro");
      strcpy(name[4],"Tanaka Ume");

      grade[0]=1;
      grade[1]=2;
      grade[2]=3;
      grade[3]=4;
      grade[4]=1;

      gender[0]=1;
      gender[1]=1;
      gender[2]=2;
      gender[3]=1;
      gender[4]=2;

      for(int i=0;i<NUM;i++){
        printf("name:%s\n",name[i]);
        printf("grade:%d\n",grade[i]);
        switch(gender[i]){
            case 1:
              printf("gender:male\n");
              break;
            case 2:
                printf("gender:femail\n");
                break;
        }
      }
      return 0;
    }

【問2】

以下の機能をもつプログラムを作成してみましょう

下の表は令和6年1月から3月の新車登録・届出台数を示すものである

対象月 普通車 小型車 軽自動車 合計
1月 1306 500 1395
2月 1186 473 1203
3月 1481 526 1124

(1) 構造体を定義し、対象月、普通車、小型車、軽自動車、合計の値を代入できるようにする
(2) 作成した構造体の配列を変数として作成し、表のデータを初期値として設定する
(3) 各月の合計値を計算し値を代入する
(4) 普通車の台数が最も小さい月を探し出し表示する
(5) 軽自動車の最も多い月と台数を表示する

実行結果
各月の台数の合計
1月 3201
2月 2862
3月 3131
普通車の台数が最も少ない月:2
軽自動車の台数が最も多い月と台数:1,1395

「4日目:構造体」解答例

【問1】

#include <stdio.h>

#define NUM 5

typedef struct student{
    char name[256];
    int grade;  // 学年(1~4)
    int gender; // 性別 1:男性、2:女性
} STUDENT;

int main(void){
    STUDENT st[NUM]={
        {"Yamada Taro",1,1},
        {"Suzuki Ichiro",2,1},
        {"Sato Hanako",3,2},
        {"Takahashi Jiro",4,1},
        {"Tanaka Ume",1,2}
    };

    for(int i=0;i<NUM;i++){
        printf("name:%s\n",st[i].name);
        printf("grade:%d\n",st[i].grade);
        switch(st[i].gender){
            case 1:
              printf("gender:male\n");
              break;
            case 2:
                printf("gender:femail\n");
                break;
        }
    }
    
    return 0;
}

【問2】

#include <stdio.h>

typedef struct car_data{
    int month;
    int normal;
    int kogata;
    int kei;
    int total;
} CAR_DATA;

int main(void){
    CAR_DATA dt[3]={
        {1,1306,500,1395,0},
        {2,1186,473,1203,0},
        {3,1481,526,1124,0}
    };
    int min,max;
    int min_month;
    int max_month;
    min = 9999;

    max = 0;
    printf("各月の台数の合計\n");
    for(int i=0;i<3;i++){
        dt[i].total = dt[i].normal + dt[i].kogata + dt[i].kei;
        printf("%d月 %d\n",dt[i].month, dt[i].total);

        if(dt[i].normal < min){
            min = dt[i].normal;
            min_month = dt[i].month;
        }

        if(dt[i].kei > max){
            max = dt[i].kei;
            max_month = dt[i].month;
        }
    }
    printf("普通車の台数が最も少ない月:%d\n",min_month);
    printf("軽自動車の最も多い月と台数:%d月,%d\n",max_month,max);
    return 0;
}

C言語応用編 4日目へ戻る

「4日目:共用体」演習問題

【問1】

以下の機能をもつプログラムを作成してみましょう
(1) 以下の共用体を宣言する
union test1{ char c; int i; double d; char s[8+1]; };
(2) すべてのメンバの値を表示する関数を作成してみましょう
void print_member(union test1 *dt);
(3) 各メンバに値を代入し、すべてのメンバの値を表示する

実行結果
(1) dt.cに'C'を代入
dt.c=C
dt.i=-289898941
dt.d=0.000000
dt.s=
(2) dt.iに'5'を代入
dt.c=
dt.i=5
dt.d=0.000000
dt.s=
(3) dt.dに'3.14'を代入
dt.c=
dt.i=1374389535
dt.d=3.140000
dt.s=
(4) dt.sに'Hello!'を代入
dt.c=H
dt.i=1819043144
dt.d=2.016326
dt.s=Hello!

【問2】

以下の機能をもつプログラムを作成してみましょう
(1) 「幅」と「高さ」のペアを、int型、あるいは float型で管理できるような共用体を作成してみましょう
hint
・共用体のメンバはint型、double型それぞれで幅、高さを保持する構造体で定義する
(2) 共用体の変数を宣言する
(3) 幅と高さから面積を計算する関数を作成してみましょう
int area_i(int width, int height); double area_d(double width, double height);
(4) int型、double型それぞれに値を代入し、それぞれの面積を表示する

実行結果
整数値で幅、高さを入力:4,5
幅:4,高さ5の面積は20
小数値で幅、高さを入力:11.25,3.5
幅:11.250000,高さ3.500000の面積は39.375000

「4日目:共用体」解答例

【問1】

#include <stdio.h>
#include <string.h>

 union test1{
    char c;
    int  i;
    double d;
    char s[8+1];
  };

  void print_member(union test1 *dt){
    printf("dt.c=%c\n",dt->c);
    printf("dt.i=%d\n",dt->i);
    printf("dt.d=%f\n",dt->d);
    printf("dt.s=%s\n",dt->s);
  }

  int main(void){
    union test1 tst;

    tst.c='C';
    print_member(&tst);

    tst.i=5;
    print_member(&tst);

    tst.d=3.14;
    print_member(&tst);

    strcpy(tst.s,"Hello!");
    print_member(&tst);
  } 

【問2】

#include <stdio.h>
#include <string.h>

 union area{
    struct {
        int width;
        int height;
    } area_int;
    struct {
        double width;
        double height;
    } area_float;
 };

 int area_i(int width,int height){
    return width * height;
 }

 double area_d(double width,double height){
    return width * height;
 }

 int main(void){
    union area dt;
   
    printf("整数値で幅、高さを入力:");
    scanf("%d,%d",&dt.area_int.width,&dt.area_int.height);
    printf("幅:%d、高さ:%dの面積は%d\n",dt.area_int.width,dt.area_int.height,area_i(dt.area_int.width,dt.area_int.height));

    printf("小数値で幅、高さを入力:");
    scanf("%lf,%lf",&dt.area_float.width,&dt.area_float.height);
    printf("幅:%lf、高さ:%lfの面積は%lf\n",dt.area_float.width,dt.area_float.height,area_d(dt.area_float.width,dt.area_float.height));
 }

C言語応用編 4日目へ戻る

5日目

「5日目」演習問題

【問1】

hello.txtファイルにHello World Cと書き出すプログラムを作成してみましょう

【問2】

以下の機能をもつプログラムを作成してみましょう
(1) one,two,three,four,five,six,seven,nine,tenと記述したfile1.txtを用意する
(2) (1)で用意したファイルを読み込む
(3) (2)で読み込んだ文字列を1文字1文字走査し出力する。その際、カンマが出現したら改行する
※C言語ではstrtok()が存在しますが、strtok()は使用せずに作成してみましょう

実行結果
one
two
three
four
five
six
seven
nine
ten

【問3】

以下の機能をもつプログラムを作成してみましょう
(1) 次の構造体を定義し値を初期化します

typedef struct student{
    char number[10]; // 学籍番号
    int grade;       // 学年
    int gender;      // 性別 1:男性 2:女性
} STUDENT;

値は以下の表のように定義します

学籍番号 学年 性別
10001 1 1
10002 2 1
10003 2 2
10004 3 2
10005 4 2

(2) 保持したデータの学年を1学年あげたデータをファイルにCSV形式で出力する
※ただし、4年⽣の場合は出力しない

実行結果
file3.csv
10001,2,1
10002,3,1
10003,3,2
10004,4,2

「5日目」解答例

【問1】

#include <stdio.h>

int main(void){
	FILE *fp;
	errno_t err;
	char s[256];
	
	err = fopen_s(&fp, "hello.txt","w");
	if (err !0){
    		printf("ファイルオープンに失敗しました");
    		return 1;
 	}

	fputs("Hello World C",fp);

	fclose(fp);
	return 0;
}

【問2】

#include <stdio.h>

int main(void){
    FILE *fp;
    errno_t err;
    char s[256];

	err = fopen_s(&fp, "file1.txt","r");
	if (err !0){
    		printf("ファイルオープンに失敗しました");
    		return 1;
 	}

	while( fgets(s,sizeof(s),fp) !NULL){
        int i=0;
        while(s[i]!'\0'){
            if(s[i]==','){
                printf("\n");
            }else{
                printf("%c",s[i]);
            }
            i++;
        }
    }
    return 0;
}

【問3】

include <stdio.h>

typedef struct student{
    char number[10];  // 学籍番号
    int grade; // 学年
    int gender; // 性別 1:男性 2:女性
} STUDENT;

int main(void){
    FILE *fp;
    errno_t err;
    char s[256];
    STUDENT st[5]={
        {"10001",1,1},
        {"10002",2,1},
        {"10003",2,2},
        {"10004",3,2},
        {"10005",4,2}
    };
    int cnt;

    err = fopen_s(&fp,"file3.csv","w");
    if(err !0){
        printf("ファイルオープンに失敗しました");
        return 1;
    }

    for(int i=0;i<5;i++){
        int grade = st[i].grade + 1;
        if (grade > 4) continue;

        fprintf(fp,"%s,%d,%d\n",st[i].number,grade,st[i].gender);
    }
    
    fclose(fp);
}

C言語応用編 5日目へ戻る

6日目

応用編 6日目に提示しているソースを実行してみましょう

7日目

「7日目」演習問題

【問1】

16進数の0x12345678から8の部分だけを取り出して出力してみましょう

【問2】

16進数の0x1234を左に0,4,8,12,16ビットシフトした結果を表示してみましょう

「7日目」解答例

【問1】

#include <stdio.h>

int main(void){
    unsigned int x = 0x12345678;
    unsigned int mask = 0x0000000f;
    printf("%x -> %08x\n",x,x & mask);
}
実行結果
12345678 -> 00000008

【問2】

#include <stdio.h>

int main(void){
    unsigned int x = 0x1234;
    for(int i=0;i<16;i+=4){
        printf("%016x\n",x<<i);
    }
}
実行結果
0000000000001234
0000000000012340
0000000000123400
0000000001234000
0000000012340000

コメント

この記事へのコメントはありません。

関連記事

Java 応用編 5日目

C言語でデータ制御 後編

Java 応用編 4日目

PAGE TOP