C 言語における配列の操作

CCBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、C プログラミングにおける配列の扱い方を学びます。この実験では、配列宣言、初期化、アクセス、および反復処理の基本概念が扱われます。まず、配列宣言の構文を紹介し、次に整数型の配列を値で初期化し、インデックスを使って配列要素にアクセスし、最後に for ループで要素を表示します。この実験が終了するとき、C 言語における配列の操作について十分な理解を得ることができます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("C")) -.-> c/BasicsGroup(["Basics"]) c(("C")) -.-> c/ControlFlowGroup(["Control Flow"]) c(("C")) -.-> c/CompoundTypesGroup(["Compound Types"]) c(("C")) -.-> c/UserInteractionGroup(["User Interaction"]) c/BasicsGroup -.-> c/variables("Variables") c/BasicsGroup -.-> c/data_types("Data Types") c/ControlFlowGroup -.-> c/for_loop("For Loop") c/CompoundTypesGroup -.-> c/arrays("Arrays") c/UserInteractionGroup -.-> c/output("Output") subgraph Lab Skills c/variables -.-> lab-438330{{"C 言語における配列の操作"}} c/data_types -.-> lab-438330{{"C 言語における配列の操作"}} c/for_loop -.-> lab-438330{{"C 言語における配列の操作"}} c/arrays -.-> lab-438330{{"C 言語における配列の操作"}} c/output -.-> lab-438330{{"C 言語における配列の操作"}} end

配列宣言の構文を紹介する

このステップでは、C プログラミングにおける配列宣言の基本概念を紹介します。配列は、同じ型の複数の要素を連続したメモリ領域に格納できる重要なデータ構造です。配列を、特定の種類のアイテムを収納できる収納ボックスの列と想像してください。そして、それぞれのボックスには一意のインデックス番号があり、これを使ってボックスにアクセスできます。

配列とは?

配列は、インデックス番号でアクセスされる変数のコレクションです。配列のすべての要素は同じ型です。同じジャンルの本を収納できる本棚を想像してください。これは、プログラミングにおける配列の仕組みに似ています。それぞれの「本」(または要素)は、棚上のその位置(インデックス)によってアクセスできます。

配列宣言の構文

C 言語で配列を宣言するには、次の構文を使用します。

type arrayName[arraySize];
  • type:配列内の要素のデータ型(たとえば、intfloatchar)。これにより、配列が格納できるデータの種類が決まります。
  • arrayName:配列の名前で、配列を参照および操作する際に使用します。
  • arraySize:配列が保持できる要素数で、配列の総格納容量を定義します。

例:配列の宣言と初期化

WebIDE で新しいファイルを作成して、配列宣言を調べてみましょう。この実際の例を通じて、現実世界のプログラミングシナリオで配列がどのように機能するかを理解できるでしょう。

WebIDE を開き、次の手順に従ってください。

  1. ファイルエクスプローラーで右クリックし、「新しいファイル」を選択します。
  2. ファイル名を arrays_intro.c にします。
  3. ファイルをクリックしてエディタで開きます。

では、配列宣言と初期化を示す簡単なプログラムを書いてみましょう。

#include <stdio.h>

int main() {
    // 5 つの要素を持つ整数型の配列を宣言する
    int numbers[5] = {10, 20, 30, 40, 50};

    // 配列要素を表示する
    printf("Array elements:\n");
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = %d\n", i, numbers[i]);
    }

    return 0;
}

配列宣言を分解してみましょう。

  • int numbers[5]:5 つの要素を保持できる整数型の配列 numbers を宣言します。これは、整数値を格納するための 5 つのスペースがある棚を作成するようなものです。
  • {10, 20, 30, 40, 50}:配列を特定の値で初期化し、各「棚のスペース」に事前に決められた数値を入れます。
  • 最初の要素 numbers[0] は 10、2 番目の numbers[1] は 20 です。C 言語では、配列のインデックスは 0 から始まることに注意してください。

プログラムをコンパイルして実行します。

プログラムをコンパイルして実行するには、ターミナルで次のコマンドを使用します。

gcc arrays_intro.c -o arrays_intro
./arrays_intro

例の出力:

Array elements:
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
numbers[3] = 40
numbers[4] = 50

この出力は、配列の各要素がそのインデックスを使ってどのようにアクセスおよび表示されるかを示しています。この基本概念を理解することは、C プログラミングにおける配列操作をマスターするための最初のステップです。

値で整数型配列を初期化する

このステップでは、C プログラミングにおいて整数型配列を初期化するさまざまな方法を調べます。配列の初期化を理解することは、データのコレクションを効果的に扱うために重要です。

WebIDE を開き、新しいファイルを作成します。

  1. ファイルエクスプローラーで右クリックし、「新しいファイル」を選択します。
  2. ファイル名を array_initialization.c にします。
  3. ファイルをクリックしてエディタで開きます。

C 言語で配列を扱う際、初期化する方法は複数あることにすぐに気付くでしょう。それぞれの方法には独自の使用例があり、データストレージを効率的に設定するのに役立ちます。これらの初期化手法を見ていき、それがどのように機能するかを理解しましょう。

#include <stdio.h>

int main() {
    // 方法 1: 完全初期化
    int scores[5] = {85, 92, 78, 90, 88};

    // 方法 2: 部分的な初期化 (残りの要素は 0 に設定)
    int temperatures[5] = {72, 75, 80};

    // 方法 3: すべての要素を 0 に初期化
    int ages[5] = {0};

    // 配列を表示する
    printf("Scores array:\n");
    for (int i = 0; i < 5; i++) {
        printf("scores[%d] = %d\n", i, scores[i]);
    }

    printf("\nTemperatures array:\n");
    for (int i = 0; i < 5; i++) {
        printf("temperatures[%d] = %d\n", i, temperatures[i]);
    }

    printf("\nAges array:\n");
    for (int i = 0; i < 5; i++) {
        printf("ages[%d] = %d\n", i, ages[i]);
    }

    return 0;
}

このコードを実行すると、実際にさまざまな初期化方法がどのように機能するかがわかります。このコードは、配列を作成して要素を設定する 3 つの主な方法を示しており、それぞれがプログラミングにおいて異なる目的を果たします。

プログラムをコンパイルして実行します。

gcc array_initialization.c -o array_initialization
./array_initialization

例の出力:

Scores array:
scores[0] = 85
scores[1] = 92
scores[2] = 78
scores[3] = 90
scores[4] = 88

Temperatures array:
temperatures[0] = 72
temperatures[1] = 75
temperatures[2] = 80
temperatures[3] = 0
temperatures[4] = 0

Ages array:
ages[0] = 0
ages[1] = 0
ages[2] = 0
ages[3] = 0
ages[4] = 0

初心者が理解すべき配列初期化のキーコンセプトを、コードを中心に解説しましょう。

  • 方法 1: 完全初期化 int scores[5] = {85, 92, 78, 90, 88};:ここでは、サイズ 5 の scores という名前の配列を宣言し、5 つの特定の値で初期化しています。これは、宣言時に配列の各位置に特定の値を割り当てる単純な方法です。配列の各要素は、波括弧内の値の順序に従って設定されます。
  • 方法 2: 部分的な初期化 int temperatures[5] = {72, 75, 80};:この場合、サイズ 5 の temperatures 配列は 3 つの値でのみ初期化されています。C は、残りの要素(インデックス 3 と 4)を 0 に設定することで対応します。部分的な初期化は、最初のいくつかの値がわかっており、残りの値を 0 にデフォルト設定したい場合に便利です。
  • 方法 3: すべての要素を 0 に初期化 int ages[5] = {0};:これは、サイズ 5 の ages という名前の配列を初期化し、すべての要素を 0 に設定します。配列内のすべての値を 0 から始める必要がある場合、これは便利なショートカットです。カウントやデータ構造の初期状態などの状況では非常に一般的です。
  • 配列のサイズは宣言時に固定される:宣言時に特定のサイズ(たとえば [5])で配列を宣言すると、その後でそのサイズを変更できないことを覚えておくことが重要です。新しい配列を作成しない限り、配列から要素を追加または削除することはできません。
  • インデックスは常に 0 から始まる:既に見たように、配列要素はインデックスを通じてアクセスされ、最初の要素のインデックスは常に 0 から始まります。scores 配列では、scores[0] が最初の要素を指し、scores[1] が 2 番目の要素を指します。

これらの初期化方法は、配列の設定と操作方法に柔軟性を提供します。C プログラミングの学習を進めるにつれて、これらの手法はデータのコレクションを効率的かつクリーンに管理するために非常に役立つことがわかります。

インデックスを使って配列要素にアクセスする

C 言語では、配列は 0 から始まるインデックス付きです。つまり、最初の要素はインデックス 0 にあり、2 番目の要素はインデックス 1 にあり、以下同様です。この概念は最初は直感的でないかもしれませんが、多くのプログラミング言語における標準的な規約であり、低レベルのメモリ管理に由来しています。

WebIDE を開き、新しいファイルを作成します。

  1. ファイルエクスプローラーで右クリックし、「新しいファイル」を選択します。
  2. ファイル名を array_indexing.c にします。
  3. ファイルをクリックしてエディタで開きます。

配列のインデックス付けと操作を示すプログラムを書いてみましょう。

#include <stdio.h>

int main() {
    // 学生の点数の配列を宣言して初期化する
    int grades[5] = {85, 92, 78, 90, 88};

    // 個々の配列要素にアクセスする
    printf("First grade (index 0): %d\n", grades[0]);
    printf("Third grade (index 2): %d\n", grades[2]);

    // 配列要素を変更する
    printf("\nBefore modification:\n");
    for (int i = 0; i < 5; i++) {
        printf("grades[%d] = %d\n", i, grades[i]);
    }

    // 特定の要素を変更する
    grades[1] = 95;  // 2 番目の点数を変更する
    grades[4] = 87;  // 最後の点数を変更する

    printf("\nAfter modification:\n");
    for (int i = 0; i < 5; i++) {
        printf("grades[%d] = %d\n", i, grades[i]);
    }

    // 平均点数を計算する
    int total = 0;
    for (int i = 0; i < 5; i++) {
        total += grades[i];
    }
    float average = (float)total / 5;
    printf("\nAverage grade: %.2f\n", average);

    return 0;
}

この例では、学生の点数の配列を扱っています。このコードは、初心者が理解すべきいくつかの重要な配列操作を示しています。まず、5 つの整数要素を持つ配列を宣言し、それぞれが異なる学生の点数を表します。

プログラムをコンパイルして実行します。

gcc array_indexing.c -o array_indexing
./array_indexing

例の出力:

First grade (index 0): 85
Third grade (index 2): 78

Before modification:
grades[0] = 85
grades[1] = 92
grades[2] = 78
grades[3] = 90
grades[4] = 88

After modification:
grades[0] = 85
grades[1] = 95
grades[2] = 78
grades[3] = 90
grades[4] = 87

Average grade: 87.00

出力は、特定の配列要素にどのようにアクセスし、その値を表示して変更するかを示しています。for ループは、すべての配列要素を反復処理する効率的な方法を示しており、任意のサイズの配列を扱う際に重要です。

配列のインデックス付けに関するポイントを、特定のコード行を中心に説明します。

  • 配列のインデックスは 0 から始まる:配列 grades の最初の要素は grades[0] を使ってアクセスされ、grades[1] ではありません。printfprintf("First grade (index 0): %d\n", grades[0]); がこの重要な概念を示しています。
  • array[index] を使って個々の要素にアクセスする:文 printf("Third grade (index 2): %d\n", grades[2]); は、与えられたインデックスにある特定の要素にどのようにアクセスするかを示しています。ここでは、インデックス 2 にある 3 番目の要素にアクセスしています。
  • 新しい値を代入することで配列要素を変更する:行 grades[1] = 95;grades[4] = 87; は、配列に格納されている値をどのように変更するかを示しています。インデックス 1 の値は 95 に更新され、インデックス 4 の値は 87 に更新されます。インデックスと代入演算子を使った直接的なアクセスと変更です。
  • 配列の範囲外のインデックスにアクセスしないように注意するgrades[5] にアクセスしようとすると(配列には 5 つの要素があり、インデックスは 0 から 4 までです)、おそらくエラーが発生します(これは「バッファオーバーフロー」または「範囲外アクセス」と呼ばれます)。存在しないインデックスにアクセスすると、予測できない動作が起こります。
  • ループを使って配列要素を効率的に反復処理する:配列を表示するために使われるような for ループは、インデックス 0 から 4 までの配列のすべての要素を順に反復処理する効率的な方法です。
for (int i = 0; i < 5; i++) {
    printf("grades[%d] = %d\n", i, grades[i]);
}

このループは、変数 i を 0 から 4 までのインデックスとして使用しています。

これらの原則を理解することで、C プログラミングの学習過程で配列を効果的に操作できるようになります。練習と実験が配列操作をマスターする鍵です。

for ループで要素を表示する

プログラミングを初めて学ぶとき、ループの概念は恐ろしいように見えるかもしれません。しかし、それらは非常に強力なツールであり、効率的かつエレガントに反復処理を行うことができます。for ループは、配列要素を反復処理する構造化された方法を提供し、各要素とのやり取り方法を正確に制御します。

WebIDE を開き、新しいファイルを作成します。

  1. ファイルエクスプローラーで右クリックし、「新しいファイル」を選択します。
  2. ファイル名を array_loop_print.c にします。
  3. ファイルをクリックしてエディタで開きます。

配列要素を表示するさまざまな方法を示すプログラムを書いてみましょう。

#include <stdio.h>

int main() {
    // 温度の配列を宣言して初期化する
    int temperatures[5] = {72, 75, 80, 68, 85};

    // 方法 1: インデックス付きの標準的な for ループを使用する
    printf("方法 1: インデックス付きで表示する\n");
    for (int i = 0; i < 5; i++) {
        printf("温度 %d: %d 度\n", i + 1, temperatures[i]);
    }

    // 方法 2: 説明的なラベル付きで配列を表示する
    printf("\n方法 2: ラベル付きで表示する\n");
    char *days[] = {"月曜日", "火曜日", "水曜日", "木曜日", "金曜日"};
    for (int i = 0; i < 5; i++) {
        printf("%s の温度: %d 度\n", days[i], temperatures[i]);
    }

    // 方法 3: 追加の情報を計算して表示する
    printf("\n方法 3: 平均温度を計算する\n");
    int total = 0;
    for (int i = 0; i < 5; i++) {
        total += temperatures[i];
        printf("%d 度を加算中\n", temperatures[i]);
    }
    float average = (float)total / 5;
    printf("平均温度: %.1f 度\n", average);

    return 0;
}

この例では、単に配列要素を表示するだけでなく、ループがどれほど多用途であるかを示しています。それぞれの方法は、配列を扱う異なるアプローチを示しており、C プログラミングにおける for ループの柔軟性を理解するのに役立ちます。

プログラムをコンパイルして実行します。

gcc array_loop_print.c -o array_loop_print
./array_loop_print

例の出力:

方法 1: インデックス付きで表示する
温度 1: 72 度
温度 2: 75 度
温度 3: 80 度
温度 4: 68 度
温度 5: 85 度

方法 2: ラベル付きで表示する
月曜日の温度: 72 度
火曜日の温度: 75 度
水曜日の温度: 80 度
木曜日の温度: 68 度
金曜日の温度: 85 度

方法 3: 平均温度を計算する
72 度を加算中
75 度を加算中
80 度を加算中
68 度を加算中
85 度を加算中
平均温度: 76.0 度

for ループと配列に関するポイントを、コードを中心に説明します。

  • ループ変数 i は 0 から始まり、array_length - 1 まで増加する:方法 1 の標準的なループ初期化 for (int i = 0; i < 5; i++) は、ループが配列 temperatures の最初の要素(インデックス 0)から最後の要素(インデックス 4)まで反復処理し、各要素を表示するように保証します。条件 i < 5 は、ループがどのくらい続くかを決定します。
  • ループインデックスを使って配列要素にアクセスできるfor ループでは、各ループサイクル中に temperatures[i] が使用されて、対応するインデックス i の要素にアクセスされます。これは、ループカウンターが配列インデックスとして機能する方法を示しています。
  • ループは、配列全体に対して操作を行うのに便利です:方法 3 は、for ループを使って配列の合計を計算し、ループ中に追加の情報を表示する例を示しています。for ループは、すべての配列要素を反復処理して total を計算するために使用されます。
  • ループを計算と追加の配列と組み合わせることができる:方法 2 は、for ループを追加の days 配列と組み合わせており、方法 3 はループ中で計算を行っています。これは、配列とループを一緒に使う方法を示しています。

これらの概念を理解することで、より効率的で読みやすいコードを書くことができます。プログラミングの学習を進めるにつれて、ループと配列は複雑な問題を解決し、洗練されたアルゴリズムを実装するための不可欠なツールであることがわかります。

高度な配列操作

このステップでは、配列に対して行うことができるいくつかの高度な操作、たとえば最大値と最小値を見つけることや、配列をソートすることを探ります。これらの技術は、データ分析、処理、およびアルゴリズムの実装に不可欠です。

配列の最大値と最小値を見つけるプログラムを書いてみましょう。

cd ~/project
touch find_max_min.c
#include <stdio.h>

int main() {
    int numbers[5] = {10, 20, 30, 40, 50};
    int max = numbers[0];
    int min = numbers[0];

    for (int i = 1; i < 5; i++) {
        if (numbers[i] > max) {
            max = numbers[i];
        }
        if (numbers[i] < min) {
            min = numbers[i];
        }
    }

    printf("最大値: %d\n", max);
    printf("最小値: %d\n", min);

    return 0;
}

このコードは、配列の最大値と最小値を見つけるためのシンプルで強力な技術を示しています。maxmin を最初の要素で初期化し、その後の各要素と比較することで、配列内の極端な値を効率的に特定できます。

重要なコード行:

  • 初期化int max = numbers[0]; int min = numbers[0]; - maxmin の変数は、配列の最初の要素で初期化されます。このステップは比較のための起点を提供します。
  • 比較ループfor (int i = 1; i < 5; i++) - この for ループは、インデックス 1(2 番目の要素)から配列の末尾まで始まります。これにより、その後の各値が既存の最大値と最小値と比較されます。
  • 最大値の検索if (numbers[i] > max) { max = numbers[i]; } - このブロックは、現在の要素が現在の max より大きいかどうかをチェックします。もしそうなら、max 変数は現在の要素の値に更新されます。
  • 最小値の検索if (numbers[i] < min) { min = numbers[i]; } - 同様に、これは現在の要素が現在の min より小さいかどうかをチェックし、より小さい値が見つかった場合に min を更新します。

次に、バブルソートアルゴリズムを使って配列を昇順にソートするプログラムを書いてみましょう。

cd ~/project
touch bubble_sort.c
#include <stdio.h>

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

int main() {
    int numbers[5] = {50, 20, 30, 10, 40};

    bubbleSort(numbers, 5);

    printf("ソート済みの配列:\n");
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = %d\n", i, numbers[i]);
    }

    return 0;
}

バブルソートは、リストを繰り返しステップし、隣接する要素を比較し、順序が間違っている場合に交換する古典的なソートアルゴリズムです。大規模なデータセットに対して最も効率的なソート方法ではありませんが、ソートの概念と配列操作の素晴らしい入門となります。

重要なコード行:

  • 外側のループfor (int i = 0; i < n-1; i++) - この外側のループは、配列を通過するパスの数を制御します。ループは n-1 回実行されます(n は配列のサイズ)。なぜなら、各パスの後に最大の要素がその最終位置にあるからです。
  • 内側のループfor (int j = 0; j < n-i-1; j++) - 内側のループは、実際の比較と交換を行います。最大の要素が末尾に「泡立って」上がるにつれて、内側のループの範囲は減少します。そのため、n - i - 1 を使っています。
  • 比較if (arr[j] > arr[j+1]) - この文は、現在の要素が次の要素より大きいかどうかをチェックします。
  • 交換:行 int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; は、arr[j]arr[j+1] より大きい場合に 2 つの要素を交換します。一時的な変数 temp は、交換中に値の 1 つを失わないようにするために使用されます。

プログラムをコンパイルして実行するには、ターミナルで次のコマンドを使用します。

gcc find_max_min.c -o find_max_min
./find_max_min

gcc bubble_sort.c -o bubble_sort
./bubble_sort

最大値と最小値を見つけるための例の出力:

最大値: 50
最小値: 10

ソートのための例の出力:

ソート済みの配列:
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
numbers[3] = 40
numbers[4] = 50

これらの例は、C プログラミングにおけるより複雑なデータ処理技術の基礎となる基本的な配列操作を示しています。

まとめ

この実験では、C プログラミングにおける配列の宣言と初期化の基本概念を学びました。整数型配列を宣言する構文を調べ、特定の値で初期化する方法も学びました。また、配列の個々の要素にインデックスを使ってアクセスする方法と、for ループで配列要素を表示する方法も学びました。最後に、最大値と最小値を見つけることや、バブルソートアルゴリズムを使って配列をソートするなどの高度な配列操作を調べました。これらのスキルは、配列を扱う際に不可欠であり、C プログラミングにおける重要なデータ構造です。