以下は目次です。
定義済みの配列のすべての要素に、同じ値を入れたいとします。
#include <stdio.h>
#define SIZE_OF_ARRAY(array) (sizeof(array)/sizeof(array[0]))
int main(void)
{
int array[] = {0, 1, 2, 3, 4};
// array[0]~array[4] まで、すべてを 10 にしたい
}
SIZE_OF_ARRAYマクロは、配列の要素数を取得するものです。詳細は「逆引き 配列の要素数を求める」を参照してください。
for文を使って、要素1つ1つに順番に値を代入していきます。実のところ、この方法よりも確実な方法はありませんし、これより楽ができる方法もありません。
#include <stdio.h>
#define SIZE_OF_ARRAY(array) (sizeof(array)/sizeof(array[0]))
int main(void)
{
int array[] = {0, 1, 2, 3, 4};
for (size_t i = 0; i < SIZE_OF_ARRAY(array); ++i) {
[i] = 10;
array}
for (size_t i = 0; i < SIZE_OF_ARRAY(array); ++i) {
("%d ", array[i]);
printf}
("\n");
printf}
実行結果:
10 10 10 10 10
memset関数を使うと、メモリの範囲を同じ値で埋めることができるため、これを使って、すべての要素を 0 で埋める方法が紹介されることがあります(「逆引き 配列の全要素を 0 で埋める」で取り上げています)。
指定する値を 0 以外にすれば、すべての要素を埋める手段として使えそうに思えますが、ほとんどの場合でうまくいきません。memset関数は「1バイト単位」で同じ値を埋める関数だからです。
【上級】memset関数はそもそも「文字」を書き込む関数なのであり、第2引数に指定した値を、unsigned char型に変換して書き込むという仕様です。
たとえば、int型の配列のすべての要素を 10 で埋めたいとします。
まず、int型の配列の各要素の大きさは sizeof(int) です。これは 4バイトであったり、2バイトであったりするでしょう。仮に 4バイトだとすると、その 4バイトを構成する 4つのバイトのそれぞれに、10 を入れるのが memset関数の仕様なのです。
次のサンプルプログラムは memset関数による方法を試したものですが、失敗しています。
#include <stdio.h>
#include <string.h>
#define SIZE_OF_ARRAY(array) (sizeof(array)/sizeof(array[0]))
int main(void)
{
int array[] = {0, 1, 2, 3, 4};
// array の各要素に 10 を入れる?
(array, 10, sizeof(array));
memset
for (size_t i = 0; i < SIZE_OF_ARRAY(array); ++i) {
("%d ", array[i]);
printf}
("\n");
printf}
実行結果:
168430090 168430090 168430090 168430090 168430090
array[i] の 4バイトを構成する 4つのバイトそれぞれに 10 が書き込まれるため、このような結果になります。この実行結果ではわかりづらいかもしれませんが、“%x” 変換指定子を使って 16進数で出力すると状況が見えやすいでしょう。
実行結果(16進数で出力した場合):
a0a0a0a a0a0a0a a0a0a0a a0a0a0a a0a0a0a
10進数の「10」は、16進数で「a」ですから、それぞれ4つの「0a」が書き込まれている様子がみえます。
このように、memset関数を使って、すべての要素に同じ値を入れる方法は、うまくいかないケースがほとんどです。0 で埋める場合や、255(0xff)で埋める場合など、1バイト単位で書き込んでも、結果が変わらないケースでなければうまくいきません。
また、ポインタ型や、浮動小数点型の配列の場合、「0」が必ずしもヌルポインタや 0.0 のことを意味しないことに注意してください(「逆引き 配列の全要素を 0 で埋める」を参照)。
return 0;
を削除(C言語編全体でのコードの統一)新規作成。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |