「配列の初期化」の版間の差分

提供: C言語入門
移動: 案内検索
(ページの作成:「C言語の配列は、配列の宣言時に配列の初期化を行えます。 '''読み方''' ;配列の初期化:はいれつ の しょきか __TOC__ == 概...」)
 
 
行10: 行10:
 
int a1[3] = {1,2,3};
 
int a1[3] = {1,2,3};
 
int a2[] = {1,2,3};
 
int a2[] = {1,2,3};
 +
int zero1[3] = {0};      // zero clear
 
char *s1[] = {"abc", "def"};
 
char *s1[] = {"abc", "def"};
 
</syntaxhighlight>
 
</syntaxhighlight>
行88: 行89:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
自分でmemset()/bzero()などを呼び出す必要がないため、非常に便利です。
 +
 +
=== アセンブラレベルでのゼロクリアの処理 ===
 +
配列をゼロクリアするためには、一体、どのようなコードが生成されているのでしょうか?
 +
プログラマがバッファを自分で明示的にクリアしようと思ったら、memset()/bzero()で0を書き込みます。
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
#include <stdio.h>
 
#include <stdio.h>

2014年3月31日 (月) 21:29時点における最新版

C言語の配列は、配列の宣言時に配列の初期化を行えます。

読み方

配列の初期化
はいれつ の しょきか

概要

配列の初期化は、配列の宣言に対して、ブレース({})で囲んだ値で初期化します。

int a1[3] = {1,2,3};
int a2[] = {1,2,3};
int zero1[3] = {0};      // zero clear
char *s1[] = {"abc", "def"};

一次元配列の初期化

整数の一次元配列

配列のサイズは、省略できます。

int a1[3] = {1,2,3};
int a2[] = {1,2,3};

charポインタ型の一次元配列

char *s1[2] = {
	"abc",
	"def"
};

配列のサイズを省略した場合は、以下の通りです。

char *s1[] = {
	"abc",
	"def"
};

整数のニ次元配列

二次元配列の初期化は、以下の通りです。

int a[2][3] = {
	{ 1, 2, 3},
	{ 4, 5, 6}
};

一つめの添字は、省略できます。

int a[][3] = {
	{ 1, 2, 3},
	{ 4, 5, 6}
};

ニ次元配列の初期化の例

/*
 * array_array.c
 * Copyright (C) 2014 kaoru <kaoru@bsd>
 */
#include <stdio.h>
#include <stdlib.h>
 
int
main(int argc, char *argv[])
{
        //int a[][3] = {
        int a[2][3] = {
                { 1, 2, 3},
                { 4, 5, 6}
        };
        int i = 0, j = 0;
        for(i = 0;i < 2;i++){
                for(j = 0;j < 3;j++){
                        (void)printf("%d ", a[i][j]);
                }
                (void)putchar('\n');
        }
        exit(EXIT_SUCCESS);
}

実行例は、以下の通りです。

$ ./a.out
1 2 3
4 5 6

配列をゼロクリアする

配列をゼロクリアするには、以下のコードを書きます。

char s [ 64 ] = { 0 };

自分でmemset()/bzero()などを呼び出す必要がないため、非常に便利です。

アセンブラレベルでのゼロクリアの処理

配列をゼロクリアするためには、一体、どのようなコードが生成されているのでしょうか? プログラマがバッファを自分で明示的にクリアしようと思ったら、memset()/bzero()で0を書き込みます。

#include <stdio.h>
#include <stdlib.h>
 
int
main (int argc, char *argv[])
{
        char s [ 64 ] = { 0 };
 
        exit(EXIT_SUCCESS);
}

上記のソースをclang バージョン 3.3でアセンブリ言語に変換すると以下のコードになりました。生成されるコードは、CコンパイラCコンパイラのバージョンによって異なるため、必ずしもこのようなコードになるとは限りません。 変数sをゼロクリアするために、memset()が呼び出されています。

        .file   "zero_clear.c"
        .text
        .globl  main
        .align  16, 0x90
        .type   main,@function
main:                                   # @main
        .cfi_startproc
# BB#0:
        pushq   %rbp
.Ltmp2:
        .cfi_def_cfa_offset 16
.Ltmp3:
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
.Ltmp4:
        .cfi_def_cfa_register %rbp
        subq    $96, %rsp
        movl    $0, %eax
        movabsq $64, %rdx
        leaq    -80(%rbp), %rcx
        movl    $0, -4(%rbp)
        movl    %edi, -8(%rbp)
        movq    %rsi, -16(%rbp)
        movq    %rcx, %rdi
        movl    %eax, %esi
        movl    %eax, -84(%rbp)         # 4-byte Spill
        callq   memset
        movl    -84(%rbp), %edi         # 4-byte Reload
        callq   exit
.Ltmp5:
        .size   main, .Ltmp5-main
        .cfi_endproc
 
 
        .section        ".note.GNU-stack","",@progbits

C99で追加された高度な初期化

C99では、配列の初期化が拡張されました。 詳しくは、配列の初期化 指示付きの初期化指定子をご参照ください。

関連項目

  1. 配列の初期化
  2. 配列の要素数を調べる
  3. 配列の初期化 指示付きの初期化指定子