C言語でのVector型の使い方!初心者から上級者まで向けた10の手引き

C言語のVector型を解説するスクリーンショットC言語
この記事は約11分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

ようこそ、この記事ではC言語でのVector型の使い方を解説します。

初心者から上級者まで、どのレベルのプログラマでも学べる内容になっています。

この記事では10の詳細なサンプルコードを用いて、Vector型の作成から操作、カスタマイズ方法までを学んでいきます。

●C言語とVector型について

C言語はプログラミングの世界で非常に重要な存在です。

その中でVector型はC言語をより強力で柔軟なツールに変えるものです。

Vector型は動的配列の一種で、配列のサイズを動的に変更できる機能を持っています。

●Vector型の基本的な概念

C言語のVector型は、要素を動的に追加または削除することが可能な一次元の配列です。

この特性により、静的配列とは異なり、Vector型は必要に応じてサイズを変更できます。

これは特にデータの量が予測できない場合や、大量のデータを扱う場合に有効です。

●Vector型の作り方

C言語には標準でVector型が提供されていないため、自分で定義する必要があります。

一般的には、配列とそのサイズ、容量を保持する構造体を定義します。

○サンプルコード1:Vector型の作成

Vector型の基本的な実装を紹介します。

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

typedef struct {
    int *array;
    size_t used;
    size_t size;
} Vector;

void initVector(Vector *v, size_t initialSize) {
    v->array = (int *)malloc(initialSize * sizeof(int));
    v->used = 0;
    v->size = initialSize;
}

このコードでは、Vectorという名前の新しい型を定義しています。

このVectorarray(実際にデータを保持する配列)、used(現在使用中の要素数)、size(配列の現在の最大容量)という3つのフィールドを持つ構造体です。

次に、initVector関数を使ってVectorを初期化します。

この関数ではメモリの確保と初期値の設定を行います。

このコードを実行すると、Vector型の変数を作成し、その初期化を行うことができます。

●Vector型の操作方法

C言語でVector型を扱う方法は多岐に渡ります。最も基本的な操作は、Vectorに要素を追加すること、Vectorから要素を取得すること、そしてVectorの要素を変更することです。

○サンプルコード2:Vectorに要素を追加する

下記のコードでは、Vectorに要素を追加するinsertVector関数を定義しています。

void insertVector(Vector *v, int element) {
    if (v->used == v->size) {
        v->size *= 2;
        v->array = (int *)realloc(v->array, v->size * sizeof(int));
    }
    v->array[v->used++] = element;
}

このコードでは、Vectorの現在の使用量が最大容量に達している場合、realloc関数を使って配列のサイズを2倍に拡張しています。

その後、新しい要素を配列の末尾に追加し、使用量を1増やします。

このコードを実行すると、指定した要素がVectorの末尾に追加されます。

○サンプルコード3:Vectorから要素を取得する

Vectorから特定の位置の要素を取得する方法を紹介します。

下記のコードでは、指定されたインデックスの要素を返すatVector関数を定義しています。

int atVector(Vector *v, size_t index) {
    if (index < v->used) {
        return v->array[index];
    } else {
        printf("Index out of bounds\n");
        exit(1);
    }
}

このコードでは、指定したインデックスがVectorの使用量内に収まっている場合、その位置の要素を返します。

それ以外の場合はエラーメッセージを出力し、プログラムを終了します。

このコードを実行すると、指定したインデックスの要素を取得できます。

○サンプルコード4:Vectorの要素を変更する

最後に、Vectorの特定の位置の要素を変更する方法を紹介します。

下記のコードでは、指定されたインデックスの要素を新しい値に更新するupdateVector関数を定義しています。

void updateVector(Vector *v, size_t index, int newElement) {
    if (index < v->used) {
        v->array[index] = newElement;
    } else {
        printf("Index out of bounds\n");
        exit(1);
    }
}

このコードでは、指定したインデックスがVectorの使用量内に収まっている場合、その位置の要素を新しい値に更新します。

それ以外の場合はエラーメッセージを出力し、プログラムを終了します。

このコードを実行すると、指定したインデックスの要素を新しい値に更新できます。

●Vector型の詳細な使い方

ここまででVector型の基本的な使い方を見てきましたが、Vector型はそれ以上の多様な利用が可能です。

具体的には、Vectorを利用したデータ処理やアルゴリズム、データ構造の作成などが考えられます。

○サンプルコード5:Vectorを利用したデータ処理

次のコードでは、Vectorを利用して一連の整数データを読み込み、その平均を計算しています。

double calculateAverage(Vector *v) {
    int sum = 0;
    for (size_t i = 0; i < v->used; ++i) {
        sum += v->array[i];
    }
    return sum / (double)v->used;
}

このコードでは、Vectorに格納されている全ての要素を順に足し合わせ、その合計を要素数で割ることで平均を計算しています。

このコードを実行すると、Vectorに格納された要素の平均を計算できます。

○サンプルコード6:Vectorを利用したアルゴリズム

次に、Vectorを利用して数値のソートを行う例を見てみましょう。

この例では、シンプルなバブルソートを実装します。

void bubbleSort(Vector *v) {
    for (size_t i = 0; i < v->used - 1; ++i) {
        for (size_t j = 0; j < v->used - i - 1; ++j) {
            if (v->array[j] > v->array[j + 1]) {
                int temp = v->array[j];
                v->array[j] = v->array[j + 1];
                v->array[j + 1] = temp;
            }
        }
    }
}

このコードでは、各要素を比較し、必要に応じて隣り合う要素を交換しています。

これを全ての要素に対して行うことで、Vector内の数値が昇順にソートされます。

このコードを実行すると、Vectorに格納された要素をソートできます。

○サンプルコード7:Vectorを利用したデータ構造

Vectorは、より複雑なデータ構造を作成するための基本的なブロックとしても利用できます。

次のコードでは、Vectorを利用してスタックを実装します。

void pushStack(Vector *v, int element) {
    insertVector(v, element);
}

int popStack(Vector *v) {
    if (v->used == 0) {
        printf("Stack is empty\n");
        exit(1);
    }
    return v->array[--v->used];
}

このコードでは、スタックの最後に要素を追加するpushStack関数と、スタックの最後の要素を取り出すpopStack関数を定義しています。

このコードを実行すると、Vectorを利用したスタックを作成できます。

●Vector型のカスタマイズ方法

Vector型は非常に汎用的なデータ構造であるため、様々なカスタマイズが可能です。

例えば、Vectorに異なるデータ型の要素を格納したり、Vectorの動作を変更したりすることができます。

○サンプルコード8:自定義Vectorの作成

次のコードでは、整数ではなく文字列を格納するVectorを作成します。

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

typedef struct {
    char **array;
    size_t used;
    size_t size;
} StringVector;

void initStringVector(StringVector *v, size_t initialSize) {
    v->array = (char **)malloc(initialSize * sizeof(char *));
    v->used = 0;
    v->size = initialSize;
}

void insertStringVector(StringVector *v, char *element) {
    if (v->used == v->size) {
        v->size *= 2;
        v->array = (char **)realloc(v->array, v->size * sizeof(char *));
    }
    v->array[v->used] = strdup(element);
    v->used++;
}

このコードでは、StringVectorという新しいVector型を作成し、文字列を保持する配列としてchar **arrayを定義しています。

また、新しい要素を追加する際にはstrdup関数を使用して文字列を複製しています。

このコードを実行すると、文字列を格納できるVectorを作成できます。

●Vector型の注意点と対処法

Vector型を扱う際には、特にメモリ管理に注意が必要です。

特に、Vectorのメモリを適切に解放しないとメモリリークが発生する可能性があります。

また、Vectorのエラーハンドリングについても考慮する必要があります。

○サンプルコード9:Vectorのメモリリーク対策

下記のコードは、Vectorのメモリを適切に解放する方法を表しています。

void freeVector(Vector *v) {
    free(v->array);
    v->array = NULL;
    v->used = v->size = 0;
}

このコードでは、free関数を使用してVectorのメモリを解放しています。

そして、NULLを代入してポインタが不適切なメモリ領域を指さないようにしています。

また、usedsizeを0に設定してVectorが空であることを示しています。

このコードを実行すると、Vectorのメモリを適切に解放できます。

○サンプルコード10:Vectorのエラーハンドリング

次に、Vectorから要素を取得する際にインデックスが範囲外の場合のエラーハンドリングを見てみましょう。

int getElement(Vector *v, size_t index) {
    if (index >= v->used) {
        printf("Index out of range\n");
        exit(1);
    }
    return v->array[index];
}

このコードでは、取得しようとする要素のインデックスがVectorの使用中の要素数以上である場合にエラーメッセージを出力し、プログラムを終了しています。

このコードを実行すると、範囲外のインデックスによるエラーを適切に処理できます。

まとめ

以上、C言語でのVector型の基本的な概念から作成、操作、詳細な使用方法、カスタマイズ方法、注意点と対処法までを解説しました。

初心者から上級者まで、Vector型の使用について理解を深めることができたでしょう。

また、各サンプルコードを通じて、Vector型の実際の使用例を見ることができました。

これらのコードを基に、自身のプログラムにVector型を適切に組み込むことができます。

Vector型は、その汎用性から様々なプログラミングシーンで利用可能です。

適切な使い方を身につけることで、より高度で効率的なコーディングが可能になるでしょう。