Menginisialisasi struct ke 0

116

Jika saya memiliki struct seperti ini:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

Apa cara termudah untuk menginisialisasi struct ini ke 0? Apakah yang berikut ini cukup?

myStruct _m1 = {0};

atau Apakah saya perlu secara eksplisit memasukkan setiap anggota ke 0?

myStruct _m2 = {0,0};
Daan Timmer
sumber

Jawaban:

142

Cara pertama paling mudah ( tidak perlu banyak mengetik ), dan dijamin berhasil, semua anggota akan disetel ke 0[Ref 1] .
Yang kedua lebih mudah dibaca.

Pilihannya tergantung pada preferensi pengguna atau yang diamanatkan standar pengkodean Anda.

[Ref 1] Referensi C99 Standar 6.7.8.21:

Jika ada lebih sedikit penginisialisasi dalam daftar yang diapit kurung kurawal daripada jumlah elemen atau anggota agregat, atau lebih sedikit karakter dalam string literal yang digunakan untuk menginisialisasi larik dengan ukuran yang diketahui daripada jumlah elemen dalam larik, sisa agregat harus diinisialisasi secara implisit sama dengan objek yang memiliki durasi penyimpanan statis.

Good Read:
C dan C ++: Inisialisasi parsial dari struktur otomatis

Alok Save
sumber
9
Juga, saya menggunakan = {};Namun saya tidak yakin apakah ini valid.
William Entriken
15
Tanda kurung kurawal kosong @FullDecent untuk inisialisasi adalah ekstensi GNU.
a3f
2
@ alias65536 Pertanyaannya adalah C bukan C ++.
a3f
3
Saya mendapat kesalahan: "kurung kurawal hilang di sekitar penginisialisasi [-Werror = tanda kurung kurawal]" mungkin karena array anggota: /
DrumM
3
@Denny. Saya tidak setuju. Saya sudah tahu foo = {0}artinya. Jika saya melihat foo = ZERO_FULL, saya harus grep untuk definisi ZERO_FULL.
Andrew Bainbridge
32

Jika datanya adalah variabel statis atau global, secara default diisi nol, jadi deklarasikan saja myStruct _m;

Jika datanya adalah variabel lokal atau zona yang dialokasikan heap, hapus dengan memsetseperti:

memset(&m, 0, sizeof(myStruct));

Kompiler saat ini (misalnya versi terbaru gcc) mengoptimalkannya dengan cukup baik dalam praktiknya. Ini hanya berfungsi jika semua nilai nol (termasuk penunjuk nol dan titik mengambang nol) direpresentasikan sebagai semua bit nol, yang benar pada semua platform yang saya ketahui (tetapi standar C mengizinkan implementasi yang salah; saya tidak tahu penerapan seperti itu) .

Anda mungkin dapat membuat kode myStruct m = {};atau myStruct m = {0};(meskipun anggota pertama dari myStructbukan skalar).

Perasaan saya adalah bahwa menggunakan memsetuntuk struktur lokal adalah yang terbaik, dan ini menyampaikan fakta yang lebih baik bahwa pada waktu proses, sesuatu harus dilakukan (sementara biasanya, data global dan statis dapat dipahami sebagai diinisialisasi pada waktu kompilasi, tanpa biaya apa pun pada waktu proses) .

Basile Starynkevitch
sumber
7
Tidak ada jaminan bahwa menyetel semua byte struct 0menjadi sama dengan menginisialisasi semua anggota struct dengan 0. Pada banyak platform, ini benar, tetapi tidak secara universal.
Sander De Dycker
1
Bisakah Anda membagikan contoh, Sander? Rasa ingin tahu yang tulus. (Jelas, tidak universal benar tidak selalu berarti ada pengecualian yang mudah dijelaskan, tetapi jika ada ...)
Steven Fisher
2
Standar C mengizinkan penunjuk nol (atau bilangan titik mengambang nol) untuk direpresentasikan dalam memori dengan sesuatu yang lain selain semua bit nol. Sangat sedikit dan implementasi aneh yang melakukan itu (saya tidak bisa menyebutkan satu pun).
Basile Starynkevitch
-1, Anda mungkin menemukan inisialisasi yang OP bertanya tentang jelek, tapi persis seperti yang terlihat oleh standar dan dapat dengan mudah dioptimalkan oleh semua kompiler. Kemudian, formulir {}tersebut bukan C yang valid tetapi hanya tersedia di C ++.
Jens Gustedt
7
@ Steven: Saya hanya bisa memikirkan platform yang tidak jelas dan / atau lama. FAQ C memiliki daftar platform yang memiliki NULLpenunjuk yang tidak semuanya 0bit: c-faq.com/null/machexamp.html . Dan kemudian ada kemungkinan platform tidak menggunakan IEEE 754 untuk mewakili nilai floating point, tetapi menggunakan beberapa representasi lain yang tidak memiliki semua nilai 0bit 0.0- tetapi saya tidak tahu platform seperti itu.
Sander De Dycker
19

Lihat §6.7.9 Inisialisasi:

21 Jika ada lebih sedikit penginisialisasi dalam daftar yang diapit kurung kurawal daripada ada elemen atau anggota agregat, atau lebih sedikit karakter dalam string literal yang digunakan untuk menginisialisasi larik dengan ukuran yang diketahui daripada jumlah elemen dalam larik, sisa agregat harus diinisialisasi secara implisit sama dengan objek yang memiliki durasi penyimpanan statis.

Jadi, ya keduanya berhasil. Perhatikan bahwa di C99 cara baru inisialisasi, yang disebut inisialisasi yang ditunjuk dapat digunakan juga:

myStruct _m1 = {.c2 = 0, .c1 = 1};
dirkgently
sumber
Terutama ini sudah C89: open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139 (Penting untuk target pemrosesan sinyal tertentu)
Tobias