大学課題レベルの実践問題を全39問収録。難易度フィルター・ヒント・解答コード付きで自主学習・試験対策に最適です。
% 演算子で偶数・奇数を判定しましょう。n % 2 == 0、奇数: n % 2 != 0#include <stdio.h> int main(void) { int num; printf("学生番号を入力: "); scanf("%d", &num); if (num >= 1 && num <= 20) { printf("学生番号%dはAクラスです\n", num); } else if (num % 2 == 0) { printf("学生番号%dはAクラスです\n", num); } else { printf("学生番号%dはBクラスです\n", num); } return 0; }
a >= b && a >= c のようにAND演算子で組み合わせて最大値を判定します。#include <stdio.h> int main(void) { int a, b, c; printf("a = "); scanf("%d", &a); printf("b = "); scanf("%d", &b); printf("c = "); scanf("%d", &c); printf("入力値: a=%d, b=%d, c=%d\n", a, b, c); if (a >= b && a >= c) { printf("最大値は %d です\n", a); } else if (b >= a && b >= c) { printf("最大値は %d です\n", b); } else { printf("最大値は %d です\n", c); } return 0; }
a / b(整数除算)、余り: a % b。偶数奇数は n % 2 で判定。#include <stdio.h> int main(void) { int a, b; printf("a = "); scanf("%d", &a); printf("b = "); scanf("%d", &b); printf("aは%sです\n", a % 2 == 0 ? "偶数" : "奇数"); printf("bは%sです\n", b % 2 == 0 ? "偶数" : "奇数"); printf("%d / %d = 商%d, 余り%d\n", a, b, a / b, a % b); return 0; }
for(i=1; i<=9; i++)、内側 for(j=1; j<=9; j++)。桁揃えに %2d や %3d を使います。#include <stdio.h> int main(void) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= 9; j++) { printf("%3d", i * j); } printf("\n"); } return 0; }
{88, 72, 95, 55, 63} の中から最小の値とそのインデックスを見つけて表示するプログラムを作成せよ。min_idx を用意し、ループで比較していきます。初期値は 0 にします。#include <stdio.h> int main(void) { int d[] = {88, 72, 95, 55, 63}; int n = 5, min_idx = 0; for (int i = 1; i < n; i++) { if (d[i] < d[min_idx]) min_idx = i; } printf("minimum is d[%d]: %d\n", min_idx, d[min_idx]); return 0; }
'\0'。strlen(str) で長さを取得し、最後の文字(index = len-1)から先頭(index = 0)に向かって1文字ずつ表示します。#include <stdio.h> #include <string.h> int main(void) { char str[128]; printf("文字列を入力してください: "); scanf("%s", str); int len = strlen(str); printf("文字列の逆順は "); for (int i = len - 1; i >= 0; i--) { printf("%c", str[i]); } printf(" です\n"); return 0; }
* で四角の枠を描き、対角線の位置に + を表示するプログラムを作成せよ。内部は空白にする。#include <stdio.h> int main(void) { int w, h; printf("幅: "); scanf("%d", &w); printf("高さ: "); scanf("%d", &h); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (i == 0 || i == h-1 || j == 0 || j == w-1) printf("*"); else if (i == j || i + j == w - 1) printf("+"); else printf(" "); } printf("\n"); } return 0; }
disp_face 関数を作成し、呼び出すたびに (^_^) を表示するプログラムを作成せよ。main関数で3回呼び出し、(^_^)(^_^)(^_^) と表示する。void disp_face(void) を定義し、中で printf("(^_^)") するだけです。#include <stdio.h> void disp_face(void) { printf("(^_^)"); } int main(void) { disp_face(); disp_face(); disp_face(); printf("\n"); return 0; }
area_rectangle 関数を関数プロトタイプ宣言を用いて定義せよ。int area_rectangle(int h, int w); を main の前に書きます。関数本体は main の後に書きます。#include <stdio.h> int area_rectangle(int h, int w); // プロトタイプ宣言 int main(void) { int h, w; printf("たて: "); scanf("%d", &h); printf("よこ: "); scanf("%d", &w); printf("面積は %d です\n", area_rectangle(h, w)); return 0; } int area_rectangle(int h, int w) { return h * w; }
lcm を作成せよ。LCM = a * b / GCD で計算する。while(b != 0) { tmp = b; b = a % b; a = tmp; } 最後の a が GCD。#include <stdio.h> int gcd(int a, int b) { while (b != 0) { int tmp = b; b = a % b; a = tmp; } return a; } int lcm(int a, int b) { return a / gcd(a, b) * b; } int main(void) { int a, b; printf("a = "); scanf("%d", &a); printf("b = "); scanf("%d", &b); printf("最小公倍数は %d です\n", lcm(a, b)); return 0; }
VALUE を 50 としてマクロ定義SUM(a,b) を定義50+50=100 と表示する#define VALUE 50 と #define SUM(a,b) ((a)+(b)) を定義します。マクロ関数では引数をカッコで囲むのが安全です。#include <stdio.h> #define VALUE 50 #define SUM(a, b) ((a) + (b)) int main(void) { printf("%d+%d=%d\n", VALUE, VALUE, SUM(VALUE, VALUE)); return 0; }
void ascend(int arr[], int n) 関数として実装すること。バブルソートを使う。tmp = a[j-1]; a[j-1] = a[j]; a[j] = tmp;#include <stdio.h> void ascend(int arr[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = n - 1; j > i; j--) { if (arr[j - 1] > arr[j]) { int tmp = arr[j - 1]; arr[j - 1] = arr[j]; arr[j] = tmp; } } } printf("昇順ソート: "); for (int i = 0; i < n; i++) { printf("%d", arr[i]); if (i < n - 1) printf(", "); } printf("\n"); } int main(void) { int data[5]; for (int i = 0; i < 5; i++) { printf("入力%d: ", i + 1); scanf("%d", &data[i]); } ascend(data, 5); return 0; }
val(初期値0)と n を宣言input(): キーボードから整数を入力し n に代入addition(): val に n を加算product(): val を n 倍display(): val の値を表示while(sw != -1) でループし、switch(sw) で分岐。各case内で input → addition/product → display の順に呼び出します。#include <stdio.h> int val = 0; int n; void input(void) { printf("値を入力してください> "); scanf("%d", &n); } void display(void) { printf("valの値は%dになりました\n", val); } void addition(void) { val += n; } void product(void) { val *= n; } int main(void) { int sw = 0; while (sw != -1) { printf("1: 加算 2:乗算 -1:終了> "); scanf("%d", &sw); switch (sw) { case 1: input(); addition(); display(); break; case 2: input(); product(); display(); break; } } return 0; }
draw_graph 関数で棒グラフを描画するプログラムを作成せよ。* を表示し、目盛り位置には = を表示j % interval == 0 && j != 0 なら =、それ以外は * を表示します。#include <stdio.h> void draw_graph(int id, int sales); int interval = 5; // グローバル: 目盛り間隔 int main(void) { int data[] = {12, 8, 20}; int n = 3; for (int i = 0; i < n; i++) draw_graph(i + 1, data[i]); return 0; } void draw_graph(int id, int sales) { printf("商品%d (%2d): ", id, sales); for (int j = 1; j <= sales; j++) { if (j % interval == 0) printf("="); else printf("*"); } printf("\n"); }
printf("%5.1f", val) で全体5桁・小数点以下1桁の右寄せ表示ができます。#include <stdio.h> int main(void) { double w1, w2; printf("重さ1: "); scanf("%lf", &w1); printf("重さ2: "); scanf("%lf", &w2); printf("重さ1 = %5.1f kg\n", w1); printf("重さ2 = %5.1f kg\n", w2); printf("合計 = %5.1f kg\n", w1 + w2); printf("差 = %5.1f kg\n", w1 > w2 ? w1 - w2 : w2 - w1); return 0; }
f(x,y,z) = x*x + 2*x*y + y*y*z の値を計算して表示するプログラムを作成せよ。scanf("%lf", &x) で読み込みます。計算式をそのまま書けばOKです。#include <stdio.h> int main(void) { double x, y, z; printf("x: "); scanf("%lf", &x); printf("y: "); scanf("%lf", &y); printf("z: "); scanf("%lf", &z); double result = x*x + 2*x*y + y*y*z; printf("f(x,y,z) = %f\n", result); return 0; }
int *pa, int *pb にし、一時変数 tmp を使って *pa と *pb を交換します。呼び出し側は swap(&a, &b)。#include <stdio.h> void swap(int *pa, int *pb) { int tmp = *pa; *pa = *pb; *pb = tmp; } int main(void) { int a, b; printf("a = "); scanf("%d", &a); printf("b = "); scanf("%d", &b); printf("交換前: a=%d, b=%d\n", a, b); swap(&a, &b); printf("交換後: a=%d, b=%d\n", a, b); return 0; }
void calc(int *arr, int n, int *sum, double *avg) として実装する。*sum = 0; で初期化し、ループで *sum += arr[i]; 、最後に *avg = (double)*sum / n;。#include <stdio.h> void calc(int *arr, int n, int *sum, double *avg) { *sum = 0; for (int i = 0; i < n; i++) *sum += arr[i]; *avg = (double)*sum / n; } int main(void) { int data[] = {10, 20, 30, 40, 50}; int sum; double avg; calc(data, 5, &sum, &avg); printf("合計: %d\n", sum); printf("平均: %.1f\n", avg); return 0; }
to_upper(char *s) を作成せよ。'a' <= *s && *s <= 'z' なら *s -= 32;(ASCIIコードで大文字と小文字の差は32)。while(*s) でヌル終端まで走査。fgets を使います。#include <stdio.h> #include <string.h> void to_upper(char *s) { while (*s) { if (*s >= 'a' && *s <= 'z') *s -= 32; s++; } } int main(void) { char str[128]; printf("入力: "); fgets(str, 128, stdin); str[strcspn(str, "\n")] = '\0'; to_upper(str); printf("変換後: %s\n", str); return 0; }
Student を定義し、3人分のデータを入力して最高得点の学生を表示するプログラムを作成せよ。struct Student { char name[20]; int score; }; を定義し、配列で3人分確保。ループで最大スコアのインデックスを探します。#include <stdio.h> struct Student { char name[20]; int score; }; int main(void) { struct Student s[3]; for (int i = 0; i < 3; i++) { printf("学生%d 名前: ", i+1); scanf("%s", s[i].name); printf(" 点数: "); scanf("%d", &s[i].score); } int max = 0; for (int i = 1; i < 3; i++) if (s[i].score > s[max].score) max = i; printf("最高得点: %s (%d点)\n", s[max].name, s[max].score); return 0; }
Point を定義し、2点を入力して2点間の距離を計算する関数 double distance(Point p1, Point p2) を作成せよ。sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))。math.h の sqrt を使います。コンパイル時に -lm オプションが必要な場合があります。#include <stdio.h> #include <math.h> struct Point { double x, y; }; double distance(struct Point p1, struct Point p2) { double dx = p2.x - p1.x, dy = p2.y - p1.y; return sqrt(dx*dx + dy*dy); } int main(void) { struct Point p1, p2; printf("点1 x: "); scanf("%lf", &p1.x); printf(" y: "); scanf("%lf", &p1.y); printf("点2 x: "); scanf("%lf", &p2.x); printf(" y: "); scanf("%lf", &p2.y); printf("距離: %.3f\n", distance(p1, p2)); return 0; }
int *data = (int *)malloc(sizeof(int) * n); で確保。NULLチェックも忘れずに。使い終わったら free(data);。#include <stdio.h> #include <stdlib.h> int main(void) { int n; printf("要素数: "); scanf("%d", &n); int *data = (int *)malloc(sizeof(int) * n); if (data == NULL) { printf("メモリ確保失敗\n"); return 1; } int sum = 0; for (int i = 0; i < n; i++) { printf("data[%d] = ", i); scanf("%d", &data[i]); sum += data[i]; } printf("合計: %d, 平均: %.1f\n", sum, (double)sum / n); free(data); return 0; }
fopen("scores.txt", "w") → fprintf → fclose。fopen("scores.txt", "r") → fscanf を EOF まで繰り返す → fclose。#include <stdio.h> int main(void) { char names[3][20]; int scores[3]; for (int i = 0; i < 3; i++) { printf("名前%d: ", i+1); scanf("%s", names[i]); printf(" 点数: "); scanf("%d", &scores[i]); } // 書き込み FILE *fp = fopen("scores.txt", "w"); for (int i = 0; i < 3; i++) fprintf(fp, "%s %d\n", names[i], scores[i]); fclose(fp); // 読み込み printf("--- scores.txt の内容 ---\n"); fp = fopen("scores.txt", "r"); char n[20]; int s; while (fscanf(fp, "%s %d", n, &s) != EOF) printf("%s %d\n", n, s); fclose(fp); return 0; }
* で直角三角形を描画するプログラムを作成せよ。* を i 個出力、最後に改行。#include <stdio.h> int main(void) { int n; printf("高さ: "); scanf("%d", &n); for (int i = 1; i <= n; i++) { for (int j = 0; j < i; j++) printf("*"); printf("\n"); } return 0; }
#、目盛り位置を +、それ以外を - で表示する grid 関数を作成せよ。i==0 || i==h-1 || j==0 || j==w-1 → #i%v_interval==0 && j%h_interval==0 → +-#include <stdio.h> void grid(int w, int h); int v_interval, h_interval; int main(void) { int w, h; printf("幅: "); scanf("%d", &w); printf("高さ: "); scanf("%d", &h); printf("間隔横: "); scanf("%d", &h_interval); printf("間隔縦: "); scanf("%d", &v_interval); grid(w, h); return 0; } void grid(int w, int h) { for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (i==0||i==h-1||j==0||j==w-1) printf("#"); else if (i%v_interval==0 && j%h_interval==0) printf("+"); else printf("-"); } printf("\n"); } }
int is_prime(int n) として実装する。math.h の sqrt を使うと効率的。#include <stdio.h> #include <math.h> int is_prime(int n) { if (n < 2) return 0; for (int i = 2; i <= (int)sqrt(n); i++) if (n % i == 0) return 0; return 1; } int main(void) { int n, count = 0; printf("n = "); scanf("%d", &n); for (int i = 2; i <= n; i++) { if (is_prime(i)) { printf("%d ", i); count++; } } printf("\n素数の個数: %d\n", count); return 0; }
add(int a, int b): 2つの整数の和を表示max(double a, double b, double c): 3つの実数の最大値を表示#include <stdio.h> void add(int a, int b) { printf("%d + %d = %d\n", a, b, a + b); } void max3(double a, double b, double c) { double m = a; if (b > m) m = b; if (c > m) m = c; printf("max(%.1f, %.1f, %.1f) = %.1f\n", a, b, c, m); } int main(void) { int x = 12, y = 25; double a = 23.5, b = 69.2, c = 10.3; add(x, y); max3(a, b, c); return 0; }
#include <stdio.h> void descend(int arr[], int n) { for (int i = 0; i < n - 1; i++) { int max_idx = i; for (int j = i + 1; j < n; j++) if (arr[j] > arr[max_idx]) max_idx = j; int tmp = arr[i]; arr[i] = arr[max_idx]; arr[max_idx] = tmp; } } int main(void) { int data[5]; for (int i = 0; i < 5; i++) { printf("入力%d: ", i+1); scanf("%d", &data[i]); } descend(data, 5); printf("降順ソート: "); for (int i = 0; i < 5; i++) { printf("%d", data[i]); if (i < 4) printf(", "); } printf("\n"); return 0; }
int power(int base, int exp) で累乗を計算するプログラムを作成せよ。ループは使わないこと。exp == 0 → 1を返す。再帰: base * power(base, exp - 1)。#include <stdio.h> int power(int base, int exp) { if (exp == 0) return 1; return base * power(base, exp - 1); } int main(void) { int b, e; printf("底: "); scanf("%d", &b); printf("指数: "); scanf("%d", &e); printf("%d^%d = %d\n", b, e, power(b, e)); return 0; }
mid = (low + high) / 2 で中央を見る。arr[mid] == target なら発見、arr[mid] < target なら low = mid + 1、そうでなければ high = mid - 1。#include <stdio.h> int binary_search(int arr[], int n, int target) { int low = 0, high = n - 1; while (low <= high) { int mid = (low + high) / 2; if (arr[mid] == target) return mid; else if (arr[mid] < target) low = mid + 1; else high = mid - 1; } return -1; } int main(void) { int data[] = {2,5,8,12,16,23,38,56,72,91}; int n = 10, target; printf("探す値: "); scanf("%d", &target); int idx = binary_search(data, n, target); if (idx >= 0) printf("data[%d] に見つかりました\n", idx); else printf("見つかりません\n"); return 0; }
【???】 部分を埋めて完成させる形式です。実際の試験を意識した出題です。#include <stdio.h> int main(void) { char c; printf("一文字入力> "); scanf("%c", 【???】); if (c=='a' || c=='e' || c=='i' || 【???】 || c=='u') { printf("「%c」は母音です\n", c); } else { printf("「%c」は【???】です\n", c); } return 0; }
&c(charのアドレスを渡す)c=='o'(残りの母音 o)子音#include <stdio.h> int main(void) { int sw; double x, y; printf("計算方法(1:+ 2:- 3:* 4:/)> "); scanf("%d", &sw); while (【???】) { printf("1-4を入力> "); scanf("%d", &sw); } printf("x = "); scanf("【???】", &x); printf("y = "); scanf("%lf", &y); switch (【???】) { case 1: printf("x + y = %f\n", x + y); break; case 2: printf("x - y = %f\n", x - y); break; case 3: printf("x * y = %f\n", x * y); break; case 4: printf("x / y = %f\n", 【???】); break; } return 0; }
sw < 1 || sw > 4(範囲外なら繰り返す)%lf(doubleの読み込み書式)sw(switchで分岐する変数)x / y(除算の計算式)#include <stdio.h> #define MAX 101 int length(char 【???】) { int len = 0; for (int i = 0; str[i] != 【???】; i++) { len++; } return 【???】; } int main(void) { char s1[MAX], s2[MAX]; printf("文字列1> "); scanf("%s", s1); printf("文字列2> "); scanf("%s", s2); int len1 = length(s1), len2 = length(s2); printf("%sは%d文字です\n", s1, len1); printf("%sは%d文字です\n", s2, len2); printf("合計は%d文字です\n", 【???】); if (len1 > len2) printf("%sの方が長いです\n", s1); else if (len2 > len1) printf("%sの方が長いです\n", s2); else printf("同じ長さです\n"); return 0; }
str[](配列を引数として受け取る)'\0'(ヌル終端文字)len(計算した文字数を返す)len1 + len2(合計文字数)#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int n, count[6] = {0}; printf("回数: "); scanf("%d", &n); srand((unsigned)time(NULL)); for (int i = 0; i < 【???】; i++) { int die = rand() % 【???】; // 0〜5 【???】; } for (int i = 0; i < 6; i++) { printf("%dの目: %d回 (%.1f%%)\n", i + 1, count[i], (double)【???】 / n * 100); } return 0; }
n(n回ループ)6(0〜5の乱数を生成)count[die]++(出た目のカウントをインクリメント)count[i](各目の出現回数をdoubleに変換)xn+1 = (a × xn + b) mod m に従って疑似乱数列を生成し、100個の値の平均と0.2以上0.4未満の出現割合を求めるプログラムの空欄を埋めよ。#include <stdio.h> int main(void) { int m = 65536, a = 717, b = 23, x = 1234; int i, count = 0; double y, sum = 0.0; for (i = 0; 【???】; i++) { x = (【???】) % m; y = (double)x / m; sum += 【???】; if (【???】) { count++; } printf("%1.3f ", y); if (【???】) { printf("\n"); } } printf("\n平均は%1.3fです\n", sum / i); printf("0.2以上0.4未満の値がでる割合は%1.3fです\n", (double)【???】); return 0; }
i < 100(100回ループ)a * x + b(線形合同法の漸化式)y(合計に y を加算)y >= 0.2 && y < 0.4(0.2以上0.4未満の判定)i % 10 == 9(10個ごとに改行)count / i(出現割合 = count ÷ 全個数)#include <stdio.h> void reverse_copy(int src[], int dst[], int n) { for (int i = 0; i < n; i++) { dst[i] = src[【???】]; } } int main(void) { int a[] = {1, 2, 3, 4, 5}; int b[5]; reverse_copy(a, b, 【???】); for (int i = 0; i < 5; i++) printf("%d ", b[i]); printf("\n"); // 出力: 5 4 3 2 1 return 0; }
n - 1 - i。n - 1 - i(逆順のインデックス計算)5(配列の要素数)#include <stdio.h> #define N 2 int main(void) { int A[N][N] = {{1,2},{3,4}}; int B[N][N] = {{5,6},{7,8}}; int C[N][N] = {0}; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < N; k++) { C[i][j] += 【???】; } } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) printf("C[%d][%d]=%d ", i, j, C[i][j]); printf("\n"); } return 0; }
A[i][k] * B[k][j]#include <stdio.h> void double_array(【???】 arr, int n) { for (int i = 0; i < n; i++) { 【???】 *= 2; } } int main(void) { int data[] = {3, 7, 1, 9}; double_array(data, 4); for (int i = 0; i < 4; i++) printf("%d ", data[i]); printf("\n"); // 出力: 6 14 2 18 return 0; }
int *(int型ポインタで配列を受け取る)arr[i] または *(arr + i)(ポインタ経由で要素にアクセス)#include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node *next; }; struct Node* insert_head(struct Node *head, int val) { struct Node *new_node = (struct Node*)malloc(【???】); new_node->data = 【???】; new_node->next = 【???】; return 【???】; } int main(void) { struct Node *list = NULL; list = insert_head(list, 30); list = insert_head(list, 20); list = insert_head(list, 10); struct Node *p = list; while (p != NULL) { printf("%d -> ", p->data); p = p->next; } printf("NULL\n"); // 出力: 10 -> 20 -> 30 -> NULL return 0; }
sizeof(struct Node)(ノード1つ分のメモリを確保)val(引数の値をdataに格納)head(元の先頭ノードを新ノードのnextに設定)new_node(新しい先頭ノードを返す)