Leí en el libro The C Programming Language de Dennis Ritchie que intdebe usarse para que una variable contenga EOF, para que sea lo suficientemente grande como para que pueda contener el valor EOF, no char. Pero el siguiente código funciona bien:
#include<stdio.h>
main() {
char c;
c=getchar();
while(c!=EOF) {
putchar(c);
c=getchar();
}
}
Cuando no hay más entrada, getchardevuelve EOF. Y en el programa anterior, la variable c, con el tipo char, puede mantenerlo con éxito.
¿Por qué funciona esto? Según la explicación en el libro mencionado anteriormente, el código no debería funcionar.

0xff. Almacenar el resultado degetchar()unintresuelve ese problema. Su pregunta es esencialmente la misma que la pregunta 12.1 en las preguntas frecuentes de comp.lang.c , que es un excelente recurso. (Además,main()debería serint main(void), y no estaría de más agregar unreturn 0;antes del cierre}.)Respuestas:
Parece que su código funciona, porque las conversiones de tipo implícito accidentalmente hacen lo correcto.
getchar()devuelve unintcon un valor que se ajusta al rango deunsigned charo esEOF(que debe ser negativo, por lo general es -1). Tenga en cuenta que enEOFsí mismo no es un carácter, sino una señal de que no hay más caracteres disponibles.Al almacenar el resultado desde
getchar()adentroc, hay dos posibilidades. El tipocharpuede representar el valor, en cuyo caso ese es el valor dec. O el tipocharno puede representar el valor. En ese caso, no está definido lo que sucederá. Los procesadores Intel simplemente cortan los bits altos que no encajan en el nuevo tipo (reduciendo efectivamente el valor del módulo 256char), pero no debe confiar en eso.El siguiente paso es comparar
cconEOF. ComoEOFes unint,ctambién se convertirá en unint, conservando el valor almacenado enc. Sicpudiera almacenar el valor deEOF, entonces la comparación tendrá éxito, pero si nocpuede almacenar el valor, entonces la comparación fallará, porque ha habido una pérdida irrecuperable de información al convertir a tipo .EOFcharParece que su compilador eligió
charfirmar el tipo y el valor de loEOFsuficientemente pequeño como para caberchar. Sicharno estuviera firmado (o si lo hubiera usadounsigned char), su prueba habría fallado, porqueunsigned charno puede contener el valor deEOF.También tenga en cuenta que hay un segundo problema con su código. Como
EOFno es un personaje en sí mismo, pero lo fuerza a unchartipo, es muy probable que haya un personaje que se malinterprete como siendoEOFy para la mitad de los posibles personajes no está definido si se procesarán correctamente.fuente
charvalores fuera del rangoCHAR_MIN...CHAR_MAXserá necesaria para generar un valor definido por la implementación, generar un patrón de bits que la implementación define como una representación de trampa o generar una señal definida por la implementación. En la mayoría de los casos, las implementaciones tendrían que pasar por mucho trabajo adicional para hacer algo más que la reducción del complemento a dos. Si la gente en el Comité de Normas se suscribieron a la idea de que los compiladores deben ser animados a poner en práctica comportamientos consistentes con la de la mayoría de los compiladores en ausencia de razones para hacer lo contrario ...(signed char)xdebería considerarse más claro y tan seguro como((unsigned char)x ^ CHAR_MAX+1))-(CHAR_MAX+1)). Tal como es, no veo ninguna probabilidad de compiladores que implementan cualquier otro comportamiento que cumpla con el estándar actual; El único peligro sería que el estándar podría cambiarse para romper el comportamiento en el supuesto interés de "optimización".int i=129; signed char c=i;es uno de esos comportamientos. Relativamente pocos procesadores tienen una instrucción quecigualaríaicuando está en el rango de -127 a +127 y produciría un mapeo consistente de otros valores deia valores en el rango de -128 a +127 que difieren de la reducción del complemento a dos, o. ..