Saya memiliki array besar di C (bukan C ++ jika itu membuat perbedaan). Saya ingin menginisialisasi semua anggota dengan nilai yang sama.
Aku bersumpah aku pernah tahu cara sederhana untuk melakukan ini. Saya dapat menggunakan memset()
dalam kasus saya, tetapi tidak adakah cara untuk melakukan ini yang dibangun langsung ke dalam sintaks C?
enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };
danstruct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };
. Jika Anda menghapus elipsis…
, fragmen-fragmen itu mengkompilasi di bawah C99 atau C11.memset()
diskusi spesifik: stackoverflow.com/questions/7202411/... Saya pikir ini hanya berfungsi untuk 0.Jawaban:
Kecuali jika nilainya 0 (dalam hal ini Anda dapat menghilangkan beberapa bagian dari penginisialisasi dan elemen yang sesuai akan diinisialisasi ke 0), tidak ada cara mudah.
Namun, jangan mengabaikan solusi yang jelas:
Elemen dengan nilai yang hilang akan diinisialisasi ke 0:
Jadi ini akan menginisialisasi semua elemen ke 0:
Di C ++, daftar inisialisasi kosong juga akan menginisialisasi setiap elemen ke 0. Ini tidak diizinkan dengan C:
Ingatlah bahwa objek dengan durasi penyimpanan statis akan diinisialisasi ke 0 jika tidak ada initializer yang ditentukan:
Dan "0" tidak berarti "semua-bit-nol", jadi menggunakan yang di atas lebih baik dan lebih portabel daripada memset (). (Nilai titik apung akan diinisialisasi ke +0, pointer ke nilai nol, dll.)
sumber
Jika kompiler Anda adalah GCC, Anda dapat menggunakan sintaks berikut:
Lihat deskripsi terperinci: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html
sumber
int
s ke dalam data statis, yaitu 256 K - persis peningkatan ukuran yang Anda amati.int
s secara statis , sepertiint foo1 = 1, foo2 = 1, ..., foo65536 =1;
Anda akan mendapatkan peningkatan ukuran yang sama.bool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}
, meskipun saya tidak yakin itu lebih mudah dibaca daripada bentuk lengkap.Untuk menginisialisasi array besar secara statis dengan nilai yang sama, tanpa beberapa copy-paste, Anda dapat menggunakan makro:
Jika Anda perlu mengubah nilainya, Anda harus melakukan penggantian hanya di satu tempat.
Edit: kemungkinan ekstensi yang berguna
(milik Jonathan Leffler )
Anda dapat dengan mudah menggeneralisasi ini dengan:
Varian dapat dibuat menggunakan:
yang bekerja dengan struktur atau susunan majemuk.
nama makro bisa dinegosiasikan.
sumber
VAL_1X
bukan bilangan bulat tunggal tetapi daftar. Seperti negara yang Dapat Diakses, ini juga merupakan cara untuk menggunakan sistem embedded di mana Anda ingin mendefinisikan nilai init dari EEPROM atau memori Flash. Dalam kedua kasus, Anda tidak dapat menggunakanmemset()
.Jika Anda ingin memastikan bahwa setiap anggota array diinisialisasi secara eksplisit, cukup hapus dimensi dari deklarasi:
Compiler akan menyimpulkan dimensi dari daftar initializer. Sayangnya, untuk array multidimensi hanya dimensi terluar yang dapat dihilangkan:
tidak apa-apa, tapi
tidak.
sumber
int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
Saya melihat beberapa kode yang menggunakan sintaks ini:
Di mana itu menjadi sangat berguna adalah jika Anda membuat array yang menggunakan enum sebagai indeks:
Ini menjaga segala sesuatunya tetap teratur, bahkan jika Anda menulis beberapa nilai enum di luar urutan.
Lebih lanjut tentang teknik ini dapat ditemukan di sini dan di sini .
sumber
char const *array[] = { ... };
atau bahkanchar const * const array[] = { ... };
, bukan?Saya pikir ini lebih baik daripada
memetikan ukuran perubahan array.
sumber
memset(myArray, VALUE, ARRAY_SIZE);
Anda dapat melakukan hal inisialisasi statis keseluruhan seperti yang dijelaskan di atas, tetapi ini bisa sangat menyebalkan ketika ukuran array Anda berubah (ketika array Anda embiggens, jika Anda tidak menambahkan inisialisasi tambahan yang sesuai Anda mendapatkan sampah).
memset memberi Anda hit runtime untuk melakukan pekerjaan, tetapi tidak ada hit ukuran kode yang dilakukan dengan benar kebal terhadap perubahan ukuran array. Saya akan menggunakan solusi ini di hampir semua kasus ketika array lebih besar dari, katakanlah, beberapa lusin elemen.
Jika benar-benar penting bahwa array dinyatakan secara statis, saya akan menulis sebuah program untuk menulis program untuk saya dan menjadikannya bagian dari proses build.
sumber
memset
untuk menginisialisasi array?Ini cara lain:
Lihat:
C-Extensions
Inits yang ditunjuk
Kemudian ajukan pertanyaan: Kapan seseorang dapat menggunakan ekstensi C?
Contoh kode di atas adalah dalam sistem tertanam dan tidak akan pernah melihat cahaya dari kompiler lain.
sumber
Untuk menginisialisasi tipe data 'normal' (seperti array int), Anda dapat menggunakan notasi braket, tetapi akan nol nilai setelah yang terakhir jika masih ada ruang dalam array:
sumber
Jika array kebetulan adalah int atau apa pun dengan ukuran int atau ukuran pola mem Anda cocok dengan waktu yang tepat menjadi int (yaitu semua nol atau 0xA5A5A5A5), cara terbaik adalah menggunakan memset () .
Kalau tidak panggil memcpy () dalam satu lingkaran untuk memindahkan indeks.
sumber
Jawaban yang sedikit tidak jelas; tulis pernyataannya
dalam bahasa yang mampu menggunakan array favorit Anda (milik saya adalah Fortran, tetapi ada banyak lainnya), dan menautkannya ke kode C Anda. Anda mungkin ingin membungkusnya menjadi fungsi eksternal.
sumber
Ada cara cepat untuk menginisialisasi array jenis apa pun dengan nilai yang diberikan. Ini bekerja sangat baik dengan array yang besar. Algoritma adalah sebagai berikut:
Untuk
1 000 000
elemenint
array, ini 4 kali lebih cepat dari inisialisasi loop biasa (i5, 2 core, 2.3 GHz, memori 4GiB, 64 bit):loop runtime 0.004248 [seconds]
memfill() runtime 0.001085 [seconds]
sumber
memfill()
kode membutuhkan sekitar 1200 μs. Namun, pada iterasi selanjutnya, loop membutuhkan sekitar 900-1000 μs sementaramemfill()
kode membutuhkan 1000-1300 μs. Iterasi pertama mungkin dipengaruhi oleh waktu untuk mengisi cache. Balikkan tes danmemfill()
lambat pertama kali.Tidak ada yang menyebutkan urutan indeks untuk mengakses elemen dari array yang diinisialisasi. Kode contoh saya akan memberikan contoh ilustrasi untuk itu.
Outputnya adalah:
sumber
<iostream>
tidak validC
karenastd::cout
,,std::cin
dll adalah bagian daristd::namespace
danC
tidak mendukungnamespaces
. Coba gunakan<stdio.h>
untukprintf(...)
.Memotong semua obrolan, jawaban singkatnya adalah jika Anda mengaktifkan optimisasi pada waktu kompilasi Anda tidak akan melakukan yang lebih baik dari ini:
Bonus tambahan: kode ini dapat dibaca :)
sumber
contoh: int array [10]; memset (array, -1, 10 * sizeof (int));
sumber
Ini akan memberikan o / p 5 5 5 5 5 5 ...... sampai ukuran seluruh array
sumber
Saya tahu pengguna
Tarski
menjawab pertanyaan ini dengan cara yang sama, tetapi saya menambahkan beberapa detail lagi. Maafkan beberapa C saya karena saya agak berkarat karena saya lebih cenderung ingin menggunakan C ++, tapi begini saja.Jika Anda mengetahui ukuran array sebelumnya ...
Ada beberapa peringatan di atas; satu adalah yang
UINT myArray[size];
tidak langsung diinisialisasi pada deklarasi, namun blok kode berikutnya atau panggilan fungsi melakukan inisialisasi setiap elemen array ke nilai yang sama yang Anda inginkan. Peringatan lainnya adalah, Anda harus menulisinitializing function
untuk setiaptype
Anda akan mendukung dan Anda juga harus memodifikasiprintArray()
fungsi untuk mendukung jenis-jenis tersebut.Anda dapat mencoba kode ini dengan pengompil online yang ditemukan di sini .
sumber
Untuk inisialisasi tertunda (mis. Inisialisasi konstruktor anggota kelas) pertimbangkan:
sumber
Saya tahu pertanyaan asli secara eksplisit menyebutkan C dan bukan C ++, tetapi jika Anda (seperti saya) datang ke sini mencari solusi untuk array C ++, berikut ini adalah trik yang rapi:
Jika kompiler Anda mendukung ekspresi lipat , Anda dapat menggunakan templat sulap dan
std::index_sequence
untuk menghasilkan daftar penginisialisasi dengan nilai yang Anda inginkan. Dan Anda dapat meratakannyaconstexpr
dan merasa seperti bos:Anda dapat melihat kode di tempat kerja (di Wandbox)
sumber
Saya tidak melihat persyaratan dalam pertanyaan, jadi solusinya harus generik: inisialisasi array multidimensi mungkin tidak ditentukan dibangun dari elemen struktur mungkin tidak ditentukan dengan nilai anggota awal:
Hasil:
EDIT:
start+element_size
diubah menjadi(char*)start+element_size
sumber
sizeof(void)
ini valid.memcpy()
tumpang tindih kedua dengan ruang tujuan. Dengan implementasi naif darimemcpy()
, itu bisa berfungsi tetapi tidak diperlukan bahwa sistem membuatnya berfungsi.Kembali pada hari itu (dan saya tidak mengatakan itu ide yang baik), kami akan menetapkan elemen pertama dan kemudian:
memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);
Bahkan tidak yakin itu akan berfungsi lagi (yang akan tergantung pada implementasi memcpy) tetapi ia bekerja dengan berulang kali menyalin elemen awal ke yang berikutnya - bahkan berfungsi untuk susunan struktur.
sumber
memcpy
tetapi perintah penyalinan bottom-up atau top-down yang ditentukan jika tumpang tindih, tetapi tidak.memmove()
tidak membuatnya bekerja.Jika Anda maksud secara paralel, saya pikir operator koma ketika digunakan bersama dengan ekspresi dapat melakukan itu:
atau jika Anda maksud dalam satu konstruksi, Anda bisa melakukannya dalam for for:
// Perhatikan operator koma dalam daftar argumen bukan operator paralel yang dijelaskan di atas;
Anda dapat menginisialisasi deklarasi array:
Anda dapat melakukan panggilan ke malloc / calloc / sbrk / mengalokasikan / dll untuk mengalokasikan wilayah penyimpanan yang tetap ke objek:
dan akses anggota dengan:
Dll
sumber