C ++ kullanarak bir satırda birden çok değişkeni nasıl bildirebilir ve tanımlayabilirim?


173

Her zaman bu üç değişkeni beyan edersem hepsinin 0 değerine sahip olacağını düşünüyorum

int column, row, index = 0;

Ama sadece endeksin sıfıra eşit olduğunu ve diğerlerinin 844553 ve 2423445 gibi önemsiz olduğunu görüyorum.

Her bir değişkeni yeni bir satırda bildirmeden tüm bu değişkenleri sıfıra nasıl başlatabilirim?


36
Bu tek satırlı çok değişkenli bildirimlere dikkat edin. Bir int işaretçisi ve ardından düzenli tamsayıların bir listesini bildirmeyi düşündüğünüzden daha kolaydır ( int* a, b, c;neye benzediğini yapmaz).
Chris Eberle

4
=0Tanımlarında her biri için sadece üç değişken vardır, ahbap, yazma . Ve gerçekten çok sayıda değişken istiyorsanız, bir dizi deneyin: sizin için int a[10]={0}her a[i]birini 0 olarak başlatır .
Stan

Derleyici, makul bir programcının yapmasını beklediğinden farklı davranacaksa bu yapıya izin vermemelidir ...
imho

1
@ cph2117 Makul bir programcı 'hmm, bu sözdizimi dilbilgisinin şeyleri nasıl bağladığına bağlı olarak birkaç farklı şey anlamına gelebilir' , hangisinin doğru olduğunu bulmak için Standart'a bakabilir ve onunla başa çıkabilir.
underscore_d

Bunu yapmayı kes. Kodun okunmasını zorlaştırır. Üst düzey bir dilde kod yazmanın amacı, bir bakıcının okumasını kolaylaştırmaktır.
Martin York

Yanıtlar:



162

Bildirdiğiniz zaman:

int column, row, index = 0;

Yalnızca dizin sıfır olarak ayarlanır.

Ancak aşağıdakileri yapabilirsiniz:

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

Ama ben şahsen belirtilmiş olanları tercih ederim.
Benim görüşüme göre daha okunabilir bir form.

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

veya

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

3
Son iki arasında, iki değerin gerçekten aynı tip ( bool previousInputValue, presentInputValue;) olup olmayacağına veya şimdi aynı tipte olup olmadıklarına, ancak gerçekten olması gerekmediğine ( gelecekte uint8_t height, width;dönüşebilir uint8_t height; uint16_t width;ve uint8_t height; uint8_t width;başlamak için).
altendky

Çünkü yazmak uint8_t height; uint16_t width;yerine yazmak uint8_t height, width;10 karakter kazandırır. :-) Tabii ki istediğiniz gibi yapabilirsiniz. Kolayca okuduğunuzdan emin olun. Yani son form en açık olanıdır.
Matt

Son form, her değişkenin türünü belirleme ve her birinin başlatıldığını açıkça belirleme konusunda en açık olanıdır. Bununla birlikte, sütun ve satırın aynı tipte olup olmayacağı konusunda açık değildir. Belki ikimiz de açık olmayı tercih ederiz int presentValue = 0; typeof(presentValue) previousValue = presentValue;, ancak bunun typeof()standart olmayan bir GCC uzantısı olduğuna inanıyorum .
altendky

49

@Josh'un dediği gibi, doğru cevap:

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

İşaretçilerle aynı şeyi izlemeniz gerekir. Bu:

int* a, b, c;

Şuna eşittir:

int *a;
int b;
int c;

34
O işaretçi şeyden nefret ediyorum, hiç mantıklı değil. Yıldız, türün bir parçasıdır, bu nedenle hepsine uygulanmalıdır. Düşünün unsigned long x, y;beyan xolarak unsigned longama ytıpkı unsigned, nam unsigned int! Bu tamamen aynı! </rant>
Cam Jackson

6
Mantıklı. "int * a, b, c;"
Jeroen

7
@JeroenBollen Evet, işaretçi yıldızlarınızı tür yerine değişken adının yanına yazarsanız mantıklıdır, ancak bu kendi başına bir anlam ifade etmez. Yukarıda söylediğim gibi, yıldız, türün bir parçasıdır, adın bir parçası değildir, bu nedenle türle gruplandırılmalıdır!
Cam Jackson

11
Bir yan olarak değil, aslında * bir değeri temsil eden int *aaraçlar olarak * mutlaka türün bir parçası değildir . *aint
mdenton8

2
Nokta zaten yapıldı ama sadece geçersiz eklemek için bir tür eksikliği aslında ama yine de işaretçiler yapabilirsiniz. Böylece neden void* aderlenecek ve void *a, b, colmayacak. Bu rasyonalizasyon benim için işe yarıyor.
Josh C

25

Satır başına bir değişken / nesne bildirirseniz, bu sorunu çözmekle kalmaz, aynı zamanda kodu daha net hale getirir ve işaretçiler bildirirken saçma hataları önler.

Sorunuzu doğrudan yanıtlamak için, her değişkeni 0 olarak açıkça başlatmanız gerekir. int a = 0, b = 0, c = 0;.


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

Bu formun, özellikle kurucuları birden fazla argüman aldığında özel türlerle de çalışacağını unutmayın.


2
ve günümüzde tek tip başlatma ile (bunu için C ++ 17 sabitleme bekleniyor auto...): int sütun { 0 } , satır { 0 } , dizin { 0 } ;
underscore_d

5

2k18'den itibaren Yapısal Ciltlemeler'i kullanabilirsiniz :

#include <iostream>
#include <tuple>

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

Demo


4

Olası yaklaşımlar:

  • Tüm yerel değişkenleri sıfırla başlat.
  • Bir dizi memsetveya {0}dizi var.
  • Global veya statik yapın.
  • Onları koyun structve memsetya sıfıra onları başlatmaya verecek bir kurucuya sahip.

#define COLUMN 0 #define ROW 1 #define INDEX 2 #define AR_SIZE 3 int Veri [ AR_SIZE ]; // Sadece bir fikir.
Ajay

Üzgünüm, demek istediğim, cevabınıza neden " Bir dizi, memset veya {0} dizi var " satırını eklediniz ?
Mateen Ulhaq

memset (Veri, 0, sizeof (Veri)); // Bu mantıksal olarak paketlenebiliyorsa.
Ajay

2

Bunu tavsiye etmem, ama gerçekten bir satır olmak ve sadece bir kez 0 yazıyorsanız, bunu da yapabilirsiniz:

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

0

Diğerlerinin de belirttiği gibi, C ++ 17'den itibaren çok değişkenli atamalar için yapılandırılmış bağlamaları kullanabilirsiniz .

Bunu std::arrayve şablon argümanı kesinti ile birleştirerek , türü veya değeri tekrar etmeden rasgele sayıda değişkene değer atayan bir işlev yazabiliriz .

#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

Bir değişkeni başlatmadan bildirdiğinizde, bellekten rastgele bir sayı seçilir ve değişken bu değere başlatılır.


7
pek sayılmaz. Derleyici açıkça şeye onun sette sürece (initialize veya atama yoluyla) başlangıç değeri olacaktır adres xxx olmak ne olduysa 'Bu değişken adresi xxx olacaktır' karar
PM100

3
@ pm100 her ne kadar daha iyi ve kullanıcıları taciz etmek için kendi yolundan gitmeyen herhangi bir önemsiz uygulama için doğrudur ... Bu hala aşırı basitleştirici ;-) kullanılmamış bir değişken kullanmak UB olduğundan , teoride herhangi bir kod da dahil olmak üzere her şey olabilir bu değişkenin basitçe programdan çıkarılması - ki bu özellikle optimizasyon sırasında mümkündür.
underscore_d

1
bu değişkenin değeri, adresinde ne olursa olsun, yani önemsiz olur.
Pedro Vernetti

@PedroVernetti Yeni değişken bildirilmeden ve aynı adresi almadan önce bu adreste ne olduğu önemli değil. Kullanıcı yeni değişkeni bir değerle başlatmadan bildirir ve sonra bir değer atamadan önce değişkeni okursa, programın tanımlanmamış davranışı vardır. Bu "rastgele" ve "önemsiz" den sonsuz derecede daha kötüdür ve kaçınılması gerekir.
underscore_d
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.