Kapan {0}
digunakan untuk menginisialisasi objek, apa artinya? Saya tidak dapat menemukan referensi ke {0}
mana pun, dan karena kurung kurawal pencarian Google tidak membantu.
Kode contoh:
SHELLEXECUTEINFO sexi = {0}; // what does this do?
sexi.cbSize = sizeof(SHELLEXECUTEINFO);
sexi.hwnd = NULL;
sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
sexi.lpFile = lpFile.c_str();
sexi.lpParameters = args;
sexi.nShow = nShow;
if(ShellExecuteEx(&sexi))
{
DWORD wait = WaitForSingleObject(sexi.hProcess, INFINITE);
if(wait == WAIT_OBJECT_0)
GetExitCodeProcess(sexi.hProcess, &returnCode);
}
Tanpa itu, kode di atas akan macet saat runtime.
Satu hal yang perlu diperhatikan adalah bahwa teknik ini tidak akan mengatur padding byte ke nol. Sebagai contoh:
Tidak sama dengan:
Dalam kasus pertama, pad byte antara c dan i tidak diinisialisasi. Kenapa kamu peduli? Nah, jika Anda menyimpan data ini ke disk atau mengirimnya melalui jaringan atau apa pun, Anda bisa memiliki masalah keamanan.
sumber
Perhatikan bahwa penginisialisasi agregat kosong juga berfungsi:
sumber
Sebagai jawaban mengapa
ShellExecuteEx()
crash:SHELLEXECUTEINFO
struct "sexi" Anda memiliki banyak anggota dan Anda hanya menginisialisasi beberapa dari mereka.Misalnya, anggota
sexi.lpDirectory
dapat menunjuk ke mana saja, tetapiShellExecuteEx()
masih akan mencoba menggunakannya, maka Anda akan mendapatkan pelanggaran akses memori.Ketika Anda memasukkan baris:
sebelum sisa pengaturan struktur Anda, Anda memberi tahu kompiler untuk membatalkan semua anggota struktur sebelum Anda menginisialisasi yang spesifik. Anda
ShellExecuteEx()
tahu bahwa jikasexi.lpDirectory
nol, ia harus mengabaikannya.sumber
Saya juga menggunakannya untuk menginisialisasi string misalnya.
sumber
{0}
adalah penginisialisasi yang valid untuk semua jenis (objek lengkap), dalam C dan C ++. Ini adalah idiom umum yang digunakan untuk menginisialisasi objek ke nol (baca terus untuk melihat apa artinya).Untuk tipe skalar (tipe aritmatika dan pointer), kurung tidak diperlukan, tetapi mereka diizinkan secara eksplisit. Mengutip konsep N1570 dari standar ISO C, bagian 6.7.9:
Ini menginisialisasi objek ke nol (
0
untuk bilangan bulat,0.0
untuk floating-point, pointer nol untuk pointer).Untuk jenis non-skalar (struktur, array, serikat),
{0}
menentukan bahwa elemen pertama objek diinisialisasi ke nol. Untuk struktur yang mengandung struktur, susunan struktur, dan sebagainya, ini diterapkan secara rekursif, sehingga elemen skalar pertama diatur ke nol, sesuai jenisnya. Seperti pada penginisialisasi apa pun, elemen apa pun yang tidak ditentukan ditetapkan ke nol.Kawat gigi menengah (
{
,}
) dapat dihilangkan; misalnya keduanya valid dan setara:itulah sebabnya Anda tidak harus menulis, misalnya,
{ { 0 } }
untuk jenis yang elemen pertamanya adalah non-skalar.Jadi ini:
adalah cara singkat menginisialisasi
obj
ke nol, yang berarti bahwa setiap sub-objek skalarobj
diatur ke0
jika itu adalah bilangan bulat,0.0
jika itu floating-point, atau null pointer jika itu adalah pointer.Aturannya mirip untuk C ++.
Dalam kasus khusus Anda, karena Anda menetapkan nilai ke
sexi.cbSize
dan sebagainya, jelas bahwa ituSHELLEXECUTEINFO
adalah tipe struct atau kelas (atau mungkin gabungan, tetapi mungkin tidak), jadi tidak semua ini berlaku, tetapi seperti yang saya katakan{ 0 }
adalah umum idiom yang dapat digunakan dalam situasi yang lebih umum.Ini tidak (harus) setara dengan menggunakan
memset
untuk mengatur representasi objek ke semua-bit-nol. Baik floating-point0.0
maupun null pointer harus direpresentasikan sebagai all-bits-zero, dan{ 0 }
penginisialisasi tidak harus menetapkan padding byte ke nilai tertentu. Pada sebagian besar sistem, kemungkinan besar memiliki efek yang sama.sumber
{0}
bukan penginisialisasi yang valid untuk objek tanpa konstruktor yang menerima0
; juga untuk agregat yang elemen pertamanya adalah seperti itu (atau agregat tanpa elemen)Sudah beberapa saat sejak saya bekerja di c / c ++ tetapi IIRC, cara pintas yang sama dapat digunakan untuk array juga.
sumber
Saya selalu bertanya-tanya, mengapa Anda harus menggunakan sesuatu seperti
Berikut ini adalah contoh kasus untuk dijelaskan:
check.c
Saya mengkompilasi dengan
gcc -O2 -o check check.c
dan kemudian output tabel simbol denganreadelf -s check | sort -k 2
(ini dengan gcc 4.6.3 di ubuntu 12.04.2 pada sistem x64). Kutipan:Bagian penting di sini adalah, yaitu
my_zero_struct
setelah__bss_start
. Bagian ".bss" dalam program C adalah bagian dari memori yang disetel ke nol sebelummain
disebut see wikipedia on .bss .Jika Anda mengubah kode di atas menjadi:
Maka executable "check" yang dihasilkan terlihat persis sama setidaknya dengan kompiler gcc 4.6.3 di ubuntu 12.04.2; yang
my_zero_struct
masih dalam.bss
bagian dan dengan demikian maka akan secara otomatis diinisialisasi ke nol, sebelummain
disebut.Petunjuk dalam komentar, bahwa
memset
mungkin menginisialisasi struktur "penuh" juga bukan perbaikan, karena.bss
bagian ini dibersihkan sepenuhnya yang juga berarti struktur "penuh" diatur ke nol.Ini mungkin bahwa standar bahasa C tidak menyebutkan semua ini, tapi di dunia C compiler nyata Aku belum pernah melihat perilaku yang berbeda.
sumber
Ini adalah gula sintaksis untuk menginisialisasi seluruh struktur Anda ke nilai kosong / nol / nol.
Versi panjang
Versi pendek
Bukankah itu jauh lebih mudah?
Ini juga bagus karena:
ZeroMemory
sumber
{0} adalah array anonim yang mengandung elemennya sebagai 0.
Ini digunakan untuk menginisialisasi satu atau semua elemen array dengan 0.
mis. int arr [8] = {0};
Dalam hal ini semua elemen arr akan diinisialisasi sebagai 0.
sumber
{0}
bukan array anonim. Itu bahkan bukan ekspresi. Ini adalah inisialisasi.