C ++ Catatan: Array Inisialisasi memiliki daftar yang bagus atas inisialisasi array. Saya punya
int array[100] = {-1};
mengharapkannya menjadi penuh dengan -1 tetapi tidak, hanya nilai pertama dan sisanya adalah 0 dicampur dengan nilai acak.
Kode
int array[100] = {0};
berfungsi dengan baik dan menetapkan setiap elemen ke 0.
Apa yang saya lewatkan di sini .. Tidak bisakah seseorang menginisialisasi jika nilainya tidak nol?
Dan 2: Apakah inisialisasi default (seperti di atas) lebih cepat daripada loop biasa melalui seluruh array dan menetapkan nilai atau apakah itu melakukan hal yang sama?
{0}
bukan kasus khusus untuk struct atau array. Aturannya adalah elemen tanpa inisialisasi diinisialisasi seolah-olah mereka memiliki0
inisialisasi. Jika ada agregat bersarang (mis.struct x array[100]
) Maka inisialisasi diterapkan pada non-agregat dalam urutan "baris-utama"; kawat gigi secara opsional dapat dihilangkan dengan melakukan hal ini.struct x array[100] = { 0 }
valid dalam C; dan valid dalam C ++ selama anggota pertamastruct X
accepts0
sebagai initializer.{ 0 }
tidak istimewa dalam C, tetapi jauh lebih sulit untuk menentukan tipe data yang tidak dapat diinisialisasi dengan itu karena tidak ada konstruktor dan dengan demikian tidak ada cara untuk berhenti0
dari yang secara implisit dikonversi dan ditugaskan ke sesuatu .Jawaban:
Menggunakan sintaks yang Anda gunakan,
mengatakan "atur elemen pertama ke
-1
dan sisanya ke0
" karena semua elemen yang dihilangkan diatur ke0
.Di C ++, untuk mengatur semuanya
-1
, Anda dapat menggunakan sesuatu sepertistd::fill_n
(dari<algorithm>
):Di C portabel, Anda harus memutar loop Anda sendiri. Ada ekstensi kompiler atau Anda dapat bergantung pada perilaku yang ditentukan implementasi sebagai pintasan jika itu dapat diterima.
sumber
#include <algorithm>
adalah header yang tepat,<vector>
mungkin atau tidak mungkin memasukkannya secara tidak langsung, yang akan tergantung pada implementasi Anda.int
s yang diinginkan dan memperluasnya ke inisialisasi array.fill_n
untuk mengisi seluruh array 2D. Anda perlu mengulangi satu dimensi, sambil mengisi yang lain.std::fill_n
bukan inisialisasi.Ada ekstensi ke kompiler gcc yang memungkinkan sintaks:
Ini akan mengatur semua elemen ke -1.
Ini dikenal sebagai "Inisialisasi yang Ditunjuk" lihat di sini untuk informasi lebih lanjut.
Catatan ini tidak diterapkan untuk kompiler gcc c ++.
sumber
Halaman yang Anda tautkan sudah memberi jawaban ke bagian pertama:
Tidak ada cara bawaan untuk menginisialisasi seluruh array ke beberapa nilai non-nol.
Adapun yang lebih cepat, aturan yang biasa berlaku: "Metode yang memberikan kebebasan paling kompiler mungkin lebih cepat".
hanya memberitahu kompiler "atur 100 ints ini ke nol", yang dapat dioptimalkan kompiler secara bebas.
jauh lebih spesifik. Ini memberitahu kompiler untuk membuat variabel iterasi
i
, memberi tahu urutan di mana elemen harus diinisialisasi, dan sebagainya. Tentu saja, kompiler cenderung untuk mengoptimalkan itu, tetapi intinya adalah di sini Anda terlalu menentukan masalah, memaksa kompiler bekerja lebih keras untuk mendapatkan hasil yang sama.Akhirnya, jika Anda ingin mengatur array ke nilai bukan nol, Anda harus (dalam C ++, setidaknya) menggunakan
std::fill
:Sekali lagi, Anda bisa melakukan hal yang sama dengan array, tetapi ini lebih ringkas, dan memberi kompilator lebih banyak kebebasan. Anda hanya mengatakan bahwa Anda ingin seluruh array diisi dengan nilai 42. Anda tidak mengatakan apa-apa tentang urutan yang harus dilakukan, atau apa pun.
sumber
C ++ 11 memiliki opsi lain (tidak sempurna):
sumber
std::fill(begin(a), end(a), -1)
Dengan {} Anda menetapkan elemen sebagaimana dinyatakan; sisanya diinisialisasi dengan 0.
Jika tidak ada
= {}
untuk memulai, konten tidak terdefinisi.sumber
Halaman yang Anda tautkan menyatakan
Masalah kecepatan: Perbedaan apa pun akan diabaikan untuk array sekecil ini. Jika Anda bekerja dengan array besar dan kecepatan jauh lebih penting daripada ukuran, Anda dapat memiliki array const dari nilai default (diinisialisasi pada waktu kompilasi) dan kemudian
memcpy
ke array yang dapat dimodifikasi.sumber
Cara lain menginisialisasi array ke nilai umum, adalah dengan benar-benar menghasilkan daftar elemen dalam serangkaian definisi:
Menginisialisasi array ke nilai umum dapat dengan mudah dilakukan:
Catatan: DUPx diperkenalkan untuk mengaktifkan substitusi makro dalam parameter ke DUP
sumber
Untuk kasus array elemen bita tunggal, Anda dapat menggunakan memset untuk mengatur semua elemen ke nilai yang sama.
Ada contoh di sini .
sumber
Dengan menggunakan
std::array
, kita bisa melakukan ini dengan cara yang cukup mudah di C ++ 14. Dimungkinkan untuk melakukannya hanya di C ++ 11, tetapi sedikit lebih rumit.Antarmuka kami adalah ukuran waktu kompilasi dan nilai default.
Fungsi ketiga terutama untuk kenyamanan, sehingga pengguna tidak harus membangun
std::integral_constant<std::size_t, size>
sendiri, karena itu adalah konstruksi yang cukup bertele-tele. Pekerjaan nyata dilakukan oleh salah satu dari dua fungsi pertama.Kelebihan pertama cukup mudah: Ini membangun
std::array
ukuran 0. Tidak perlu menyalin, kami hanya membangunnya.Kelebihan kedua agak rumit. Ini meneruskan sepanjang nilai yang didapatnya sebagai sumber, dan juga membangun sebuah instance
make_index_sequence
dan hanya memanggil beberapa fungsi implementasi lainnya. Seperti apa fungsi itu?Ini mengkonstruksi argumen ukuran - 1 pertama dengan menyalin nilai yang kami berikan. Di sini, kami menggunakan indeks paket parameter variad kami hanya sebagai sesuatu untuk diperluas. Ada entri ukuran - 1 dalam paket itu (seperti yang kami tentukan dalam konstruksi
make_index_sequence
), dan mereka memiliki nilai 0, 1, 2, 3, ..., ukuran - 2. Namun, kami tidak peduli dengan nilai-nilai tersebut ( jadi kami membatalkannya, untuk membungkam setiap peringatan kompiler). Ekspansi paket parameter memperluas kode kami ke sesuatu seperti ini (dengan asumsi ukuran == 4):Kami menggunakan tanda kurung itu untuk memastikan bahwa ekspansi paket variadic
...
memperluas apa yang kami inginkan, dan juga untuk memastikan kami menggunakan operator koma. Tanpa tanda kurung, akan terlihat seperti kami melewati banyak argumen untuk inisialisasi array kami, tapi sungguh, kami mengevaluasi indeks, membuangnya untuk membatalkan, mengabaikan hasil yang batal, dan kemudian mengembalikan nilai, yang kemudian disalin ke dalam array .Argumen terakhir, yang kami panggil
std::forward
, adalah optimasi kecil. Jika seseorang lewat di std :: string sementara dan mengatakan "buat 5 array ini", kami ingin memiliki 4 salinan dan 1 langkah, bukannya 5 salinan. Thestd::forward
memastikan bahwa kami melakukan ini.Kode lengkap, termasuk tajuk dan beberapa tes unit:
sumber
non_copyable
Jenis Anda sebenarnya dapat disalin dengan caraoperator=
.non_copy_constructible
akan menjadi nama yang lebih akurat untuk objek. Namun, tidak ada tugas di mana pun dalam kode ini, jadi tidak masalah untuk contoh ini.1) Ketika Anda menggunakan penginisialisasi, untuk struct atau array seperti itu, nilai yang tidak ditentukan pada dasarnya dibangun secara default. Dalam kasus tipe primitif seperti int, itu berarti mereka akan memusatkan perhatian. Perhatikan bahwa ini berlaku secara rekursif: Anda bisa memiliki array struct yang berisi array dan jika Anda menentukan hanya bidang pertama dari struct pertama, maka semua sisanya akan diinisialisasi dengan nol dan konstruktor default.
2) Compiler mungkin akan menghasilkan kode initializer yang setidaknya sebagus yang Anda bisa lakukan dengan tangan Saya cenderung lebih suka membiarkan kompiler melakukan inisialisasi untuk saya, bila memungkinkan.
sumber
Di C ++, juga dimungkinkan untuk menggunakan pemrograman meta dan templat variadic. Posting berikut menunjukkan cara melakukannya: Secara terprogram membuat array statis pada waktu kompilasi dalam C ++ .
sumber
Dalam bahasa pemrograman C ++ V4, Stroustrup merekomendasikan penggunaan vektor atau valarrays pada array bawaan. Dengan valarrary's, saat Anda membuatnya, Anda dapat memasukkannya ke nilai tertentu seperti:
Untuk menginisialisasi susunan 7 anggota dengan "7777777".
Ini adalah cara C ++ untuk mengimplementasikan jawaban menggunakan struktur data C ++ alih-alih susunan "biasa C lama".
Saya beralih menggunakan valarray sebagai upaya dalam kode saya untuk mencoba menggunakan C ++ 'isms v. C'isms ....
sumber
Seharusnya fitur standar tetapi karena alasan tertentu itu tidak termasuk dalam standar C atau C ++ ...
Di Fortran Anda bisa melakukan:
tetapi tidak memiliki nomor yang tidak ditandatangani ...
Mengapa C / C ++ tidak bisa hanya mengimplementasikannya. Apakah ini sangat sulit? Sangat konyol harus menulis ini secara manual untuk mencapai hasil yang sama ...
Bagaimana jika itu adalah array 1.000,00 byte? Saya perlu menulis skrip untuk menulisnya untuk saya, atau menggunakan hacks dengan assembly / etc. Ini tidak masuk akal.
Ini sangat portabel, tidak ada alasan untuk itu tidak ada dalam bahasa.
Cukup retas seperti:
Salah satu cara untuk meretasnya adalah melalui preprocessing ... (Kode di bawah ini tidak mencakup kasus tepi, tetapi ditulis untuk dengan cepat menunjukkan apa yang bisa dilakukan.)
sumber
memset
, bahkan dengan array "hardcoded".