C言語サンプル集

プログラミングを学ぶ最良の方法はたくさんのコードを書くことです。これらの小さなプログラムはそれぞれ異なるスキルに焦点を当てています——興味のあるものを選んで練習してください。

九九表

C
#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= i; j++) {
            printf("%d*%d=%-4d", j, i, i * j);
        }
        printf("\n");
    }
    return 0;
}
TEXT
1*1=1
1*2=2   2*2=4
1*3=3   2*3=6   3*3=9
1*4=4   2*4=8   3*4=12  4*4=16
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81

素数判定

C
#include <stdio.h>
#include <math.h>

int is_prime(int n) {
    if (n < 2) return 0;
    if (n == 2) return 1;
    if (n % 2 == 0) return 0;
    for (int i = 3; i <= (int)sqrt(n); i += 2) {
        if (n % i == 0) return 0;
    }
    return 1;
}

int main(void) {
    int start = 2, end = 100;
    printf("%dから%dまでの素数:\n", start, end);
    int count = 0;
    for (int i = start; i <= end; i++) {
        if (is_prime(i)) {
            printf("%4d", i);
            count++;
            if (count % 10 == 0) printf("\n");
        }
    }
    if (count % 10 != 0) printf("\n");
    printf("合計: %d個の素数\n", count);
    return 0;
}
TEXT
2から100までの素数:
   2   3   5   7  11  13  17  19  23  29
  31  37  41  43  47  53  59  61  67  71
  73  79  83  89  97
合計: 25個の素数

ファイルコピー

C
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "使い方: %s コピー元 コピー先\n", argv[0]);
        return 1;
    }

    FILE *src = fopen(argv[1], "rb");
    if (src == NULL) {
        perror("コピー元ファイルを開けません");
        return 1;
    }

    FILE *dst = fopen(argv[2], "wb");
    if (dst == NULL) {
        perror("コピー先ファイルを作成できません");
        fclose(src);
        return 1;
    }

    char buf[4096];
    size_t bytes;
    while ((bytes = fread(buf, 1, sizeof(buf), src)) > 0) {
        fwrite(buf, 1, bytes, dst);
    }

    fclose(src);
    fclose(dst);
    printf("コピー完了\n");
    return 0;
}

文字列の反転

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

void str_reverse(char *str) {
    int len = strlen(str);
    for (int i = 0; i < len / 2; i++) {
        char tmp = str[i];
        str[i] = str[len - 1 - i];
        str[len - 1 - i] = tmp;
    }
}

int main(void) {
    char str1[] = "Hello, World!";
    str_reverse(str1);
    printf("%s\n", str1);

    char str2[] = "ABCDEF";
    str_reverse(str2);
    printf("%s\n", str2);

    return 0;
}
TEXT
!dlroW ,olleH
FEDCBA

フィボナッチ数列

C
#include <stdio.h>

long fibonacci(int n) {
    if (n <= 0) return 0;
    if (n == 1) return 1;

    long a = 0, b = 1;
    for (int i = 2; i <= n; i++) {
        long next = a + b;
        a = b;
        b = next;
    }
    return b;
}

int main(void) {
    for (int i = 0; i <= 20; i++) {
        printf("F(%d) = %ld\n", i, fibonacci(i));
    }
    return 0;
}
TEXT
F(0) = 0
F(1) = 1
F(2) = 1
F(3) = 2
F(4) = 3
F(5) = 5
...
F(20) = 6765

バブルソート

C
#include <stdio.h>

void bubble_sort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int swapped = 0;
        for (int j = 0; j < n - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
                swapped = 1;
            }
        }
        if (!swapped) break;
    }
}

int main(void) {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("ソート前: ");
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");

    bubble_sort(arr, n);

    printf("ソート後:  ");
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");

    return 0;
}
TEXT
ソート前: 64 34 25 12 22 11 90
ソート後:  11 12 22 25 34 64 90

数当てゲーム

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

int main(void) {
    srand((unsigned int)time(NULL));
    int target = rand() % 100 + 1;
    int guess, attempts = 0;

    printf("1から100までの数を当ててください\n");

    while (1) {
        printf("あなたの推測: ");
        if (scanf("%d", &guess) != 1) {
            printf("有効な数値を入力してください\n");
            while (getchar() != '\n');
            continue;
        }
        attempts++;

        if (guess < target) {
            printf("もっと大きいです!\n");
        } else if (guess > target) {
            printf("もっと小さいです!\n");
        } else {
            printf("おめでとう!%d回で当たりました!\n", attempts);
            break;
        }
    }

    return 0;
}

学生成績管理

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

typedef struct {
    char name[32];
    int id;
    float scores[3];
    float average;
} Student;

void calc_average(Student *s) {
    s->average = (s->scores[0] + s->scores[1] + s->scores[2]) / 3.0f;
}

void print_student(const Student *s) {
    printf("%-20s %4d  %6.1f  %6.1f  %6.1f  %6.1f\n",
           s->name, s->id,
           s->scores[0], s->scores[1], s->scores[2],
           s->average);
}

int cmp_by_average(const void *a, const void *b) {
    float diff = ((const Student *)a)->average - ((const Student *)b)->average;
    return (diff > 0) ? -1 : ((diff < 0) ? 1 : 0);
}

int main(void) {
    Student students[] = {
        {"Alice", 101, {85, 90, 78}, 0},
        {"Bob", 102, {92, 88, 95}, 0},
        {"Carol", 103, {76, 82, 70}, 0},
        {"Diana", 104, {98, 95, 92}, 0}
    };
    int n = sizeof(students) / sizeof(students[0]);

    for (int i = 0; i < n; i++) {
        calc_average(&students[i]);
    }

    printf("%-20s %4s  %6s  %6s  %6s  %6s\n",
           "名前", "ID", "国語", "数学", "英語", "平均");
    printf("------------------------------------------------------\n");
    for (int i = 0; i < n; i++) {
        print_student(&students[i]);
    }

    qsort(students, n, sizeof(Student), cmp_by_average);
    printf("\n平均順:\n");
    printf("%-20s %4s  %6s\n", "名前", "ID", "平均");
    printf("------------------------------------\n");
    for (int i = 0; i < n; i++) {
        printf("%-20s %4d  %6.1f\n",
               students[i].name, students[i].id, students[i].average);
    }

    return 0;
}
TEXT
名前                 ID    国語    数学     英語     平均
------------------------------------------------------
Alice                 101    85.0    90.0    78.0    84.3
Bob                   102    92.0    88.0    95.0    91.7
Carol                 103    76.0    82.0    70.0    76.0
Diana                 104    98.0    95.0    92.0    95.0

平均順:
名前                 ID  平均
------------------------------------
Diana                 104    95.0
Bob                   102    91.7
Alice                 101    84.3
Carol                 103    76.0

単語カウント

C
#include <stdio.h>
#include <ctype.h>

int main(void) {
    int ch;
    int chars = 0, words = 0, lines = 0;
    int in_word = 0;

    while ((ch = getchar()) != EOF) {
        chars++;
        if (ch == '\n') {
            lines++;
        }
        if (isspace(ch)) {
            in_word = 0;
        } else {
            if (!in_word) {
                words++;
                in_word = 1;
            }
        }
    }

    printf("文字数: %d\n", chars);
    printf("単語数: %d\n", words);
    printf("行数: %d\n", lines);
    return 0;
}

基数変換

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

void to_binary(unsigned int n, char *buf, int size) {
    buf[size - 1] = '\0';
    for (int i = size - 2; i >= 0; i--) {
        buf[i] = (n & 1) + '0';
        n >>= 1;
    }
}

void to_hex(unsigned int n, char *buf, int size) {
    const char digits[] = "0123456789ABCDEF";
    buf[size - 1] = '\0';
    for (int i = size - 2; i >= 0; i--) {
        buf[i] = digits[n & 0xF];
        n >>= 4;
    }
}

int main(void) {
    unsigned int values[] = {42, 255, 1024, 65535};
    int count = sizeof(values) / sizeof(values[0]);

    printf("%-10s %-34s %-10s\n", "10進数", "2進数", "16進数");
    printf("----------------------------------------------------\n");

    for (int i = 0; i < count; i++) {
        char bin[33], hex[9];
        to_binary(values[i], bin, sizeof(bin));
        to_hex(values[i], hex, sizeof(hex));
        printf("%-10u %-34s 0x%s\n", values[i], bin, hex);
    }

    return 0;
}
TEXT
10進数     2進数                            16進数
----------------------------------------------------
42         00000000000000000000000000101010  0x2A
255        00000000000000000000000011111111  0xFF
1024       00000000000000000000010000000000  0x400
65535      00000000000000001111111111111111  0xFFFF

簡易計算機

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

int main(void) {
    double a, b, result;
    char op;

    printf("式を入力してください(例:3 + 5): ");
    if (scanf("%lf %c %lf", &a, &op, &b) != 3) {
        printf("入力形式が無効です\n");
        return 1;
    }

    switch (op) {
    case '+': result = a + b; break;
    case '-': result = a - b; break;
    case '*': result = a * b; break;
    case '/':
        if (b == 0) {
            printf("エラー: ゼロ除算\n");
            return 1;
        }
        result = a / b;
        break;
    case '%':
        if ((int)b == 0) {
            printf("エラー: ゼロ剰余\n");
            return 1;
        }
        result = (int)a % (int)b;
        break;
    default:
        printf("未対応の演算子: %c\n", op);
        return 1;
    }

    printf("%.2f %c %.2f = %.2f\n", a, op, b, result);
    return 0;
}

回文判定

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

int is_palindrome(const char *str) {
    int left = 0;
    int right = strlen(str) - 1;

    while (left < right) {
        while (left < right && !isalnum((unsigned char)str[left])) left++;
        while (left < right && !isalnum((unsigned char)str[right])) right--;

        if (tolower((unsigned char)str[left]) != tolower((unsigned char)str[right])) {
            return 0;
        }
        left++;
        right--;
    }
    return 1;
}

int main(void) {
    const char *tests[] = {
        "racecar",
        "A man a plan a canal Panama",
        "hello",
        "12321",
        "Was it a car or a cat I saw"
    };
    int n = sizeof(tests) / sizeof(tests[0]);

    for (int i = 0; i < n; i++) {
        printf("\"%s\" -> %s\n", tests[i],
               is_palindrome(tests[i]) ? "回文です" : "回文ではありません");
    }

    return 0;
}
TEXT
"racecar" -> 回文です
"A man a plan a canal Panama" -> 回文です
"hello" -> 回文ではありません
"12321" -> 回文です
"Was it a car or a cat I saw" -> 回文です

行列の乗算

C
#include <stdio.h>

void matrix_multiply(int A[2][3], int B[3][2], int C[2][2]) {
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            C[i][j] = 0;
            for (int k = 0; k < 3; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

void print_matrix_2x3(int m[2][3]) {
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%4d", m[i][j]);
        }
        printf("\n");
    }
}

void print_matrix_3x2(int m[3][2]) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 2; j++) {
            printf("%4d", m[i][j]);
        }
        printf("\n");
    }
}

void print_matrix_2x2(int m[2][2]) {
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            printf("%4d", m[i][j]);
        }
        printf("\n");
    }
}

int main(void) {
    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int B[3][2] = {{7, 8}, {9, 10}, {11, 12}};
    int C[2][2];

    printf("行列 A (2x3):\n");
    print_matrix_2x3(A);
    printf("行列 B (3x2):\n");
    print_matrix_3x2(B);

    matrix_multiply(A, B, C);
    printf("A x B (2x2):\n");
    print_matrix_2x2(C);

    return 0;
}
TEXT
行列 A (2x3):
   1   2   3
   4   5   6
行列 B (3x2):
   7   8
   9  10
  11  12
A x B (2x2):
  58  64
 139 154

二分探索

C
#include <stdio.h>

int binary_search(int arr[], int n, int target) {
    int left = 0, right = n - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

int main(void) {
    int arr[] = {2, 5, 8, 12, 16, 23, 38, 45, 56, 72, 91};
    int n = sizeof(arr) / sizeof(arr[0]);

    int targets[] = {23, 7, 72, 1};
    int m = sizeof(targets) / sizeof(targets[0]);

    for (int i = 0; i < m; i++) {
        int idx = binary_search(arr, n, targets[i]);
        if (idx >= 0) {
            printf("%dがインデックス%dで見つかりました\n", targets[i], idx);
        } else {
            printf("%dは見つかりませんでした\n", targets[i]);
        }
    }

    return 0;
}
TEXT
23がインデックス5で見つかりました
7は見つかりませんでした
72がインデックス9で見つかりました
1は見つかりませんでした

シーザー暗号

C
#include <stdio.h>

void caesar_encrypt(char *text, int shift) {
    for (int i = 0; text[i] != '\0'; i++) {
        if (text[i] >= 'A' && text[i] <= 'Z') {
            text[i] = 'A' + (text[i] - 'A' + shift) % 26;
        } else if (text[i] >= 'a' && text[i] <= 'z') {
            text[i] = 'a' + (text[i] - 'a' + shift) % 26;
        }
    }
}

void caesar_decrypt(char *text, int shift) {
    caesar_encrypt(text, 26 - shift % 26);
}

int main(void) {
    char msg[] = "Hello World!";
    int shift = 3;

    printf("原文: %s\n", msg);
    caesar_encrypt(msg, shift);
    printf("暗号化: %s\n", msg);
    caesar_decrypt(msg, shift);
    printf("復号化: %s\n", msg);

    return 0;
}
TEXT
原文: Hello World!
暗号化: Khoor Zruog!
復号化: Hello World!
100%