Domanda

Il C standard (< strong> 5.1.2.2.1 programma di avvio ) dice:

  

La funzione chiamata all'avvio del programma   prende il nome principale. [...]
  Sarà definita con un   tipo di ritorno di int e senza   Parametri:
   int main(void) { /* ... */ }

     

o con due parametri [...] :
   int main(int argc, char *argv[]) { /* ... */ }

E poi dice:

  

Il valore di argc deve essere non negativo.

  • Perché non dovrebbe argc essere definito come un unsigned int, argc suppone che significa 'numero di argomenti'?
  • Nel caso argc essere utilizzato come indice per argv?

Così ho iniziato a chiedermi se lo standard C dice qualcosa circa il tipo di indice di array. E 'firmato?

6.5.2.1 Array indicizzazione di :

  

Una delle espressioni avranno tipo   ‘‘ puntatore al tipo di oggetto ’’, l'altra   espressione deve avere tipo intero ,   e il risultato è di tipo ‘‘ tipo ’’.

Non dice nulla circa la sua signedness (o io non l'ho trovato). E 'abbastanza comune vedere i codici usando negativi indici di matrice (array[-1]), ma non è che un comportamento indefinito?

  • indici di matrice siano Qualora non firmato?
È stato utile?

Soluzione

La ragione per l'int in main () è storica - è sempre stato così, da molto tempo prima la lingua è stata standardizzata. Il requisito di un indice di matrice è che è entro i limiti della matrice (o in alcuni casi, uno oltre la fine) -. Altro è definito, in modo che il signedness è irrilevante

Altri suggerimenti

1) A proposito di main () Tipo di argc: IMHO lo standard continua una tradizione molto antica (più di 30 anni), e ora ... è semplicemente troppo tardi per cambiare le cose (Attenzione: sulla maggior parte dei sistemi né il compilatore, né il linker, né la CPU si lamenterà se "argc" è definito "unsigned", ma si sono fuori dello standard!)

2) la maggior parte delle implementazioni argv [argc] è legale e restituisce NULL. In effetti, un modo alternativo per trovare alla fine della lista degli argomenti è quello di iterare sulle argv da 0 terminazione quando argv [i] è nullo.

3) Array / puntatori con numeri negativi è legale per quanto riguarda il settore degli indirizzi da (p-n) p appartiene allo stesso oggetto memoria. OSSIA si può avere

char array[100];
char *p;

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

Questo utilizzo di aritmetica dei puntatori è legale perché il puntatore risultante rimane ancora dentro l'oggetto di memoria originale ( "allineamento"). Sulla maggior parte del sistema del l'aritmetica dei puntatori può essere utilizzato per navigare in memoria in violazione di questa regola, ma questo non è portabile in quanto è completamente dipendente dal sistema.

In generale in C, il "principio di minima sorpresa" implica che è preferibile fare una variabile firmato a meno che non ci sia una buona ragione per essere firmato. Questo perché le regole tipo di promozione può portare a risultati imprevisti quando si mescolano firmato e valori senza segno: per esempio, se argc era firmato allora questo semplice confronto porterebbe a risultati sorprendenti:

if (argc > -1)

(La -1 è promosso a unsigned int, quindi il suo valore viene convertito in UINT_MAX, che è quasi certamente maggiore di argc).

1) argc è un numero di argomenti, ma per essere onesti, come si può anteporre un argomento prima che il nome del programma che argv[0]. Immaginate un programma chiamato foo, non si può semplicemente dire args1 foo args2 come che è privo di significato, nonostante la argc essere un tipo di firma int, vale a dire una cosa come argv[-1] che vi porterà 'args1' ...

2) La ragione argc non è realmente un indice al vettore argomento (da qui ' argv ') come runtime infila il nome del programma eseguibile nella zero'th offset, cioè argv[0] quindi il argc sarà off di 1.

3) indici di array, in termini di manipolazione dei puntatori, disponibile siete entro i confini del blocco di memoria in cui il puntatore si trova, con indici di matrice come negativo è giuridico dei indici di matrice sono una scorciatoia per i puntatori, e non solo quello, sono commutativa ad esempio

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';

Anche se si utilizza array e di manipolarli in modo tale che è al di fuori dei confini - che è un comportamento indefinito e dipenderà l'attuazione della fase di esecuzione su come gestire la cosa, forse un errore di segmentazione, o un programma di incidente ....

4) In ambienti * nix, qualcuno potrebbe avere un terzo parametro fornito al char **endvp principale, ancora una volta questa è raramente utilizzato nel mondo Microsoft di DOS / Windows. Alcune implementazioni * nix run-time, per motivi preistorici, si potrebbe passare le variabili di ambiente tramite la fase di esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top