配列をコピーする | Programming Place Plus C言語編 逆引き

トップページC言語編逆引き

このページの概要

以下は目次です。

目的

配列をコピーして、同じ要素数、同じ値を持つ配列を作りたいとします。

C言語では、配列は代入できませんから、他の手段が必要になります。

#include <stdio.h>

#define ARRAY_SIZE (5)

int main(void)
{
    int array1[ARRAY_SIZE] = {0, 1, 2, 3, 4};
    int array2[ARRAY_SIZE];

    array2 = array1;  // エラー
}

文字の配列(文字列)の場合は、ほかの手法があります。「文字列をコピーする」のページを参照してください。

方法①(memcpy関数を使う)

「配列をコピーする」という関数はありませんが、メモリの内容をまとめてコピーする memcpy関数があります。配列は、すべての要素が隙間なく連続的に並ぶことが保証されているので、memcpy関数でコピーできます。

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

#define ARRAY_SIZE (5)

int main(void)
{
    int array1[ARRAY_SIZE] = {0, 1, 2, 3, 4};
    int array2[ARRAY_SIZE];

    memcpy(array2, array1, sizeof(array1));

    for (int i = 0; i < ARRAY_SIZE; ++i) {
        printf("%d ", array2[i]);
    }
    printf("\n");
}

実行結果:

0 1 2 3 4

このサンプルプログラムのように、sizeof演算子を使って配列全体の大きさを取得して、 memcpy関数に渡すときには、それが本当に配列であることをよく確認してください。 たとえば、このコピー処理を関数化すると、配列を関数に渡せず、ポインタに変換されますから、 配列のバイト数を取得したつもりが、実際にはポインタのバイト数を取得していることになってしまいます。

// 失敗例
void copy_array(int* dest, const int* src)
{
    memcpy(dest, src, sizeof(src));
}

この間違った実装では、「sizeof(src)」の部分で、ポインタのバイト数を取得してしまっているため、 ポインタ1個分の相当する範囲のコピーしか行われません。

方法②(1要素ずつコピーする)

基本的には memcpy関数を使った方が良いですが、1要素ずつ手動でコピーすることも考えられます。 こちらの方法の場合は、1要素ずつ、値に何らかの加工を加える等、処理を追加できる余地が生まれます。

#include <stdio.h>

#define ARRAY_SIZE (5)

int main(void)
{
    int array1[ARRAY_SIZE] = {0, 1, 2, 3, 4};
    int array2[ARRAY_SIZE];

    for (int i = 0; i < ARRAY_SIZE; ++i) {
        array2[i] = array1[i];
    }

    for (int i = 0; i < ARRAY_SIZE; ++i) {
        printf("%d ", array2[i]);
    }
    printf("\n");
}

実行結果:

0 1 2 3 4


参考リンク


更新履歴

’2018/2/22 「サイズ」という表記について表現を統一。 型のサイズ(バイト数)を表しているところは「大きさ」、要素数を表しているところは「要素数」。

’2017/6/20 新規作成。



逆引きのトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る