概要
C 言語で構造体を初期化する方法には、
- 一つずつ代入
- 複合リテラルを使う
memset()
の三つがあるとのこと。
memset() では浮動小数点型やポインタ型のメンバに対して保証がないとのことなので、複合リテラルを使用する方法の検証を行った。
Ref:
構造体の全メンバを 0 で埋める | Programming Place Plus C言語編 逆引き
複合リテラル
複合リテラルとは
複合リテラルとは、構造体や配列のリテラルのこと。リテラルとは「値をソースコードなどにべた書きしたもの」なので、複合リテラルとは「構造体や配列の中身をソースコードにべた書きしたもの」となる。
C99 から追加された機能なので、C95 以前のコンパイラでは動かないとのこと。
記法
複合リテラルの記法は↓のカンジ。
(型名){数値}
0 で初期化する方法は↓の通り。
typedef struct{
int hoge;
int fuga;
} piyo_t;
// ------------------
piyo_t foo;
foo = (piyo_t){0}; // 初期化.
追記(2024/7/3)
変数は定義と同時に初期化しよう、ヨシ!
コメント下さった方々、ありがとうございます
typedef struct{
int hoge;
int fuga;
} piyo_t;
// ------------------
piyo_t foo = (piyo_t){0}; // 初期化.
実施例
実際にやってみる。
# include <stdio.h>
# include <string.h>
typedef struct {
int first;
double second;
int *third;
} numbers_t;
void zero_set_memset(){
numbers_t num;
printf("-------case of memset------\n");
memset(&num, 0, sizeof(numbers_t));
printf("first: %d, second: %lf, third: %p\n", num.first, num.second, num.third);
if(num.third == NULL){
printf("num.third is NULL\n");
}
}
void zero_set_fukugo_literal(){
numbers_t num;
printf("-------case of literal------\n");
num = (numbers_t){0};
printf("first: %d, second: %lf, third: %p\n", num.first, num.second, num.third);
if(num.third == NULL){
printf("num.third is NULL\n");
}
}
// 追記(2024/7/3).
// main() は int で定義するのが一般的.
void main(){
zero_set_memset();
printf("\n");
zero_set_fukugo_literal();
}
実行すると↓のようになる。
hoge@fuga-VirtualBox:~/tmp$ gcc -o ./fukugo_liretal ./fukugo_literal.c
hoge@fuga-VirtualBox:~/tmp$ ./fukugo_liretal
-------case of memset------
first: 0, second: 0.000000, third: (nil)
num.third is NULL
-------case of literal------
first: 0, second: 0.000000, third: (nil)
num.third is NULL
hoge@fuga-VirtualBox:~/tmp$
複合リテラルでも問題なく初期化できることが確認できた。
まとめ
構造体の初期化には、念のため複合リテラルを使用しよう、ヨシ!