C ++ 03'te 'auto' anahtar sözcüğünü kullanmak için herhangi bir neden var mı?


85

Bu sorunun ilk olarak 2009'da, C ++ 11 onaylanmadan önce ve autoanahtar kelimenin anlamı büyük ölçüde değiştirilmeden önce yayınlandığını unutmayın . Verilen yanıtlar, yalnızca C ++ 03'ün anlamı ile ilgilidir auto- bu, belirtilen bir depolama sınıfıdır - ve C ++ 11'in anlamı auto- otomatik tür kesintisi değildir. C ++ 11'i ne zaman kullanacağınızla ilgili tavsiye arıyorsanız auto, bu soru bu soruyla alakalı değildir.

En uzun süre, kullanmak için bir neden olmadığını düşündüm. static anahtar kelimeyi C'de , çünkü blok kapsamının dışında bildirilen değişkenler dolaylı olarak küreseldi. Sonra, bir değişkeni staticblok kapsamı içinde ilan etmenin ona kalıcı bir süre vereceğini ve onu blok kapsamı dışında (program kapsamında) ilan etmenin ona dosya kapsamı vereceğini keşfettim (sadece bu derleme biriminde erişilebilir).

Yani bu bana, henüz tam olarak anlamadığım (belki de) tek bir anahtar kelime bırakıyor: autoAnahtar kelime. Bunun 'yerel değişken'den başka bir anlamı var mı? Kullanmak isteyebileceğiniz her yerde sizin için dolaylı olarak yapılmayan herhangi bir şey? Bir autodeğişken program kapsamında nasıl davranır? static autoDosya kapsamındaki bir değişken nedir ? Bu anahtar kelimenin tamlık için var olmaktan başka bir amacı var mı ?

Yanıtlar:


74

autobir depolama sınıfı belirteci, static, registerveextern de. Bir bildirimde bu dördünden yalnızca birini kullanabilirsiniz.

Yerel değişkenler (olmadan static ) otomatik depolama süresine sahiptir, bu da tanımlarının başından bloklarının sonuna kadar yaşadıkları anlamına gelir. Auto'yu onların önüne koymak gereksizdir çünkü zaten bu varsayılandır.

C ++ 'da kullanmak için herhangi bir neden bilmiyorum. Örtük int kuralı olan eski C sürümlerinde, aşağıdaki gibi bir değişken bildirmek için kullanabilirsiniz:

int main(void) { auto i = 1; }

iKapsam dahilinde olması durumunda sözdizimini geçerli kılmak veya bir atama ifadesinden netleştirmek için . Ancak bu zaten C ++ 'da çalışmaz (bir tür belirtmeniz gerekir). Yeterince komik, C ++ Standardı şöyle yazıyor:

Blok kapsamında depolama sınıfı belirticisi olmadan veya bir işlev parametresi olarak bildirilen bir nesne, varsayılan olarak otomatik depolama süresine sahiptir. [Not: dolayısıyla, otomatik tanımlayıcı neredeyse her zaman gereksizdir ve sıklıkla kullanılmaz; auto'nun bir kullanımı, bir bildirim-ifadeyi bir ifade-ifadeden (6.8) açıkça ayırmaktır. - son not]

olan bir döküm ya da aşağıdaki gibi olabilir senaryoda, değinmektedir aiçin intya da bir değişken bildirimi aÇeşidi intçevresinde yedek parantez sahip olan a. Her zaman bir beyan olarak alınır, bu yüzden autoburada yararlı bir şey eklemeyin, bunun yerine insan için olur. Ama sonra yine, insan etrafındaki gereksiz parantezleri kaldırsa daha iyi aolurdu, derdim:

int(a);

autoC ++ 0x ile gelmenin yeni anlamı ile, onu C ++ 03'ün koddaki anlamı ile kullanmaktan vazgeçerdim.


4
C ++ derleyicileri genellikle standarttan önceki ARM günlerinde işlevlerden geri dönüş değerleri için örtük int kullanırdı ...
EMPIRE'den

1
Bunu derleyicilerimin, bir işlevi ileri-bildirmeyi unuttuğumu söylemenin bir yolu olarak kabul ettim. Bana bir işlevi kullanımımın, örtük int nedeniyle bildirilme biçiminden farklı olduğunu söylerdi.
Carson Myers

29
En iyi yanı, programcıların kendilerini "int" (üç harf) yazmaktan kurtarmak için "auto" (dört harf) yazmalarıdır.
Max Lybbert

30
@Max - hey, pek çok insan "World Wide Web" in kısaltması olarak "double-u-double-u-double-u" diyor.
Daniel Earwicker

3
@smichak no, "uçucu" bir tür niteleyicidir. Bir değerin nerede saklanacağını belirlemek yerine, geçici nitelikli türden bir nesneye yazma ve ondan okuma davranışını değiştirir. Uçucu nitelikli yığın değişkenleri (otomatik depolama sınıfı) yanı sıra uçucu nitelikli statik depolama süresi değişkenleri (yerel 'statik' depolama sınıfı, yerel olmayan değişkenler) olabilir. Bunun yanı sıra, "değişken kaydı" nın geçerli bir kombinasyon olup olmadığını bilmiyorum :)
Johannes Schaub - litb

86

C ++ 11'de autoyeni bir anlama sahiptir: bir değişkenin türünü otomatik olarak çıkarmanıza izin verir.

Bu neden her zaman işe yarar? Basit bir örneği ele alalım:

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

autoTüründe bir yineleyici orada yaratır std::list<int>::iterator.

Bu, bazı ciddi karmaşık kodların okunmasını çok daha kolay hale getirebilir.

Başka bir örnek:

int x, y;
auto f = [&]{ x += y; };
f();
f();

Burada, autobir değişkende bir lambda ifadesini depolamak için gereken tür çıkarıldı. Wikipedia, konu hakkında iyi bir haber içeriyor.


4
Yine de bunun harika bir otomobil kullanımı olup olmadığından emin değilim. Kodun okunması kolay olmalı, yazması kolay olmamalıdır!
DanDan

38
Seni bilmiyorum ama okumayı yineleyici türü spam'den çok daha kolay buluyorum.
Bakış

17
Ve eğer bir rezonans için sınıfı <int> listesinden başka bir sınıfa değiştirmeye karar verirseniz, her yineleyici bildirimini aramanıza ve değiştirmenize gerek yoktur.
roslav

2
@KarateSnowMachine: Sabit'i istiyorsanız, "auto" yerine "const auto" kullanırsınız.
darth happyface

4
@darth const auto it = a.begin();size bir sabit verir iterator, bir const_iterator. Öğeyi yine de değiştirebilirdiniz, ancak derlemezsiniz ++it. Bir almak için şunu const_iteratorkullanırsınızauto it = a.cbegin();
fredoverflow

35

Auto anahtar kelimesinin şu anda bir amacı yok. Yerel bir değişkenin varsayılan depolama sınıfını yeniden ifade ettiği konusunda tam olarak haklısınız, gerçekten kullanışlı bir alternatif static.

Bu sahiptir yepyeni bir anlam C ++ 0x ile. Bu size ne kadar işe yaramaz olduğuna dair bir fikir verir!


1
oh adamım, bu hiç işe yaramaz. Yine de yeni anlamı sevdim. Bazı kodları çok daha az ayrıntılı ve gereksiz hale getirir.
Carson Myers

Evet, eşdeğerini C # 'da kullanmak muhtemelen çok büyük bir fark yaratacaktır. Daha çok, türlerin çok karmaşık olduğu ve hiçbir zaman elle yazılmaları amaçlanmayan ifade şablonlarını kullanıyorsanız C ++ 'da böyledir.
Daniel Earwicker

7

GCC, autoiç içe geçmiş işlevler için özel bir kullanıma sahiptir - buraya bakın .

Tanımından önce çağırmak istediğiniz yuvalanmış işleviniz varsa, ile bildirmeniz gerekir auto.


Bu, derleyiciye bağımlı olsa da, harika bir auto uygulamasıdır. Araştırma için teşekkürler :)
Carson Myers

3

"auto", derleyiciye değişkeni (bellek veya kayıt) nereye koyacağına kendisi karar vermesini söyler. Onun analogu "register" dır ve derleyiciye onu bir kayıtta tutmaya çalışmasını söyler. Modern derleyiciler her ikisini de görmezden gelir, bu yüzden siz de yapmalısınız.


1
Tam olarak değil - eğer bunu "register" ile bildirirseniz, derleyiciler değişken üzerinde adresin (& foo) operatörünü kullanmanıza izin vermez, çünkü bellekte herhangi bir yerde yoktur (ve dolayısıyla adresi yoktur).
Tim Čas

3

Bu anahtar sözcüğü, işlev için kritik olduğunda, değişken yığın tabanlı işlemciler için yığına yerleştirileceğini açıkça belgelemek için kullanıyorum. Bu işlev, bir işlevden dönmeden (veya hizmet rutinini kesmeden) önce yığını değiştirirken gerekli olabilir. Bu durumda beyan ederim:

auto unsigned int auiStack[1];   //variable must be on stack

Ve sonra değişkenin dışına erişiyorum:

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

Dolayısıyla autoanahtar kelime, amacı belgelemeye yardımcı olur.


1
Anahtar kelime aslında yığın yerleşimini zorunlu kılmadığından, yalnızca bunu ihmal etmekten daha fazlasını yapmadığından, bunun yalnızca sinyal verme amacı olduğunu varsayıyorum .
underscore_d

2

Stroustrup'a göre, "The C Programming Language" (4. Baskı, C 11'i kapsayan), 'auto' kullanımının aşağıdaki ana nedenleri vardır (bölüm 2.2.2) (Stroustrup sözcükleri alıntılanmıştır):

1)

Tanım, türü kodumuzun okuyucuları tarafından açıkça görülebilir hale getirmek istediğimiz geniş bir kapsamdadır.

'Auto' ve gerekli başlatıcı ile değişkenin türünü bir bakışta öğrenebiliriz!

2)

Değişkenin aralığı veya hassasiyeti hakkında açık olmak istiyoruz (örneğin, float yerine çift)

Bence buraya uyan bir durum şuna benzer:

   double square(double d)
    {
        return d*d; 
    }

    int square(int d)
    {
        return d*d; 
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

3)

'Auto' kullanarak fazlalıktan ve uzun tip isimler yazmaktan kaçınırız.

Şablon haline getirilmiş bir yineleyiciden uzun bir tür adı düşünün:

(bölüm 6.3.6.1'deki kod)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}

Bu noktalar C ++ 11 için geçerlidir, ancak C ++ 03 için geçerli değildir. Tür çıkarımı C ++ 11'de yeniydi.
Jirka Hanika

1

Eski derleyicide auto, yerel bir değişkeni bildirmenin bir yoluydu. Turbo C gibi eski derleyicilerde auto anahtar sözcüğü veya benzeri olmadan yerel değişkenler bildiremezsiniz.


Korkarım yanılıyorsun. Turbo C'nin 1986'daki Wizard-C adlı orijinal versiyonunda veya çağdaşlarından herhangi birinde bile böyle bir kısıtlama yoktu: MSC, Lattice C, Concurrent-C, High-C, Watcom-C ...
chqrlie

1

STL MSDN'ın Kanal 9 Alanda bulunan C ++ 0 x oto anahtar kelimenin yeni bir anlam, bir serbestçe görüntülenebilir / indirilebilir video dersinde Microsoft'un Stephan T. Lavavej tarafından çok güzel tarif edilir burada .

Ders bütünüyle izlenmeye değer, ancak auto anahtar kelimesiyle ilgili kısım yaklaşık 29. dakika işaretindedir (yaklaşık olarak).


1

"Otomatik" için "yerel değişken" dışında başka bir anlam var mı?

C ++ 03'te değil.

Kullanmak isteyebileceğiniz her yerde sizin için örtük olarak yapılmayan herhangi bir şey?

C ++ 03'te hiçbir şey yok.

Otomatik değişken program kapsamında nasıl davranır? Dosya kapsamındaki statik otomatik değişkenden ne haber?

Bir işlev / yöntem gövdesi dışında anahtar kelimeye izin verilmez.

Bu anahtar kelimenin [C ++ 03'te] tamlık için var olmaktan başka herhangi bir amacı var mı?

Şaşırtıcı bir şekilde, evet. C ++ tasarım kriterleri, C ile yüksek derecede geriye dönük uyumluluk içeriyordu. C bu anahtar kelimeye sahipti ve onu yasaklamak veya C ++ 'da anlamını yeniden tanımlamak için gerçek bir neden yoktu. Yani amaç, C ile bir uyumsuzluk eksikliğiydi.

Bu anahtar kelimenin C'de tamlık için var olmaktan başka herhangi bir amacı var mı?

Yakın zamanda bir tane öğrendim: B'den eski programları taşıma kolaylığı, sözdizimi C'ye oldukça benzeyen B adlı bir dilden gelişti. Ancak, B'nin hiçbir türü yoktu. B'de bir değişkeni tanımlamanın tek yolu, depolama türünü ( autoveya extern) belirlemekti. Bunun gibi:

oto i;

Bu söz dizimi hala C'de çalışır ve eşdeğerdir

int i;

çünkü C'de, depolama sınıfı varsayılan değerine autove tür varsayılan değerine ayarlanır int. Sanırım, B'de ortaya çıkan ve C'ye taşınan her bir program o sırada tam anlamıyla autodeğişkenlerle doluydu .

C ++ 03 artık C stili örtük int'e izin vermiyor, ancak artık tam olarak kullanışlı olmayan autoanahtar kelimeyi korudu çünkü örtük int'in aksine C'nin sözdiziminde herhangi bir soruna neden olduğu bilinmiyordu.

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.