Bagaimana saya bisa mendeklarasikan dan mendefinisikan beberapa variabel dalam satu baris menggunakan C ++?


173

Saya selalu berpikir bahwa jika saya menyatakan tiga variabel ini bahwa mereka semua akan memiliki nilai 0

int column, row, index = 0;

Tapi saya menemukan bahwa hanya indeks yang sama dengan nol & yang lainnya adalah sampah seperti 844553 & 2423445.

Bagaimana saya bisa menginisialisasi semua variabel menjadi nol tanpa mendeklarasikan setiap variabel pada baris baru?


36
Hati-hati dengan deklarasi multi-variabel satu baris itu. Lebih mudah daripada yang Anda pikirkan untuk mendeklarasikan pointer int diikuti oleh daftar bilangan bulat biasa ( int* a, b, c;tidak seperti apa tampilannya).
Chris Eberle

4
Hanya ada tiga variabel, Bung, tulis =0untuk masing-masing dalam definisi mereka. Dan, jika Anda benar-benar menginginkan banyak variabel, maka cobalah sebuah array: int a[10]={0}akan menginisialisasi masing a[i]- masing ke 0 untuk Anda.
Stan

Kompilator seharusnya tidak membiarkan konstruk itu jika itu akan berperilaku berbeda dari apa yang diharapkan oleh seorang programmer yang masuk akal ... imho
cph2117

1
@ cph2117 Seorang programmer yang masuk akal akan berpikir 'hmm, sintaks ini dapat berarti beberapa hal yang berbeda tergantung pada bagaimana tata bahasa mengikat sesuatu' , mencari Standar untuk mencari tahu mana yang benar, dan melanjutkannya.
underscore_d

Berhentilah melakukan ini. Itu hanya membuat kode lebih sulit untuk dibaca. Inti dari penulisan kode dalam bahasa tingkat tinggi adalah membuatnya mudah bagi pengelola untuk membaca.
Martin York

Jawaban:



162

Ketika Anda menyatakan:

int column, row, index = 0;

Hanya indeks yang diatur ke nol.

Namun Anda dapat melakukan hal berikut:

int column, row, index;
column = index = row = 0;

Tetapi secara pribadi saya lebih suka hal-hal berikut yang telah ditunjukkan.
Ini bentuk yang lebih mudah dibaca menurut saya.

int column = 0, row = 0, index = 0;

atau

int column = 0;
int row = 0;
int index = 0;

3
Di antara dua yang terakhir saya memutuskan berdasarkan apakah kedua nilai tersebut harus benar-benar bertipe sama ( bool previousInputValue, presentInputValue;) atau jika keduanya bertipe sama sekarang tetapi tidak benar-benar perlu ( uint8_t height, width;mungkin berubah menjadi uint8_t height; uint16_t width;di masa depan dan seharusnya menjadi uint8_t height; uint8_t width;memulai dengan).
altendky

Karena menulis uint8_t height; uint16_t width;bukan uint8_t height, width;menyimpan 10 karakter di masa depan. :-) Anda tentu saja dapat melakukannya sesuka Anda. Pastikan Anda membuatnya mudah dibaca. Jadi bentuk terakhir adalah yang paling eksplisit.
Matt

Bentuk terakhir tentu saja yang paling eksplisit dalam menyatakan jenis setiap variabel dan memperjelas bahwa masing-masing diinisialisasi. Yang mengatakan, itu tidak eksplisit tentang apakah kolom dan baris diharapkan menjadi tipe yang sama atau tidak. Mungkin kita berdua lebih suka dengan kesaksian int presentValue = 0; typeof(presentValue) previousValue = presentValue;, tapi saya percaya itu typeof()adalah perpanjangan GCC non-standar.
altendky

49

Seperti yang dikatakan @Josh, jawaban yang benar adalah:

int column = 0,
    row = 0,
    index = 0;

Anda harus berhati-hati terhadap hal yang sama dengan pointer. Ini:

int* a, b, c;

Setara dengan:

int *a;
int b;
int c;

34
Aku benci benda penunjuk itu, tidak masuk akal. Tanda bintang adalah bagian dari tipenya, jadi itu harus berlaku untuk semuanya. Bayangkan jika unsigned long x, y;dinyatakan xsebagai unsigned longtetapi yhanya unsigned, alias unsigned int! Itu persis sama! </rant>
Cam Jackson

6
Masuk akal. "int * a, b, c;"
Jeroen

7
@ JoenBollen Yah ya, masuk akal jika Anda menulis tanda bintang pointer Anda di sebelah nama variabel, bukan tipe, tapi itu sendiri tidak masuk akal. Seperti yang saya katakan di atas, tanda bintang adalah bagian dari tipe, bukan bagian dari nama, sehingga harus dikelompokkan dengan tipe!
Cam Jackson

11
Sebagai sisi tidak, sebenarnya masuk akal bahwa * tidak selalu merupakan bagian dari tipe, sebagai int *acara yang *amewakili intnilai.
mdenton8

2
Intinya telah dibuat tetapi hanya untuk menambahnya batal pada dasarnya adalah kurangnya jenis tetapi Anda masih dapat membuat pointer ke sana. Jadi mengapa void* aakan dikompilasi dan void *a, b, ctidak. Rasionalisasi ini bekerja untuk saya.
Josh C

25

Jika Anda mendeklarasikan satu variabel / objek per baris tidak hanya menyelesaikan masalah ini, tetapi membuat kode lebih jelas dan mencegah kesalahan konyol saat mendeklarasikan pointer.

Untuk langsung menjawab pertanyaan Anda, Anda harus menginisialisasi setiap variabel menjadi 0 secara eksplisit. int a = 0, b = 0, c = 0;.


16
int column(0), row(0), index(0);

Perhatikan bahwa formulir ini juga akan berfungsi dengan tipe kustom, terutama ketika konstruktornya mengambil lebih dari satu argumen.


2
dan saat ini dengan inisialisasi seragam (menunggu C ++ 17 memperbaiki ini untuk auto...): kolom int { 0 } , baris { 0 } , indeks { 0 } ;
underscore_d

5

Mulai 2k18, Anda dapat menggunakan Structured Bindings :

#include <iostream>
#include <tuple>

int main () 
{
    auto [hello, world] = std::make_tuple("Hello ", "world!");
    std::cout << hello << world << std::endl;
    return 0;
}

Demo


4

Kemungkinan pendekatan:

  • Inisialisasi semua variabel lokal dengan nol.
  • Memiliki array, memsetatau {0}array.
  • Jadikan global atau statis.
  • Masukkan mereka struct, dan memsetatau memiliki konstruktor yang akan menginisialisasi mereka ke nol.

#define COLUMN 0 #define ROW 1 #define INDEX 2 #define AR_SIZE 3 int Data [ AR_SIZE ]; // Hanya sebuah ide.
Ajay

Maaf, maksud saya, mengapa Anda memasukkan baris " Miliki array, memset atau {0} array. " Dalam jawaban Anda?
Mateen Ulhaq

memset (Data, 0, sizeof (Data)); // Jika ini bisa dikemas secara logis.
Ajay

2

Saya tidak akan merekomendasikan ini, tetapi jika Anda benar-benar menjadi satu baris dan hanya menulis 0 sekali, Anda juga dapat melakukan ini:

int row, column, index = row = column = 0;

0

Seperti yang telah disebutkan orang lain, dari C ++ 17 dan seterusnya Anda dapat menggunakan binding terstruktur untuk beberapa tugas variabel.

Menggabungkan ini dengan std::arraydan mengurangi argumen templat kita dapat menulis fungsi yang memberikan nilai ke sejumlah variabel acak tanpa mengulang jenis atau nilai .

#include <iostream>
#include <array>

template <int N, typename T> auto assign(T value)
{
    std::array<T, N> out;
    out.fill(value);
    return out;
}

int main()
{
    auto [a, b, c] = assign<3>(1);

    for (const auto& v : {a, b, c})
    {
        std::cout << v << std::endl;
    }

    return 0;
}

Demo


-13

Ketika Anda mendeklarasikan variabel tanpa menginisialisasi, nomor acak dari memori dipilih dan variabel diinisialisasi ke nilai itu.


7
tidak juga. Kompiler memutuskan 'variabel ini akan ada di alamat xxx', apa pun yang terjadi di alamat xxx akan menjadi nilai awal kecuali jika disetel ke sesuatu secara eksplisit (dengan inisialisasi atau penugasan)
pm100

3
@ pm100 meskipun lebih baik , dan berlaku untuk setiap implementasi sepele yang tidak menghalangi para pengguna ... itu masih terlalu menyederhanakan ;-) karena menggunakan variabel yang tidak diinisialisasi adalah UB, jadi secara teori segala sesuatu dapat terjadi, termasuk kode apa pun menggunakan variabel itu hanya dikeluarkan dari program - yang sangat mungkin saat optimasi sedang dilakukan.
underscore_d

1
nilai variabel itu akan menjadi apa pun yang ada di alamat yang didapatnya, yaitu sampah.
Pedro Vernetti

@PedroVernetti Tidak masalah apa yang terjadi pada alamat tersebut sebelum variabel baru dideklarasikan dan kebetulan mendapatkan alamat yang sama. Jika pengguna mendeklarasikan variabel baru tanpa menginisialisasinya dengan nilai, dan kemudian membaca variabel sebelum menetapkannya nilai, program memiliki perilaku yang tidak ditentukan. Itu jauh lebih buruk daripada "acak" dan "sampah" dan hanya perlu dihindari.
underscore_d
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.