Pregunta

El C estándar (< strong> 5.1.2.2.1 inicio del programa ) dice:

  

La función llamada al inicio del programa   se llama principal. [...]
  Será definida con una   tipo de retorno de int y sin   Parámetros: Read    int main(void) { /* ... */ }

     

o con dos parámetros [...] :
   int main(int argc, char *argv[]) { /* ... */ }

Y más adelante dice:

  

El valor de argc debe ser no negativo.

  • ¿Por qué no debe argc ser definido como un unsigned int, argc supuestamente significa 'número de argumentos'?
  • En caso de argc ser utilizado como un índice para argv?

Así que empezaron a preguntarse si el estándar C dice algo sobre el tipo de índice de matriz. Se firmó?

6.5.2.1 Matriz subscripting :

  

Una de las expresiones tendrán Tipo   ‘‘ puntero al tipo de objeto ’’, el otro   expresión tendrá tipo entero ,   y el resultado es de tipo ‘‘ type ’’.

No dice nada acerca de su signo numérico (o yo no lo encontré). Es bastante común ver los códigos usando negativos índices de matriz (array[-1]), pero no es que un comportamiento indefinido?

  • En caso de índices de matriz no está firmado?
¿Fue útil?

Solución

La razón de la int en main () es histórica - que siempre ha sido así, desde mucho antes de la lengua fue estandarizada. La exigencia de un índice de matriz es que está dentro de los límites de la matriz (o en algunas circunstancias, uno más allá del final) -. Todo lo demás es indefinido, por lo que el signo numérico es inmaterial

Otros consejos

1) Acerca de main () Tipo de argc: En mi humilde opinión el estándar continúa una tradición muy antigua (más de 30 años), y ahora ... es simplemente demasiado tarde para cambiar las cosas (NOTA: en la mayoría de los sistemas ni el compilador, ni el enlazador, ni la CPU se quejará si "argc" se define "sin firmar", pero que están fuera de la norma!)

2) En la mayoría de las implementaciones argv [argc] es legal y se evalúa como NULL. De hecho, una forma alternativa de encontrar el final de la lista de argumentos es iterar sobre argv del 0 al de terminación argv [i] es nulo.

3) aritmética Array / puntero con números negativos es legal en lo que el rango de dirección a partir de (p-n) a p pertenece a la misma objeto de memoria. ES DECIR. usted puede tener

char array[100];
char *p;

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

Este uso de la aritmética de punteros es legal porque el puntero resultante todavía permanece dentro del objeto de memoria original ( "array"). En la mayor parte del sistema de la aritmética de punteros se puede utilizar para navegar en la memoria, en violación de esta regla, pero esto no es portátil, ya que es totalmente dependiente del sistema.

En general en C, el "principio de la menor sorpresa" implica que es preferible hacer una variable firmó a menos que haya una buena razón para que sea firmado. Esto se debe a que las reglas de promoción de tipo pueden conducir a resultados inesperados cuando se mezcla firmado y valores sin signo: por ejemplo, si argc no estaba firmado, entonces este simple comparación conduciría a resultados sorprendentes:

if (argc > -1)

(El -1 es promovido a unsigned int, por lo que su valor se convierte a UINT_MAX, que es casi ciertamente mayor que argc).

1) ARGC es un número de argumentos, pero para ser sincero, ¿cómo se puede anteponer un argumento antes de que el nombre del programa, que argv[0]. Imagine un programa llamado foo, no se puede simplemente decir args1 foo args2 ya que es sin sentido, a pesar de la argc ser un tipo con signo de int, es decir, no hay tal cosa como argv[-1] que le llevará 'args1' ...

2) La razón argc no es realmente un índice para el vector de argumento (por lo tanto ' argv ') como el tiempo de ejecución mete el nombre del programa ejecutable en el zero'th offset, es decir, por lo tanto, argv[0] la argc estará apagado por 1.

3) índices de la matriz, en cuanto a la manipulación de punteros, siempre que se encuentra dentro de los límites del bloque de memoria donde el puntero está en, utilizando subíndices de matriz como negativos es legal como los subíndices de matriz son un acceso directo para los punteros, y no solo eso, son conmutativa por ejemplo

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

Además, si utiliza matrices y manipularlas de tal manera que se encuentra fuera de los límites - que es un comportamiento indefinido y dependerá de la implementación del tiempo de ejecución sobre cómo manejar la situación, tal vez un fallo de segmentación, o un programa accidente ....

4) En los entornos * nix, algunos podrían tener un tercer parámetro suministrado a char **endvp principal, de nuevo esto rara vez se utiliza en el mundo de Microsoft DOS / Windows. Algunas implementaciones * nix en tiempo de ejecución, por motivos prehistóricos, que pudieran pasar en las variables de entorno a través del tiempo de ejecución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top