Frage

Der C Standard (< strong> 5.1.2.2.1 Programmstart ) sagt:

  

Die Funktion beim Programmstart aufgerufen   heißt main. [...]
  Es ist de fi niert mit einem   Rückgabetyp int und ohne   Parameter:
   int main(void) { /* ... */ }

     

oder mit zwei Parametern [...] :
   int main(int argc, char *argv[]) { /* ... */ }

Und später sagt:

  

Der Wert von argc soll nicht negativ sein.

  • Warum nicht argc als unsigned int definiert werden, argc angeblich bedeutet 'Argument count'?
  • Should argc als Index für argv verwendet werden?

So begann ich mich gefragt, ob der C-Standard etwas über die Art des Array-Index sagt. Ist es unterzeichnet?

6.5.2.1 Array Subskribierung :

  

Einer der Begriffe sind Typ haben   ‚‚ Zeiger auf Objekttyp ‘‘, die andere   dieser Begriff hat Integer-Typen ,   und das Ergebnis hat Typ ‚‚ type ‘‘.

Es sagt nichts über seine Signedness (oder ich habe es nicht finden). Es ist ziemlich häufig Codes zu sehen Negative Array-Indizes (array[-1]) verwenden, aber ist es nicht Verhalten nicht definiert?

  • Should Arrays Indizes ohne Vorzeichen sein?
War es hilfreich?

Lösung

Der Grund für die int in main () ist historisch - es ist schon immer so, seit lange vor der Sprache standardisiert wurde. Die Anforderung eines Array-Index ist, dass es innerhalb der Grenzen des Arrays ist (oder in einigen Fällen eine über das Ende.) - alles andere ist nicht definiert, so dass die Signedness immateriell ist

Andere Tipps

1) Über main () argc Typ: IMHO weiterhin der Standard eine sehr alte Tradition (mehr als 30 Jahre), und jetzt ... es ist einfach zu spät zu ändern Dinge (Anmerkung: auf den meisten Systemen weder den Compiler, noch der Linker, noch die CPU wird sich beschweren, wenn „arge“ definiert ist „unsigned“, aber Sie sind aus dem Standard!)

2) Bei den meisten Implementierungen argv [argc] ist legal und wird auf NULL. Tatsächlich ist eine alternative Art und Weise das Ende der Argumentliste zu finden ist, zu iterieren auf argv von 0 endet, wenn argv [i] NULL ist.

3) Array / Zeigerarithmetik mit negativen Zahlen ist legal, so weit wie der Adressbereich von (p-n) bis p zu demselben Speicherobjekt gehört. I.E. Sie können haben

char array[100];
char *p;

p = &array[50];
p += -30; /* Now p points to array[20]. */

Diese Verwendung von Zeigerarithmetik ist legal, da die resultierenden Zeiger noch in dem ursprünglichen Speicherobjekt bleibt ( „Array“). Auf den meist System kann die Zeigerarithmetik verwendet werden, bei Verstoß gegen diese Regel im Speicher zu navigieren, aber das ist nicht tragbar, da es vollständig systemabhängig ist.

In der Regel in C, das „Prinzip der geringsten Überraschung“ impliziert, dass es vorzuziehen ist, eine Variable unterzeichnet zu machen, es sei denn es einen guten Grund ist für sie ohne Vorzeichen zu sein. Dies liegt daran, dass die Art-Förderung Regeln zu unerwarteten Ergebnissen führen können, wenn Sie und Werte ohne Vorzeichen unterzeichnet mischen: zum Beispiel, wenn argc unsigned wurde dann dieser einfache Vergleich zu überraschenden Ergebnissen führen würden:

if (argc > -1)

(Der -1 zu unsigned int gefördert wird, so dass ihr Wert auf UINT_MAX umgewandelt wird, die mit ziemlicher Sicherheit größer als argc).

1) ARGC ist ein Argument zählen, aber ganz ehrlich zu sein, wie kann man ein Argument vor dem Programmnamen, der argv[0] voranstellen. Stellen Sie sich ein Programm namens foo, kann man nicht einfach sagen args1 foo args2 wie sinnlos ist, trotz der argc ein signiertes Art von int zu sein, das heißt nicht so etwas wie argv[-1], die Sie ‚args1‘ ...

erhalten

2) Der Grund argc ist nicht wirklich ein Index für das Argument Vektor (also ‚ argv ‘) als die Laufzeit des ausführbaren Programmnamen in der stopft nullten Offset, dh argv[0] daher die argc von 1 aus sein wird.

3) Array-Indizes in Bezug auf die Zeigermanipulation, zur Verfügung gestellt Sie sind innerhalb der Grenzen des Blocks des Speichers, wo der Zeiger auf ist, Array-Indizes als negativ mit legal ist, da der Array-Indizes eine Abkürzung für die Zeiger ist, und nicht allein das, sie sind kommutativ zB

char v[100];
char *p = &v[0];

You can do this:

p[55] = 'a'; 

Which is the same as

*(p + 55) = 'a';

You can even do this:

p = &v[55];

p[-10] = 'b' /* This will stuff 'b' into 45'th offset! */

Which is the same as

*(p - 10) = 'b';

Auch wenn Sie verwenden und manipulieren Arrays in einer solchen Art und Weise, die außerhalb der Grenzen ist - das nicht definiertes Verhalten ist und hängt von der Umsetzung der Laufzeit, wie man es handhaben, vielleicht ein Segmentierungsfehler, oder ein Programm Absturz ....

4) In * nix-Umgebungen, müssten einige einen dritten Parameter Haupt char **endvp geliefert wird, wieder das selten in der Microsoft-Welt von DOS / Windows verwendet wird. Einige * nichts Laufzeitimplementierungen für prähistorische Gründe Sie in den Umgebungsvariablen über die Laufzeit passieren könnten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top