Main'in uygun beyanı nedir?


150

mainC ++ ' da işlevin uygun imzası nedir ? Doğru dönüş türü nedir ve bir değer döndürmek ne anlama gelir main? İzin verilen parametre türleri nelerdir ve anlamları nelerdir?

Bu sisteme özel mi? Bu kurallar zamanla değişti mi? Onları ihlal edersem ne olur?


1
Bu, C ve C ++ 'da Ne maindöndürmeli ile çok yakından ilgilidir veya bir kopyasıdır .
Jonathan Leffler

@JonathanLeffler Şaka yapmıyorum ... yaklaşık 8 ay önce revizyon 6'da yinelenenler listesine eklendi .
fredoverflow

Yanıtlar:


195

mainFonksiyon genel ad üye olmayan bir fonksiyonu olarak beyan edilmelidir. Bu, bir sınıfın statik veya statik olmayan üye işlevi olamayacağı veya bir ad alanına (hatta adsız ad alanına) yerleştirilemeyeceği anlamına gelir.

Ad main, genel ad alanındaki bir işlev dışında C ++ 'da rezerve edilmez. mainDiğer şeylerin yanı sıra, sınıflar, değişkenler, numaralandırmalar, üye işlevler ve genel ad alanında olmayan üye olmayan işlevler dahil olmak üzere adlandırılmış diğer varlıkları bildirmekte özgürsünüz .

mainÜye işlev olarak veya bir ad alanında adlandırılmış bir işlevi bildirebilirsiniz , ancak böyle bir işlev main, programın nerede başladığını belirleyen işlev olmayacaktır .

mainFonksiyonu olarak ilan edilemez staticveya inline. Ayrıca aşırı yüklenemez; maingenel isim alanında isimlendirilmiş yalnızca bir işlev olabilir .

mainAramak izin verilmez: işlevi programda kullanılamaz mainKodunuzdaki herhangi bir yerden işlevi ne de adresini almaya izin verilir.

Dönüş türü mainolmalıdırint . Başka hiçbir dönüş türüne izin verilmez (bu kural kalın yazılmıştır çünkü mainbir dönüş türü ile bildiren yanlış programları görmek çok yaygındır void; bu muhtemelen mainişlevle ilgili en sık ihlal edilen kuraldır ).

mainİzin verilmesi gereken iki bildirim vardır :

int main()               // (1)
int main(int, char*[])   // (2)

In (1) , hiçbir parametreler vardır.

In (2) , iki parametre vardır ve bunlar geleneksel olarak adlandırılır argcve argvsırasıyla. argvprogramın argümanlarını temsil eden bir C dizgisi dizisine göstericidir. dizideki argcbağımsız değişkenlerin sayısıdır argv.

Genellikle argv[0]programın adını içerir, ancak bu her zaman böyle değildir. argv[argc]boş gösterici olduğu garantilidir.

Bir dizi türü bağımsız değişkeni (gibi char*[]) gerçekten gizlenmiş bir işaretçi türü bağımsız değişkeni olduğundan, aşağıdaki ikisinin her ikisi de yazmak için geçerli yöntemler (2) olduğunu ve her ikisinin de tamamen aynı anlama geldiğini unutmayın:

int main(int argc, char* argv[])
int main(int argc, char** argv)

Bazı uygulamalar başka tür ve sayıda parametreye izin verebilir; Neyi desteklediğini görmek için uygulamanızın belgelerini kontrol etmeniz gerekir.

main()başarıyı göstermek için sıfır ve başarısızlığı belirtmek için sıfırdan farklı bir değer döndürmesi beklenir. Açıkça bir returnifade yazmanız gerekmez: açık bir ifade olmadan geri dönmeye main()izin verirseniz , yazmışsınız gibi aynıdır . Aşağıdaki iki işlev aynı davranışa sahiptir:main()returnreturn 0;main()

int main() { }
int main() { return 0; }

İki makro vardır EXIT_SUCCESSve EXIT_FAILUREtanımlanan, <cstdlib>o da döndü edilebilir main()sırasıyla başarı ve başarısızlığını gösterir.

Döndürülen değer , programı sonlandıran işleve main()iletilir exit().

Tüm bunların yalnızca barındırılan bir ortam için derleme yaparken geçerli olduğunu unutmayın (gayri resmi olarak, tam standart bir kitaplığa sahip olduğunuz ve programınızı çalıştıran bir işletim sistemi bulunan bir ortam). Bağımsız bir ortam (örneğin, bazı gömülü sistemler) için bir C ++ programı derlemek de mümkündür, bu durumda başlatma ve sonlandırma tamamen uygulama tanımlıdır ve bir main()işlev bile gerekli olmayabilir. Modern bir masaüstü işletim sistemi için C ++ yazıyorsanız, barındırılan bir ortam için derliyorsunuz demektir.


1
IIRC garantili dönüş değerleri yalnızca 0, EXIT_SUCCESS (0 ile aynı etki) ve EXIT_FAILURE şeklindedir. DÜZENLEME: Ah, tamam, diğer sıfır olmayan durum değerleri döndürülebilir, ancak uygulama tanımlı anlamlarla. Yalnızca EXIT_FAILURE'ın bir şekilde bir hata değeri olarak yorumlanması garanti edilir.
Derrick Turk

4
@Synetech: Soru ilk cümlesinde soruyor, "C ++ 'daki ana işlevin doğru imzası nedir?" ve soru hem [c ++] hem de [c ++ - faq] olarak etiketlenmiştir. Java veya C # kullanıcılarının (veya başka birinin) kafası karışmışsa yardım edemem. C # Main, üye olmayan işlevlere sahip olmadığı için statik üye işlev olmayı gerektirir . C89'un bile maingeri dönmesi gerekiyor int. Ben onun tam kuralları bilmek K & R C yeteri kadar bilgi sahibi değilim ama o da gerektirir tahmin ediyorum maindönmek intberi mainhiçbir dönüş tipi biraz yaygın ve hiçbir type = örtük oldu ile intK & R.
James McNellis

3
@Suhail: Çünkü dil standardı dönüş tipinin olacağını söylüyor int.
James McNellis

1
@Suhail: Evet. Kodunuz doğru C ++ olmayacak ve birçok derleyici kodunuzu reddedecektir.
James McNellis

2
@Suhail: Visual C ++ , bir dil uzantısı olarak birvoid dönüş türüne izin verir . Buna izin vermeyen derleyiciler GCC ve Comeau'yu içerir.
James McNellis

15

Standart belgelerden 3.6.1.2 Ana İşlev ,

Dönüş türü int türünde olacaktır, ancak aksi takdirde türü uygulama tanımlıdır. Tüm uygulamalar, aşağıdaki main tanımlarının her ikisine de izin verecektir:

int main() { / ... / } ve int main(int argc, char* argv[]) { / ... / }

İkinci biçimde argc, programın çalıştırıldığı ortamdan programa aktarılan argüman sayısı olacaktır. Argc sıfırdan farklıysa, bu argümanlar argv [0] ile argv [argc-1] arasında baştaki işaretçiler olarak sağlanacaktır. boş sonlandırılmış çok baytlı dizelerin karakterleri .....

Umarım yardımcı olur..


2
dönüş türünün neden mainolması gerektiğine dair belirli bir neden var intmı?
Suhail Gupta

1
@SuhailGupta: Böylece arama işlemi bu işlemin başarılı olup olmayacağını bilir . voidO modelin kırılmasına izin vermek . "Her zaman başarıyı kabul et" anlamına geldiyse, bu gerçekten mantıklı değil. Sürecin gerçekten başarısız olup olmadığını söylemenin hiçbir yolu olmadığından, gerçekten başarılı mıydın? Hayır, geri dön int.
Orbit'te Hafiflik Yarışları

4

En son yayınlanan standardın (C ++ 14) tam metni şöyledir:

Bir uygulama, hem

  • ()dönen bir fonksiyon intve

  • bir işlevi, geri dönen (intişaretçiye işaretçichar)int

türü olarak main.

Bu main, türü int()veya türü olduğu sürece alternatif yazımlara izin verildiğini açıkça ortaya koymaktadır int(int, char**). Dolayısıyla aşağıdakilere de izin verilir:

  • int main(void)
  • auto main() -> int
  • int main ( )
  • signed int main()
  • typedef char **a; typedef int b, e; e main(b d, a c)

1
NB. Bu cevabı başka bir konuya yorumlarda olduğu gibi gönderdim, birisi bu konuyu int main(void)C ++ 'da doğru olmayan kanıt olarak göstermeye çalıştı .
MM

3
@Stargateur kesintili auto main() -> intbir dönüş türüne sahip değil. {İn "(auto main () {... izin verilmez)" konusuna dikkat edin ve lütfen anlamlı bir şey eklemek için henüz yeterince bilmediğinizi öğrenin.

3

İki geçerli şebeke int main()ve int main(int, char*[]). Başka herhangi bir şey derlenebilir veya derlenmeyebilir. Eğer maindışardan bir değer döndürmez, 0 dolaylı döndürülür.


1
mainVoid olmak üzere dönüş türünden bahsettiğimde kodun derlenmediğini hiç görmedim . Geri dönüş türünün int olması için belirli bir neden var mı?
Suhail Gupta

4
Dil belirtimi, main'in bir dönüş türüne sahip olması gerektiğini söylüyor. Derleyiciniz tarafından izin verilen diğer herhangi bir dönüş türü, derleyiciye özgü bir geliştirmedir. Temel olarak void kullanmak, C ++ 'ya benzer ancak C ++ diline benzer bir dilde programlama yaptığınız anlamına gelir.
stonemetal

2
Standardın intdönüş türü olarak bir gerektirmesinin nedeni, mainbu değerin kabuğa programın çıkış kodu olarak verilmesi ve shbir int.
uckelman

Belki sebebi disiplindir? Birden fazla çıkış yolu olabilir. Dönüş türü ise void, hepsi sessizdir. İle int, her dönüş için belirli bir çıkış değeri tanımlamamız gerekir main.
Andreas Spindler

2

Dönüş değerleri ve anlamları ile ilgili ayrıntılar

3.6.1 ( [basic.start.main]) için:

İçindeki bir dönüş ifadesi main, mainişlevi bırakma (otomatik depolama süresi olan herhangi bir nesneyi yok etme) ve std::exitargüman olarak dönüş değeri ile çağırma etkisine sahiptir . Kontrol, mainbir returnifadeyle karşılaşmadan sona ulaşırsa, etki, yürütme işlemidir.

return 0;

Davranışı std::exitbölüm 18.5 ( [support.start.term]) ' de ayrıntılı olarak açıklanmıştır ve durum kodunu açıklar:

Son olarak, kontrol ana bilgisayar ortamına döndürülür. Durum sıfır ise veya EXIT_SUCCESS, başarılı sonlandırma durumunun uygulama tanımlı bir formu döndürülür. Durum ise EXIT_FAILURE, başarısız sonlandırma durumunun uygulama tanımlı bir biçimi döndürülür. Aksi takdirde, döndürülen durum uygulama tanımlıdır.

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.