¿Cómo maneja C enteros literales con ceros delante, y ¿qué pasa atoi?
Pregunta
Cuando se crea un entero con ceros a la izquierda, ¿cómo c manejarlo? ¿Es diferente para diferentes versiones de C?
En mi caso, sólo parecen estar disminuido (pero tal vez eso es lo que hace printf?):
#include <stdio.h>
int main() {
int a = 005;
printf("%i\n", a);
return 0;
}
Sé que puedo usar printf para rellenar con 0s, pero estoy preguntando cómo funciona esto.
Solución
ceros iniciales indican que el número se expresa en octal , o base 8; Por lo tanto, 010 = 8. La adición de ceros a la izquierda adicionales no tiene ningún efecto; del mismo modo que se puede esperar en matemáticas, x + 0 * 8 ^ n = x; no hay cambio en el valor al hacer su representación más tiempo.
Un lugar que usted ve a menudo esto es en los modos de archivos UNIX; 0755 significa en realidad 7 * 8 ^ 2 + 5 * 8 + 5 = 493; o con umasks tales como 0022 = 2 * 8 + 2 = 10.
atoi(nptr)
se define como equivalente a strtol(nptr, (char **) NULL, 10)
, excepto que no detecta errores - como tal, atoi()
siempre utiliza decimal (y por tanto ignora los ceros iniciales). strtol(nptr, anything, 0)
hace lo siguiente:
La cadena puede comenzar con una arbitraria cantidad de espacio en blanco (como se determina por
isspace(3)
) seguido de un único'+'
opcional o signo'-'
. Si la base es cero o 16, la cadena puede entonces incluir un prefijo"0x"
, y el número será leído en la base 16; de lo contrario, una base cero se toma como 10 (decimal) a menos que el carácter siguiente se'0'
, en cuyo caso se toma como 8 (octal).
Por lo tanto, utiliza las mismas reglas que el compilador C.
Otros consejos
Tenga cuidado!
En este 005
declaración es una constante octal.
int a = 005;
En este caso no importa porque una sola constante octal dígito tiene el mismo valor que la constante decimal equivalente pero en C: 015 != 15
Ya sea un número entero literal se expresa en octal, decimal o hexadecimal, una vez que se analiza por el compilador es sólo entendido como un valor. ¿Cómo es un número entero de salida a través printf
depende sólo de su tipo, su valor y los especificadores de formato (y la configuración regional activa).
El hecho de que un cero indica un número octal es algo que a menudo se olvida. Lo he visto varias causar confusión veces, como cuando alguien trató de introducir una dirección IP utilizando un formato amigable, regular para los octetos:
192.168.010.073
y el analizador interpreta los últimos 2 octetos como números octales.
La única cosa peor que lamentable uso de ceros a la izquierda de C para hacer una octal número es el manejo de Javascript de ceros a a veces hacer una octal número (el número es octal si el resto de los dígitos son OK - menos de 8 - decimal de otra manera). En Javascript, pero (017 == 15)
(018 == 18)
.
Yo prefiero que hay un error; En realidad prefiero gota de la ayuda octal literal por completo. Al menos usar un prefijo más en-su-cara, como tal vez
0t10 (ocTal 8)
0k17 (oKtal 15)
Pero estoy cerca de 35 años de retraso con mi propuesta.
A número con un cero significa codificación octal en todas las versiones de C. Así 011 == 9 == 0x9
.
octal es un sistema de numeración en base a 8 (en lugar de 10 para decimal o 16 para hex). Así 011 == 1*8 + 1, 013 == 1*8 + 3
, etc.
Usted debe tratar:
int a = 5;
printf("%03i\n", a);
0 significa "almohadilla con ceros", 3 es la longitud deseada de salida.
Editar Lo sentimos, he leído tu pregunta demasiado rápido - ahora veo lo solicitado por algo completamente diferente. Sin embargo voy a dejar esto como es, como podría ser útil para otra persona.
Una serie de dirigir 0
denota que el número es un octal número. Se llama Entero literales . También se puede utilizar para denotar 0b
número binario , número hexadecimal es 0x
o 0X
. No es necesario para escribir cualquier cosa para decimal . Ver el código de abajo.
#include<stdio.h>
int main()
{
int binary = 0b10;
int octal=010;
int decimal = 10;
int hexa = 0x10;
printf("%d %d %d %d\n", octal, decimal, hexa, binary);
}
Para obtener más información, visite tutorialspoint .
Los enteros no tienen "ceros a la izquierda" a 5 es un 5, puede escribir su representación de cadena con 0 a la izquierda si lo desea, para que tenga los modificadores printf.
En su caso particular, los ceros se redujo en un printf.
Todos los ceros iniciales son despojados a cabo por el compilador a excepción del cero inicial que hace que el compilador para tratar el entero como octal. Para 005, tanto el octal y representaciones decimales son los mismos y no debería molestar, pero aún así, es buscar problemas a menos que específicamente destinado a la representación octal.
Los ceros iniciales tienen que ver únicamente con la representación de cadena del número entero. Para imprimir con ceros a la izquierda, utilice "% 03d". Esto asegurará una longitud de campo de 3.
En general, "%