Argv'nin sonunda her zaman bir null varken neden argc'ye ihtiyacımız var?


117

Görünüşe göre argv[argc]her zaman NULLöyle, bu yüzden argüman listesini onsuz gezebileceğimizi düşünüyorum argc. Bunu tek bir whiledöngü yapacak.

NULLSonunda her zaman bir varsa argv, neden bir'ye ihtiyacımız var argc?


17
Muhtemelen bir kolaylık meselesidir. Yeterli sayıda argüman yoksa programcıya döngü yapmadan erken kurtulmanın kolay bir yolunu sunar. Aksi takdirde, kesinlikle int argc(char *argv[])bunu yapmak olarak adlandırılan işlevlere sahip olurduk :-))
cnicutar

5
Açık olmak "\0"gerekirse NULL işaretçisi ile aynı şey değildir ( 0C ++ 'da
NULL'a

31
Eğer argc'ye sahipsek neden argv [argc] 'nin NULL olmasına ihtiyacımız var?
Ambroz Bizjak

7
Sabit zamanda argüman sayısını başka nasıl belirlersiniz?
avakar

4
Linux / unix etiketlerinin burada uygun olduğunu düşünmeyin, çünkü bu davranış tüm işletim sistemlerindeki tüm derleyiciler için geçerli olmalıdır.
Darrel Hoffman

Yanıtlar:


106

Evet argv[argc]==NULLgarantilidir. Bkz C11 5.1.2.2.1 Program başlatma (vurgu bana ait)

Bildirilirlerse, ana fonksiyonun parametreleri aşağıdaki kısıtlamalara uyacaktır:

Argc değeri negatif olmayacaktır. argv [argc] bir boş gösterici olacaktır.

argcBu nedenle sağlamak hayati değildir ama yine de faydalıdır. Diğer şeylerin yanı sıra, doğru sayıda argümanın geçirildiğinin hızlı bir şekilde kontrol edilmesini sağlar.

Düzenleme: Soru, C ++ 'yı içerecek şekilde değiştirildi. n3337 taslak 3.6.1 Ana işlev diyor

2 ... argc, programın çalıştırıldığı ortamdan programa aktarılan argüman sayısıdır. .... argc'nin değeri negatif olmayacaktır. Argv [argc] 'nin değeri 0 olacaktır .


36
Ve argc(böylece kabuk genişleme yapıyor, çünkü oldukça büyük olabilir önce kabuk tarafından genişletilir ve çalıştırılabilir). Sistemimde birkaç yüz binlerce olabilir. ls **execve/bin/lsargc
Basile Starynkevitch

Bu oldukça havalı, her zaman argcyeterli bulduğum için bu hiç aklıma gelmedi , ancak bu garantinin alakalı ve hatta gerekli olduğu durumları kesinlikle düşünebiliyorum. +1
Thomas

6
@BasileStarynkevitch Sadece NULL'a kadar bir işaretçi değerleri dizisinde fazladan bir kez adım atma süresi, sayımı elde etmek için, işaretçi dizisini oluşturmak için harcanan zamana kıyasla çok küçüktür ve programdaki her bir bağımsız değişken değerini kullanmaya kıyasla daha da önemsizdir. Ve eğer bağımsız değişken sayısının N'den fazla olup olmadığını kontrol ediyorsanız, tüm diziyi gözden geçirmek gerekmez. Yine de, argcbunun iyi bir şey olduğuna tamamen katılıyorum .
hyde

43

Evet, argv[argc]boş gösterici olduğu garantilidir. argckolaylık sağlamak için kullanılır.

C99 Rationale'deki resmi açıklamadan alıntı yaparak, gereksiz kontrol kelimelerine dikkat edin :

Uluslararası Standart için Gerekçe - Programlama Dilleri - C §5.1.2.2.1 Program başlatma

Kapsamlı önceki uygulamaları tanımak için argümanlar olarak argcve spesifikasyonu . yine genel uygulama temelinde, listenin sonu için fazladan bir kontrol sağlamak için bir boş gösterici olması gerekir.argvmainargv[argc]


19

Tarihsel nedenlerden ve eski kodla uyumluluktan kaynaklanmaktadır. Başlangıçta, argv dizisinin son öğesi olarak bir boş gösterici olacağına dair bir garanti yoktu. Ancak argc her zaman var olmuştur.


... Bu bir bakıma utanç verici. Eğer yapmış olsaydık int main(char *argv[], int argc, ...), o zaman bazı programlar argcbuna ihtiyaç duymadıkları için ihmal edebilirdi . Zıt (ihtiyaç duyan argcama olmayan argv) muhtemelen gerçek bir programda hiçbir zaman yararlı değildir .
hyde

@hyde: Basile Starynkevitch'in yukarıdaki yorumuna bakın
zentrunix

6

Buna "ihtiyacımız var" çünkü çeşitli standartlar tarafından gerekli.

Değeri tamamen göz ardı etmekte özgürüz, ancak ilk parametresi olduğu mainiçin onu parametre listesinde bulundurmalıyız. C ++ 'da (ve muhtemelen standart olmayan C lehçelerinde), aşağıdaki C ++ pasajı gibi (C'ye dönüştürmesi kolay) parametre adını çıkarabilirsiniz:

#include <stdio.h> // C-compatible include, guarantees puts in global namespace

// program will print contents of argv, one item per line, starting from argv[0]

int main(int /*argc*/, char *argv[]) { // uncomment argc for C

    //(void)argc; // uncomment statement for C

    for (int i=0; argv[i]; ++i) {
        puts(argv[i]);
    }

    return 0;
}

Standart C'de, ortak uyarı ayarlarıyla, kullanılmayan parametre, aşağıdaki gibi bir ifadeyle düzeltilebilen uyarı üretir (void)argc; , adın herhangi bir kod oluşturmadan kullanılmasına neden olan .

argcolması güzel, çünkü aksi halde birçok programın sayımı elde etmek için parametreler boyunca yürümesi gerekir. Ayrıca, uzunluğu olan dizilere sahip birçok programlama dilinde, herhangi bir argcparametre yoktur, sadece öğelerden oluşan bir dizi vardır.


Soru hem C hem de C ++ ile ilgili. C'de, parametre adı gereklidir.
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.