Vous êtes sur la page 1sur 29

Introducción para programar en C

1.1.1 Lenguaje natural vs lenguaje de programación (1)

Estamos aquí para mostrarte el idioma "C" y para qué lo utilizamos. Consideremos por un
momento qué idioma es, no solo "C", sino cualquier idioma que use la gente. Trataremos de
no recurrir a definiciones científicas y, hablando de manera informal, podemos decir que un
idioma es una herramienta para expresar y registrar los pensamientos humanos.

En otras palabras, es un mecanismo conocido para nosotros y para nuestros socios que nos
permite a todos entendernos y ser comprendidos. Podemos usar nuestro lenguaje para hablar,
escribir, leer, escuchar, pensar y muchos otros propósitos.

Al menos un idioma nos acompaña a lo largo de nuestras vidas: es nuestro idioma materno,
nuestra lengua materna, que aprendemos casi inconscientemente desde el comienzo de
nuestras vidas. Aprenderemos otros idiomas, principalmente como resultado de una decisión
consciente, tal vez forzada por las condiciones sociales o las necesidades comerciales, o tal vez
simplemente por interés personal.

Los idiomas que usamos para comunicarnos con otras personas se llaman lenguajes naturales.
Fueron creados durante muchos siglos y aún están sujetos a cambios. Si ignoramos los
lenguajes que se han creado artificialmente, como el esperanto o incluso el quenya (el idioma
utilizado por los elfos en el mundo de Tolkien), podemos decir que los lenguajes naturales han
evolucionado de forma casi independiente, naturalmente; una evolución sobre la cual
tenemos poco o ningún control.

Sin embargo, hay idiomas cuya creación y desarrollo fueron y siguen siendo dictados por
necesidades específicas, y su desarrollo está completamente sujeto al control de amplios
grupos de personas, como comités internacionales y grupos de trabajo. Las formas de estos
lenguajes están definidos por estándares internacionales, y aunque son entendidos por
muchas personas, el intercambio de pensamientos entre seres humanos no es su aplicación
más importante.

Dichos lenguajes son, entre otros, los lenguajes de programación. Probablemente ya estés
familiarizado con este concepto. Un lenguaje de programación se define mediante un conjunto
de ciertas reglas rígidas, mucho más inflexibles que cualquier lenguaje natural.

Por ejemplo, estas reglas determinan qué símbolos (letras, dígitos, signos de puntuación, etc.)
podrían usarse en el idioma. Esta parte de la definición del lenguaje se llama léxico.

Otro conjunto de reglas determina las formas apropiadas de cotejar los símbolos: esta es la
sintaxis del idioma.

También nos gustaría poder reconocer el significado de cada enunciado expresado en el


lenguaje dado, y esto es lo que llamamos semántica.

Cualquier programa que escribamos debe ser correcto en estas tres formas: léxica, sintáctica y
semántica, de lo contrario no se ejecutará ni producirá ningún resultado aceptable. Puede
estar seguro de que en el transcurso de su carrera de programación, experimentará todos
estos errores: errar es humano, y estos humanos escriben programas de computadora.
El poder expresivo de los lenguajes de programación es mucho, mucho más débil que los
ofrecidos por los lenguajes naturales. No podemos (aunque podemos intentar) usar un
lenguaje de programación para expresar emociones humanas, y es difícil imaginar una
declaración de amor codificada en él. Es un hecho simple que el mensaje incrustado dentro de
un programa de computadora no está destinado a un ser humano, sino a una máquina.

Algunos podrían preguntar por qué necesitamos un lenguaje de programación. Esa es una
buena pregunta, una que intentaremos responder por usted ahora.

1.1.2 Lenguaje natural vs lenguaje de programación (2)

Una computadora, incluso la más sofisticada técnicamente, está desprovista de siquiera un


rastro de inteligencia. Se podría decir que es como un perro bien entrenado: responde solo a
un conjunto predeterminado de órdenes conocidas. Estos comandos reconocidos son muy
simples. Podemos imaginar que la computadora responde a pedidos como "tomar ese
número, agregar a otro y guardar el resultado". Un conjunto completo de comandos bien
conocidos se denomina lista de instrucciones, a veces abreviado como IL. Los diferentes tipos
de computadoras pueden variar según el tamaño de sus IL y las instrucciones en sí mismas
pueden diferir completamente de un modelo a otro.

El IL es, de hecho, el alfabeto de un idioma, comúnmente conocido como lenguaje de máquina.


Este es el lenguaje más simple y primario que podemos usar para dar órdenes a nuestra
computadora. Podríamos decir que es la lengua materna de la computadora.

La programación de computadoras es el acto de componer comandos seleccionados


(instrucciones) en el orden correcto para que se produzca el efecto deseado. El efecto en sí
mismo podría ser diferente en cada caso, depende de la imaginación, el conocimiento y la
experiencia del programador determinar qué efecto debería tener.

Es posible, y a menudo se usa en la práctica, que un programa de computadora se codifique


directamente en lenguaje de máquina usando instrucciones elementales (órdenes). Este tipo
de programación es tediosa, lenta y muy propensa a los errores de un programador. En las
primeras etapas de la tecnología informática, era el único método disponible de programación
y muy rápidamente reveló algunos defectos serios. En primer lugar, la programación en
lenguaje de máquina requiere un conocimiento exhaustivo del diseño del hardware de la
computadora y su estructura interna. Esto también significa que reemplazar la computadora
con una que difiera en el diseño puede inutilizar todo el conocimiento del programador.
Además, los viejos programas podrían volverse completamente inútiles si la nueva
computadora "usaba" una IL diferente. Por lo tanto, un programa escrito para un tipo
específico de computadora podría ser completamente inútil para otras computadoras y
viceversa. En segundo lugar, los programas escritos en lenguaje de máquina son muy difíciles
de entender para los humanos, incluidos los programadores experimentados. También lleva
mucho tiempo desarrollar programas en lenguaje de máquina, y es muy costoso y engorroso
también.

Todas estas circunstancias llevaron a la necesidad de algún tipo de puente entre el lenguaje
humano (lenguaje natural) y el lenguaje informático (lenguaje de máquina). Ese puente
también es un lenguaje, un lenguaje común intermedio para que los humanos y las
computadoras trabajen juntos. Tales idiomas a menudo se llaman lenguajes de programación
de alto nivel.

Un lenguaje de programación de alto nivel es al menos algo similar a un lenguaje natural; usa
símbolos, palabras y convenciones legibles para los humanos. Este lenguaje permite a los
humanos expresar comandos complejos para computadoras.

Puede preguntar cómo hacemos que las computadoras entiendan los programas escritos de
esta manera. El aliento no funcionará, pero puede traducir su programa al lenguaje de la
máquina. Además, la traducción se puede hacer en una computadora, lo que hace que todo el
proceso sea rápido y eficiente.

Observe cuántos beneficios puede obtener de un curso así. No necesita aprender muchos
lenguajes de máquina diferentes; solo necesita saber un lenguaje de programación de alto
nivel. Si hay un traductor diseñado para una computadora específica, su programa podría
ejecutarse sin ningún problema. En otras palabras, los programas escritos en lenguajes de alto
nivel podrían traducirse a cualquier cantidad de diferentes lenguajes de máquina y así hacerlos
utilizables en muchas computadoras diferentes. Esta característica de los lenguajes de
programación de alto nivel se llama portabilidad.

1.1.3 Lenguaje natural vs lenguaje de programación (3)

La traducción a la que nos referimos está hecha por un programa informático especializado
llamado compilador. El proceso de traducción de un lenguaje de alto nivel a un lenguaje de
máquina se llama compilación.

Ahora volvamos a cuestiones más interesantes relacionadas con el proceso de creación de un


nuevo programa. Ya sabemos que la tarea principal es escribir un programa de acuerdo con las
reglas del lenguaje de programación elegido. Tal programa (que de hecho es solo texto) se
llama código fuente, o simplemente fuente, mientras que el archivo que contiene la fuente se
llama archivo fuente.
Para escribir el código fuente necesita un editor de texto que le permita manipular el texto sin
ninguna información de formato (por esta razón Microsoft Word no es una buena opción, a
diferencia del Bloc de notas). Este código se coloca en un archivo y el nombre del archivo
debería darle alguna pista sobre su contenido. Por ejemplo, es común que un archivo que
contiene el código fuente en el idioma "C" tenga su nombre que termine con el sufijo ".c", así
que si usted escribió un programa de computadora y decidió nombrarlo "proggie" sería un
buena idea poner el código fuente en un archivo llamado "proggie.c".

Luego, tu código fuente necesita ser compilado. Para hacerlo, ejecute un compilador que le
indique dónde guardó el código fuente que desea traducir al lenguaje de la máquina. El
compilador lee su código, realiza algunos análisis complejos y su primer objetivo es determinar
si cometió algún error durante la codificación. Estos análisis son muy reveladores, pero
recuerde que están hechos por una máquina, no un ser humano, y no debe esperar demasiado
de ellos. De acuerdo, si su error fue que trató de sumar dos números usando "#" en lugar de
"+", el compilador le informará amablemente de su error. Sin embargo, si escribió un "-" en
lugar de un "+", el compilador ya no podrá adivinar que su intención era agregar dos números,
en lugar de restarlos. No espere que el compilador piense por usted. Pero no hay razón para
estar triste por eso, gracias a eso, aún se necesitan desarrolladores.

Si el compilador no nota ningún error en su fuente, el resultado de su trabajo será un archivo


que contenga su programa traducido a lenguaje de máquina. Ese archivo se llama
comúnmente un archivo ejecutable. El nombre del archivo depende del compilador que usa y
del sistema operativo con el que está trabajando. Por ejemplo, la mayoría de los compiladores
diseñados para el sistema Unix / Linux crean un archivo de salida llamado "a.out" de manera
predeterminada. Los compiladores diseñados para su uso en MS Windows® pueden darle a
este archivo el mismo nombre que el archivo fuente, solo cambiando el sufijo de ".c" a ".exe".

Debemos admitir que todo el proceso es en realidad un poco más complicado. Su código
fuente puede ser completo y estar dividido entre varios o incluso docenas de archivos fuente.
También puede suceder que el programa no haya sido escrito solo por usted, sino por un
equipo, en cuyo caso la división de fuentes en múltiples archivos es simplemente una
obligación. En tales casos, la compilación se divide en dos fases: una compilación de su fuente
para traducirla al lenguaje de máquina y unir (o pegar) su código ejecutable con el código
ejecutable derivado de otros desarrolladores en un único y unificado producto. La fase de
"pegar" los diferentes códigos ejecutables se conoce comúnmente como vinculación, mientras
que el programa que conduce el proceso se denomina enlazador.

El idioma "C" es uno de una gran cantidad de lenguajes de programación actualmente en uso,
y uno de los más antiguos. Fue creado a principios de los años setenta del siglo XX por Dennis
Ritchie mientras trabajaba en Bell Laboratories. Algunos dicen que "C" fue un subproducto de
un proyecto que condujo a la primera versión del sistema operativo Unix. Hay muchos otros
lenguajes de programación ampliamente utilizados, algunos de ellos podrían considerarse
como descendientes "C". Incluso heredaron un nombre de su antepasado, como "C ++" o "C
#". Otros tomaron prestadas algunas características de la "C" original y agregaron muchas
nuevas, como Perl, Java o JavaScript.

¿Cuál es el uso más común de "C"? Es el denominado lenguaje de programación de propósito


general, es decir, adecuado para casi cualquier proyecto de programación y, al mismo tiempo,
no está particularmente predestinado a ninguna clase específica y estrecha de aplicaciones. Es
mejor si se usa para codificar controladores, aplicaciones integradas o sistemas operativos (por
ejemplo, el kernel de Linux está codificado principalmente en "C"). También puede usarlo para
crear utilidades complejas. Podemos asegurarle que conocer el idioma "C" es muy útil si desea
aprender C ++, C # o Java.

Le garantizamos que el tiempo que dedique a aprender el idioma "C" no se desperdiciará.

1.1.4 Lectura adicional

Si tomas en serio el aprendizaje del lenguaje "C", ciertamente no dejarás de leer este texto.
Entre los cientos de libros escritos sobre el lenguaje "C", hay uno que es particularmente
recomendable. El libro se ha emitido docenas de veces en todo el mundo y está disponible en
más de 20 idiomas diferentes (naturales). Lo recomendamos sin dudarlo. Sin lugar a dudas, es
el mejor libro sobre programación de C jamás escrito; su alta calidad puede demostrarse por el
hecho de que uno de sus autores es Dennis Ritchie. El segundo autor es Brian Kernighan, el
compañero de trabajo de Dennis de cuando trabajaron juntos en los Laboratorios Bell. El libro
se llama simplemente The C Programming Language, pero no se sorprenda cuando sus amigos
lo aborden simplemente como "Kernighan-Ritchie".

Una vez que sea un programador competente, querrá acceder a una fuente de conocimiento a
través de la cual podrá comprender rápidamente las respuestas a las preguntas emergentes o
simplemente completar los vacíos en su memoria. En lugar de un manual, necesitará un libro
que describa brevemente los estándares del idioma, todo lo que es realmente importante y
nada más. Este libro es en realidad un informe (mejorado y actualizado permanentemente),
publicado por el comité de normalización de ISO. La versión más reciente del informe es ISO /
IEC 9899: TC3. Puede encontrarlo en Internet y buscarlo, pero aún es demasiado pronto para
que lo lea.

Mire eso cuando termine nuestro curso, no antes.

1.2.1 Tu primer programa (1)

Ahora nos gustaría mostrarte un programa muy simple (y completamente inútil) escrito en el
lenguaje "C". Usando este ejemplo, le mostraremos algunas reglas básicas ya que modificamos
el programa muchas veces, enriqueciéndolo con varios elementos y al mismo tiempo
expandiendo nuestro conocimiento de programación.

Primero, definimos nuestras expectativas para el programa. Ellos serán muy modestos.
Queremos que aparezca un texto breve y bastante sin sentido en la pantalla. Supongamos que
el texto debe proclamar al mundo:

-Soy yo, tu primer programa.

-No esperamos nada más de eso hasta el momento.

¿Qué pasos adicionales debe realizar nuestro primer programa? Intentemos enumerarlos aquí:

- Para comenzar;
- Escribir el texto en la pantalla;
- Para detener;

Este tipo de descripción estructurada y semiformal de cada paso del programa se denomina
algoritmo. Las fuentes de esta palabra se remontan a la lengua árabe, y se originó a principios
de la época medieval, que puede ser el pretexto para señalar que los inicios de la
programación informática se encuentran en tiempos muy antiguos.

Ahora es el momento de ver nuestro programa. Está en el lado derecho de la diapositiva.

Se ve un poco misterioso, ¿no? Ahora veremos cuidadosamente cada línea del programa,
explicando su significado y propósito. La descripción no es particularmente precisa y aquellos
que conocen el lenguaje "C" probablemente ya concluyan que es demasiado simplista y algo
infantil. Hicimos esto a propósito: no es nuestra intención construir Roma en un día.

Empecemos.

#include <stdio.h>
int main(void)
{
puts("It's me, your first program.");
return 0;
}

1.2.2 Tu primer programa (2)

Preste atención al caracter # (hash) al comienzo de la primera línea. Significa que el contenido
de esta línea es una directiva de preprocesador. Vamos a contarte más sobre el preprocesador
un poco más tarde, pero por ahora solo diremos que es una parte separada del compilador,
cuya tarea es leer previamente el texto del programa y hacer algunas modificaciones a eso. El
prefijo "pre" sugiere que estas operaciones se realizan antes de que tenga lugar el
procesamiento completo (compilación).

Los cambios que introduce el preprocesador están controlados por completo por sus
directivas. En el programa de ejemplo, estamos tratando con la directiva de inclusión. Cuando
el preprocesador encuentra esa directiva, reemplaza la directiva con el contenido del archivo
cuyo nombre figura en la directiva (en nuestro caso, este es el archivo stdio.h). Nota: los
cambios realizados por el preprocesador nunca modifican el contenido de su archivo fuente de
ninguna manera. Cualquier modificación se realiza en una copia volátil de su programa, que
desaparece inmediatamente después de que el compilador finaliza su trabajo.

Puede preguntar por qué queremos que el preprocesador incluya el contenido de un archivo
completamente desconocido stdio.h. Escribir un programa es similar a construir un edificio con
bloques prefabricados. En nuestro programa, vamos a usar dicho bloque y lo usaremos cuando
queremos escribir algo en la pantalla. Ese bloque se llama puts (puedes encontrarlo dentro de
nuestro código), pero el compilador no sabe nada al respecto hasta el momento. En particular,
el compilador no tiene idea de que puts es un nombre válido para ese bloque mientras que
pust no lo es. El compilador debe ser consciente de esto. Esta información preliminar que
necesita el compilador se incluye en los archivos cuyos nombres generalmente terminan en
".h" (encabezado). Estos archivos se denominan comúnmente archivos de encabezado.

El archivo stdio.h (definido por el estándar del lenguaje "C") contiene una colección de
información preliminar sobre bloques preparados que puede usar un programa para escribir
texto en la pantalla o leer letras del teclado. Entonces, cuando nuestro programa va a escribir
algo, obviamente usará un bloque llamado puts, que puede hacer el truco. No queremos que
el compilador se sorprenda, así que debemos advertirlo sobre eso. Los desarrolladores del
compilador ponen un conjunto de dicha información anticipatoria en el archivo stdio.h. Solo
tenemos que usar el archivo. Esto es exactamente lo que esperamos de la directiva de
inclusión.

También puede preguntar dónde se encuentra el archivo stdio.h. La respuesta es simple pero
no tan precisa como puede desear, pero ese no es nuestro problema en este momento. El
preprocesador sabe dónde está. Volveremos al tema cuando comencemos la historia detallada
de preprocesamiento.

#include <stdio.h>
int main(void)
{
puts("It's me, your first program.");
return 0;
}
1.2.3 Tu primer programa (3)
Ya hemos mencionado algo sobre bloques. Vamos un poco más profundo ahora. Uno de los
tipos más comunes de bloques utilizados para construir programas "C" es funciones. Si
entiendes funciones solo en un sentido puramente matemático, esta sigue siendo una buena
pista. Imagine una función como una caja negra, donde puede insertar algo en ella (no siempre
es necesario) y sacar algo nuevo de ella como si fuera un sombrero mágico. Las cosas que se
ponen en la caja se llaman argumentos de función (o parámetros de función). Las cosas que se
sacan de la caja se llaman resultados de función. Además, una función puede hacer otra cosa
en el lado. Si esto suena bastante vago, no se preocupe, hablaremos de funciones muchas
veces con más detalle.

Volvamos a nuestro programa. El estándar del lenguaje "C" asume que, entre los muchos
bloques diferentes que se pueden poner en un programa, un bloque específico siempre debe
estar presente, de lo contrario, el programa no será correcto. Este bloque siempre es una
función del mismo nombre: principal.
Cada función en "C" comienza con el siguiente conjunto de información:

¿Cuál es el resultado de la función?

¿Cuál es el nombre de la función?

¿Cuántos parámetros tiene la función y cuáles son sus nombres?

Eche un vistazo a nuestro programa e intente leerlo correctamente, aceptando el hecho de


que es posible que aún no comprenda completamente todo.

- el resultado de la función es un valor entero (lo leemos de la palabra int, que es la


abreviatura de entero)
- el nombre de la función es principal (ya sabemos por qué)
- la función no requiere ningún parámetro (que leemos de la palabra vacía)

Un conjunto de información como este a veces se denomina prototipo, y es como una etiqueta
adherida a una función que anuncia cómo podemos usar esa función en su programa. El
prototipo no dice nada sobre a qué se destina la función. Está escrito dentro de la función y el
interior de la función se llama cuerpo de la función. El cuerpo de la función comienza donde se
coloca el primer soporte de apertura {y termina donde se coloca el corchete de cierre
correspondiente}. Puede sonar sorprendente, pero el cuerpo de la función puede estar vacío;
esto solo significa que la función no hace nada.

Incluso podemos imaginar una función que es floja, se codificaría así:

Vacío perezoso (vacío) {}

Este dron no proporciona ningún resultado (el primer vacío), su nombre es "flojo", no toma
ningún parámetro (el segundo vacío) y no hace absolutamente nada (el espacio en blanco
entre los corchetes).

Por cierto, los nombres de las funciones están sujetos a restricciones bastante rígidas.
Discutiremos esto más tarde.

#include <stdio.h>
int main(void)
{
puts("It's me, your first program.");
return 0;
}
1.2.4 Tu primer programa (4)

Dentro del cuerpo de la función principal debemos escribir lo que nuestra función (y, por lo
tanto, el programa) debe hacer. Miramos adentro y encontramos una referencia a un bloque
llamado puts. Esto es lo que llamamos una invocación de función. Ahora consideremos algunos
detalles importantes.

En primer lugar, tenga en cuenta el punto y coma al final de la línea. Cada instrucción
(precisamente: cada instrucción) en "C" debe terminar con un punto y coma; sin ella, el
programa será incorrecto. Una afirmación como esta dice: instruir a la función llamada puts
para que muestre el texto en la pantalla. Puede preguntar: ¿cómo sabemos que la función de
poner lo hará por nosotros? Bueno, lo sabemos por los estándares de lenguaje "C", pero
también, el nombre de la función es una abreviación de "PUT String". El texto destinado a
mostrarse en la pantalla se pasa a la función como un parámetro de función. Recuerde que el
nombre de la función invocada siempre debe ir seguido de un par de paréntesis (y), incluso
cuando la función no espera ningún parámetro de nosotros.

En segundo lugar, el parámetro de la función pone es texto (cadena). Para simplificar,


podemos suponer que las cadenas en un programa en "C" están siempre entre comillas, de esa
manera el compilador distingue el texto que se envía al usuario del programa y el texto que se
pretende compilar (traducido al lenguaje de la máquina)) Esta distinción es muy importante.
Echar un vistazo:

- int main (vacío);

La línea de arriba es el prototipo de la función principal.

- "int main (void);"

La línea de arriba no es el prototipo de la función principal, sino una cadena que solo se ve
como parte de un código fuente. El compilador no está interesado en lo que se incluye entre
las comillas, y por lo tanto no lo reconoce como código.

¿Cómo funciona la invocación de la función? Podemos imaginarlo así: la ejecución de nuestra


función principal se suspende (podemos decir que la función principal se queda dormida) y
durante ese tiempo la función puts imprime el texto en la pantalla. Una vez que se imprime el
texto, se produce el retorno a la función principal y la función principal se activa y continúa su
actividad.

Deberíamos añadir aquí que la forma anterior de código fuente es la más natural y tal vez la
más fácil de leer para los humanos, pero no hay obstáculos para escribirla de una manera
bastante diferente, como esta:

pone

("Soy yo, tu primer programa");

En el lenguaje "C" no tiene que escribir solo una declaración por línea. Es posible colocar dos (o
más) enunciados en la misma línea, o dividir una declaración en varias líneas, pero tenga en
cuenta que la legibilidad (para los humanos) es el factor más importante. Los compiladores
nunca se quejarán de su estilo. ¡Qué suerte!

1.2.5 Tu primer programa (5)


Estamos llegando al final ahora. Solo queda una línea para explicar en nuestro programa. Esto
es:

return 0;
Además de la invocación de función, esta es otra declaración del lenguaje "C". Su nombre es
solo regresar y eso es exactamente lo que hace. Usado en la función, causa el final de la
ejecución de la función. Si realiza un retorno en algún lugar dentro de una función, esta
función interrumpe inmediatamente su ejecución. El cero que ves después de la palabra return
es el resultado de la función main. Esto es importante, así es como su programa le dice al
sistema operativo el siguiente mensaje: Hice lo que tenía que hacer, nada me detuvo y todo
está bien. Si tuviera que escribir

return 1;
Significaría que algo salió mal, no permitió que su programa tuviera éxito y el sistema
operativo podría usar esa información para reaccionar de la manera más adecuada.

¿Eso es todo? ¡Sí! Veamos nuevamente nuestro programa y veamos lo que está pasando paso
a paso:

- introducimos la función main en nuestro programa; se ejecutará cuando inicie el


programa;
- invocamos la función pone dentro de la función principal - imprimirá el texto en la
pantalla;
- el programa finaliza inmediatamente después de la impresión, lo que indica que se ha
logrado todo lo que esperaba lograr.

Esperamos que no haya sido tan difícil como parecía a primera vista. Ahora trataremos de
persuadir a la computadora para que calcule algo para nosotros. De hecho, para esto usamos
las computadoras.

#include <stdio.h>
int main(void)
{
puts("It's me, your first program.");
return 0;
}
1.3.1 Números y cómo los ven las computadoras

¿Sabes cómo las computadoras realizan cálculos en números? Quizás hayas oído hablar del
sistema binario y sepas que son las computadoras del sistema las que usan para almacenar
números, y que pueden realizar cualquier operación sobre ellos. No vamos a explorar las
complejidades de los sistemas de numerales posicionales aquí, pero diremos que los números
que manejan las computadoras modernas son de dos tipos:

- enteros, es decir, aquellos que están desprovistos de la parte fraccional;


- números de punto flotante (o simplemente flotantes), que contienen (o son capaces de
contener) la parte fraccionaria.

Esta definición no es del todo exacta, pero es lo suficientemente buena para nuestros
propósitos. Esta distinción es muy importante y el límite entre estos dos tipos de números es
muy estricto. Ambos tipos de números difieren significativamente en cómo se almacenan en la
memoria de una computadora y en el rango de valores aceptables. Además, la característica
de un número que determina su tipo, rango y aplicación se llama un tipo.

En este punto, nos hemos hecho amigos de dos tipos del lenguaje "C": un tipo entero (conocido
como int) y un tipo de coma flotante (conocido como float).

Por ahora, dejemos de lado los números flotantes (volveremos a consultarlos pronto) y
consideremos la pregunta, quizás un poco banal a primera vista, de cómo el lenguaje "C"
reconoce números enteros.

Bueno, es casi la misma forma en que estás acostumbrado a escribirlos con un lápiz sobre
papel: es simplemente una cadena de dígitos que componen el número. Pero hay una reserva:
no debe insertar ningún carácter que no sean dígitos dentro del número. Tomemos por
ejemplo el número once millones ciento once mil ciento once. Si tomaras un lápiz en tu mano
ahora mismo, escribirías el número así:

- 11,111,111

O (si eres polaco o alemán) como este:

- 11.111.111

O incluso así:

- 11 111 111
Obviamente, esto hace que sea más fácil de leer si el número está compuesto por muchos
dígitos. Sin embargo, en "C" está prohibido. Debe escribir este número de la siguiente manera:

- 11111111

De lo contrario, te expondrías a algunos comentarios mordaces del compilador. ¿Cómo


codificamos los números negativos en "C"? Como de costumbre, agregando un signo menos.
Puedes escribir:

- 11111111

Los números positivos no necesitan ir precedidos por el signo más, pero puede hacerlo si lo
desea. Las siguientes líneas describen el mismo número:

- +123

- 123

Por ahora, nos ocuparemos solamente de los enteros: presentaremos los números de coma
flotante en el próximo capítulo.

Hay dos convenciones adicionales, desconocidas para el mundo de las matemáticas. El primero
nos permite usar los números en una representación octal. Si un número entero está
precedido por el dígito 0, se tratará como un valor octal. Esto significa que el número debe
contener dígitos tomados del rango [0..7] solamente.

- 0123

Es un número octal con un valor decimal igual a 83.

El segundo nos permite usar números hexadecimales. Este tipo de número debe ir precedido
por un prefijo escrito como 0x o 0X.

- 0x123

Es un número hexadecimal con un valor decimal igual a 291.

Quizás quieras ver el resultado de tu cálculo. Discutiremos esto más adelante (en el Capítulo
2.5), pero ahora es un buen momento para mencionar cómo imprimir el valor de un número.

Bueno, para imprimir un número entero, debe usar (esto es solo una forma simple):

printf ("% d \ n", Número entero o expresión);


Para imprimir un número de punto flotante, debe usar (esto es solo una forma simple):

printf ("% f \ n", Número de flotador o expresión);

En ambos casos, primero debe incluir el archivo de encabezado stdio (como lo hicimos en el
primer programa):

#include <stdio.h>

1.3.2 Una variable es variable (1)

Parece bastante obvio que el lenguaje "C" nos permite escribir números. No te sorprenderá
que podamos hacer algunas operaciones aritméticas con estos números: sumar, restar,
multiplicar y dividir. Lo haremos pronto. Pero es perfectamente una pregunta normal
preguntar cómo almacenar los resultados de estas operaciones para usarlas en otras
operaciones. Hay "contenedores" especiales para este propósito y estos contenedores se
llaman variables. El nombre sugiere que el contenido de un contenedor puede variarse (casi)
de cualquier forma.

¿Qué tiene cada variable?

- un nombre
- un tipo
- un valor

Comencemos nuestra discusión con los problemas relacionados con el nombre de una
variable. Las variables no aparecen en nuestro programa de alguna manera mágica. Nosotros
(como desarrolladores) decidimos cuántas y qué variables queremos que existan en nuestro
programa. También les damos sus nombres, casi convirtiéndonos en sus padrinos. Si desea dar
un nombre a una variable, debe seguir algunas reglas estrictas:

- el nombre de la variable debe estar compuesto de letras latinas en mayúsculas o


minúsculas, dígitos y el carácter _ (guión bajo);
- el nombre de la variable debe comenzar con una letra
- el carácter subrayado es una letra (extraño pero cierto)
- las letras mayúsculas y minúsculas se tratan como diferentes (un poco diferente que
en el mundo real: Alice y ALICE son los mismos nombres de pila, pero son dos nombres
de variables diferentes, en consecuencia, dos variables diferentes)
Tenga en cuenta que las mismas restricciones se aplican a los nombres de funciones.

El estándar del lenguaje "C" no impone restricciones en la longitud de los nombres de las
variables, pero un compilador específico puede tener una opinión diferente sobre este asunto.
No te preocupes por lo general, la limitación es tan alta que es poco probable que realmente
desee utilizar nombres de variables (o funciones) tan largos.

Estos son algunos nombres de variables correctos, pero no siempre convenientes:

- variable
- yo
- t10
- Tipo de cambio
- Mostrador
- DaysToTheEndOfTheWorld
- TheNameOfAVariableWhichIsSoLongThatYouWillNotBeAbleToWriteItWithoutMistake_

El apellido en particular puede plantear inquietudes, pero desde el punto de vista del
compilador no hay nada de malo en ello.

Y ahora algunos nombres incorrectos:

- 10t (no está con una letra)


- Adiós_Señora (contiene caracteres ilegales)
- Tipo de cambio (contiene un espacio)

1.3.3 Una variable es variable (2)


El tipo es un atributo que define de forma única qué valores se pueden almacenar dentro de la
variable. Ya conocemos tipos enteros (int) y de coma flotante (flotante). El valor de una
variable es lo que hemos puesto en él. Por supuesto, solo puede poner un valor que sea
compatible con el tipo de variable. Solo se puede asignar un valor entero a una variable entera
(para decir lo mismo pero de una manera ligeramente diferente a una variable de tipo int). El
compilador no nos permitirá poner un número de coma flotante allí.

Hablemos ahora sobre dos cosas importantes: cómo se crean las variables y cómo poner un
valor dentro de ellas (o mejor dicho, cómo darles un valor).

La variable aparece como resultado de una declaración. Una declaración es una estructura
sintáctica que vincula un nombre, proporcionado por el programador, a un tipo específico
ofrecido por el lenguaje "C". La construcción de la declaración (en otras palabras, la sintaxis de
la declaración) es simple: simplemente use el nombre del tipo deseado, luego el nombre de la
variable (o nombres de variables separados por comas si hay más de uno). Toda la instrucción
termina con un punto y coma.

1.3.4 Una variable es variable (3)


Intentemos declarar una variable de tipo int llamada Mostrador. La parte relevante del
programa se ve así:

- int Mostrador;

¿Qué se declara por el siguiente fragmento de un programa?

- int variable1, account_balance, facturas;

Declara tres variables de tipo int denominadas (respectivamente) variable1, account_balance y


facturas.

Recuerde que puede usar tantas declaraciones variables como necesite para lograr su objetivo.

1.3.5 Una variable es variable (4)

¿Y cómo le damos un valor a la variable recién declarada? Necesita usar el operador de


asignación. Aunque esto suena bastante misterioso, el operador tiene una sintaxis simple y
una interpretación inequívoca. El operador de asignación se ve muy familiar, aquí está:

- =

Veamos algunos ejemplos:

- Contador = 1;

La instrucción anterior dice: asigne un valor de 1 a una variable llamada Contador o un poco
más corto asigne 1 a Contador.

Algunos usan una convención diferente y la leen como: el contador se convierte en 1.


1.3.6 Una variable es variable (5)

Otro ejemplo:

- Resultado = 100 + 200;

En este caso, el nuevo valor de la variable Resultado será el resultado de agregar 100 a 200, lo
que probablemente no sea una sorpresa para usted, ¿verdad?

1.3.7 Una variable es variable (6)


Y ahora un ejemplo un poco más difícil:

- x = x + 1;

Al ver eso, un matemático probablemente protestaría: ningún valor puede ser igual a uno más
uno. Esto es una contradicción.

Pero en el lenguaje "C", el signo "=" no significa que es igual a, sino que asigna un valor.

Entonces, ¿cómo leemos tal registro en el programa?

Tome el valor actual de la variable x, agréguele 1 y almacene el resultado en la variable x

En efecto, el valor de la variable x se incrementó en uno, lo que no tiene nada que ver con la
comparación de la variable con ningún valor.

1.3.8 palabras clave: ¿por qué son las claves?

Eche un vistazo al lado derecho de la pantalla; hay una lista de palabras que desempeñan un
papel muy especial en cada programa de lenguaje "C". Se llaman palabras clave, o (más
precisamente) palabras clave reservadas. Son reservados porque no debe usarlos como
nombres: ni para sus variables, funciones ni otras entidades nombradas que quiera crear. El
significado de la palabra reservada está predefinido y no debe modificarse de ninguna manera.
Afortunadamente, dado que el compilador "C" distingue entre mayúsculas y minúsculas,
puede modificar cualquiera de estas palabras cambiando la mayúscula de cualquier letra,
creando así una nueva palabra, que ya no está reservada.
Por ejemplo, no puedes hacer esto:

- int int;

No debe tener una variable llamada int, está prohibido. Pero puedes hacer esto en su lugar:

- Int Int;

El compilador estará contento, muy contento.

1.3.9 Comentarios sobre los comentarios (1)

Ahora vamos a hacer algunos comentarios. No nos referimos a comentarios sobre sus logros o
nuestros logros. Nos referimos a todos los otros comentarios, a saber, los comentarios sobre el
programa y dentro del programa al mismo tiempo.
El desarrollador puede querer poner algunas palabras
dirigidas no al compilador sino a los humanos, por lo general
para explicar a otros lectores del código cómo funcionan los
trucos utilizados en el código, o los significados de las
variables y funciones y, finalmente, para mantenga la
información almacenada sobre quién es el autor y cuándo se escribió el programa.

Los desarrolladores buenos (y responsables) describen cada función; en particular, explican el


papel de los parámetros, el valor que devuelve la función como resultado y lo que realmente
hace la función.

¿Cómo dejamos este rastro en el código fuente? Tiene que hacerse de una manera que no
obligue al compilador a interpretarlo como parte del código. Una observación insertada en un
programa que se omite en el momento de la compilación se llama comentario.

Si queremos ser precisos, deberíamos decir que cada comentario es léxicamente equivalente a
un espacio. Cada vez que el compilador encuentra un comentario en su programa, el
comentario es completamente transparente: desde el punto de vista del compilador, este es
solo un espacio (independientemente de cuánto tiempo sea el comentario real).

En el lenguaje "C", un comentario es un texto que comienza con el par de caracteres

- /*

y termina con el par de personajes

- */

El comentario puede abarcar varias líneas o puede ocupar solo una línea o solo parte de una
línea.

1.3.10 Comentarios sobre los comentarios (2)

A un lado, puede ver un ejemplo de un comentario cuidadoso y justo ingresado en el


programa. Cualquier desarrollador que lea el programa tendrá conocimiento del verdadero
significado de la variable. El desarrollador leerá el código más rápido y le tomará menos
tiempo entenderlo.

- / * La variable contraria cuenta el número de ovejas en el prado * /


- int contador;
1.3.11 Comentarios sobre los comentarios (3)

Los desarrolladores a menudo colocan una nota al comienzo de la fuente que nos informa
cuándo escribieron el programa y quién lo modificó y por qué. La nota puede aparecer así:

A pesar de la estructura complicada y la multitud de estrellas, la condición que indica cómo se


debe comenzar y finalizar el comentario se cumple por completo.

Los comentarios pueden ser útiles en otro aspecto: puede usarlos para marcar un fragmento
de código que actualmente no es necesario por el motivo que sea. A menudo hacemos esto
durante las pruebas de un programa para aislar el lugar donde podría ocultarse un error.

- / *************************************************
Contando ovejas versión 1.0
Autor: Ronald Sleepyhead, 2012
correo electrónico: rs@insomnia.org

Cambios:
2012-09-13: Ginny Drowsy: contar ovejas negras mejoró
************************************************* /

1.3.12 Comentarios sobre los comentarios (4)

Lo que nos queda ahora es tratar con otro aspecto de este caso. Los compiladores difieren al
evaluar si otro comentario puede colocarse dentro de un solo comentario. Considere el
siguiente programa →

- /* int i; /* int j; */ int k; */


La pregunta es: ¿es la declaración de la variable k un comentario o no? Si el compilador
permite el uso de comentarios dentro de los comentarios, todo el registro se tratará como un
comentario. De lo contrario, si el compilador no acepta tales comentarios (a veces llamados
comentarios anidados) verá la declaración de la variable k como una parte normal y visible del
programa y el último par de * / se considerará no válido porque el compilador no puede
determinar dónde comenzó el comentario

Este es ciertamente un argumento en contra de anidar comentarios en sus programas.


2.1.1 Números de coma flotante (1)

Números flotantes en la vida real y en el lenguaje "C"

En nuestra primera lección, nos familiarizamos con el concepto del tipo de datos y aprendimos
que uno de los tipos básicos conocidos en el lenguaje "C" es el tipo entero llamado int.

Ahora es el momento de hablar sobre otro tipo, que está diseñado para representar y
almacenar números que (como diría un matemático) tienen una fracción decimal no vacía.

En otras palabras, son los números que tienen (o pueden tener) una parte fraccional después
del punto decimal, y aunque dicha definición es muy pobre, sin duda es lo suficientemente
buena para nuestros propósitos. Cada vez que usamos un término como "dos y medio" o "cero
punto cuatro", pensamos en los números que una computadora considera números flotantes.

2.1.2 Números de coma flotante (2)

Números flotantes en la vida real y en el lenguaje "C"

Regresemos a los valores que citamos hace un momento. "Dos y medio" parece normal
cuando lo escribes en un programa, aunque si tu idioma nativo prefiere usar una coma en
lugar de un punto en el número, debes asegurarte de que tu número no contenga comas. El
compilador no lo aceptará, o (en casos muy raros pero posibles) malinterpretará tus
intenciones, ya que la coma misma tiene su propio significado reservado en el idioma "C".

Si desea usar un valor de solo "dos y medio", debe escribirlo como se muestra en la imagen.
Tenga en cuenta una vez más: hay un punto entre "2" y "5", no una coma.
2.1.3 Números de coma flotante (3)

Números flotantes en la vida real y en el lenguaje "C"

Como probablemente se pueda imaginar, el valor de "punto cero cuatro" podría escribirse en
"C" como:

0.4

No olvides esta regla simple: puedes omitir el cero cuando es el único dígito delante o después
del punto decimal. En esencia, puede escribir el valor 0.4 como se muestra a la derecha.

2.1.4 Números de coma flotante (4)


Números flotantes en la vida real y en el lenguaje "C"

Por ejemplo: el valor de 4.0 podría escribirse como 4. sin cambiar su tipo o valor.

Nota: el punto decimal es esencial para reconocer números en coma flotante en "C". Mira
estos dos números:

- 4
- 4.0

Para ti, pueden ser exactamente iguales, pero el compilador "C" ve estos dos números de una
manera completamente diferente.

- 4 es un int.
- 4.0 es un doble (se puede asignar fácilmente a flotar).

Podemos decir que el punto hace un doble. No lo olvides


2.1.5 Números de coma flotante (5)
Números flotantes en la vida real y en el lenguaje "C"

Cuando desee usar cualquier número que sea muy grande o muy pequeño, puede usar la
notación científica. Tome, por ejemplo, la velocidad de la luz, expresada en metros por
segundo. Escrito directamente, se vería así:

- 300000000

Para evitar escribir tantos ceros tediosamente, los libros de texto de física usan una forma
abreviada, que probablemente ya hayas visto:

- 3 • 10 ^ 8

Se lee: "tres veces diez a la potencia de ocho"

En el lenguaje "C", se logra el mismo efecto en una forma ligeramente diferente, eche un
vistazo:

- 3E8

La letra E (también puede usar la letra minúscula e - viene de la palabra exponente) es una
versión concisa de la frase "multiplicado por diez a la potencia de".

Nota:

• el exponente (el valor después de la "E")

tiene que ser un número entero.

• la base (el valor al frente de la "E")

puede o no ser un número entero.


2.1.6 Números de coma flotante (6)
Números flotantes en la vida real y en el lenguaje "C"

Veamos cómo usamos esta convención para registrar números que son muy pequeños (en el
sentido de su valor absoluto, que es cercano a cero). Una constante física llamada constante
de Planck (y denotada como h) tiene, según los libros de texto, el valor de:

- 6.62607 x 10-34

Si desea utilizarlo en un programa, debe escribirlo de esta manera:

- 6.62607E-34

¿Estás con nosotros hasta ahora?

2.1.7 Números de coma flotante (7)

Números flotantes en la vida real y en el lenguaje "C"

Regresemos a los valores de coma flotante. Ya sabe qué es una variable y también puede
declarar una variable entera, por lo que no le sorprenderá cómo declarar las variables de tipo
flotante. Esto se hace usando la palabra clave float. Sabiendo que podemos declarar dos
variables de punto flotante, llamadas PI (no podemos nombrarlas Π porque, como ya sabes, el
idioma "C" no permite nombres de variables escritas con letras griegas) y Campo:

Como puede ver, desde el punto de vista de la sintaxis, la diferencia al declarar variables
enteras y flotantes es bastante pequeña.
2.1.8 Números de coma flotante (8)
Números flotantes en la vida real y en el lenguaje "C"

Esta diferencia es muy significativa en términos de semántica, que se muestra en el ejemplo de


la derecha. Con un poco de anticipación, podemos decir que el símbolo (más precisamente, el
operador) que realiza la división matemática es un solo carácter / (barra oblicua). Eche un
vistazo a este código.

int i;
float x;
i = 10 / 4;
x = 10.0 / 4.0;
Sin embargo, puede encontrar un poco sorprendente que el valor colocado en la variable i sea
2 (sí, ¡solo 2!), Mientras que la variable x es igual a 2.5. Mire este ejemplo detenidamente,
porque ilustra una diferencia muy importante entre estos dos tipos de datos.

2.1.9 Números de coma flotante (9)


Números flotantes en la vida real y en el lenguaje "C"

¿Qué sucede cuando nos vemos obligados a convertir valores enteros en valores flotantes o
viceversa? La transformación de tipo int a float siempre es posible y factible, pero en algunos
casos puede causar una pérdida de precisión. Considere el ejemplo a la derecha →.

int i;
float f;
i = 100;
f = i;
Después de la segunda asignación, el valor de la variable f es 100.0, porque el valor de tipo int
(100) se convierte automáticamente en un flotante (100.0). La transformación afecta la
representación interna (máquina) de esos valores, ya que las computadoras usan diferentes
métodos para almacenar flotantes y datos en su memoria.
2.1.10 Números de coma flotante (10)

Números flotantes en la vida real y en el lenguaje "C"

Consideremos la situación opuesta ahora.

Como probablemente haya adivinado, estas sustituciones resultan en una pérdida de


precisión: el valor de la variable i será de 100. Veinticinco centésimas no tiene ningún
significado en el mundo int. Hay otro aspecto de la operación: la conversión de un flotante en
un int no siempre es factible. Las variables enteras (como flotantes) tienen una capacidad
limitada.

int i;
float f;
f = 100.25;
i = f;
No pueden contener números arbitrariamente grandes (o arbitrariamente pequeños). Por
ejemplo, si un determinado tipo de computadora usa cuatro bytes (es decir, 32 bits) para
almacenar valores int, solo podrá usar los números del rango de -2147483648..2147483647.

2.1.11 Números de coma flotante (11)

Números flotantes en la vida real y en el lenguaje "C"

La variable i no puede almacenar un valor tan grande, pero no está claro qué sucederá durante
la asignación. Ciertamente, se producirá una pérdida de precisión, pero el valor asignado a la
variable i no se conoce de antemano. En algunos sistemas, puede ser el valor int máximo
permitido, mientras que en otros se produce un error y, en otros, el valor asignado puede ser
completamente aleatorio.

int i;
float f;
f = 1E10;
i = f;
Esto es lo que llamamos un problema dependiente de la implementación. Es la segunda (y más
fea) cara de la portabilidad del software.

2.2.1 Operadores

Un operador es un símbolo del lenguaje de programación que puede operar en los valores. Por
ejemplo, un operador de asignación es el signo =. Usted ya sabe que puede asignar valores a
las variables.

Echemos un vistazo a otros operadores disponibles en el lenguaje "C" y aprendamos qué reglas
rigen su uso y cómo interpretar las operaciones que realizan. Comenzaremos con los
operadores asociados con operaciones aritméticas ampliamente reconocibles. El orden de su
apariencia no es accidental. Hablaremos más al respecto al final.

2.2.2 Multiplicación

Un asterisco ("*") es un operador de multiplicación. Si echas un vistazo al código, verás que la


variable k se establecerá en el valor de 120, mientras que la variable z se establecerá en 0.625.

int i,j,k;
float x,y,z;
i = 10;
j = 12;
k = i * j;
x = 1.25;
y = 0.5;
z = x * y;
2.2.3 División

Una barra oblicua ("/") es un operador divisional. El valor delante de la barra es un dividendo,
el valor detrás de la barra, un divisor. Considere el fragmento del programa: por supuesto, k se
establecerá en 2, z en 0,5.

int i,j,k;
float x,y,z;
i = 10;
j = 5;
k = i / j;
x = 1.0; y = 2.0;
z = x / y;

2.2.4 División por cero

Como probablemente haya adivinado, la división por cero está estrictamente prohibida, pero
la penalización por violar esta regla le llegará en diferentes momentos. Si se atreve a escribir
algo así, el compilador emitirá un juicio: puede obtener un error de compilación y no podrá
ejecutar su programa.

float x;
x = 1.0 / 0.0;
2.2.5 División por cero
En el siguiente ejemplo, el compilador no le dirá nada, pero cuando intente ejecutar el código,
puede terminar anormalmente y producir resultados poco fiables. Serás informado de este
hecho triste por un mensaje relevante y luego nada más sucederá.

float x,y;

x = 0.0;
y = 1.0 / x;

2.2.6 Adición

El operador de suma es el signo "+" (más), que ya conocemos de las matemáticas. De nuevo,
eche un vistazo al fragmento del programa; por supuesto, k pasa a ser 102 y z a 1.02.

int i,j,k;
float x,y,z;
i = 100;
j = 2;
k = i + j;
x = 1.0;
y = 0.02;
z = x + y;
2.2.7 Resta
El operador de resta es obviamente el signo "-" (menos), aunque debe tener en cuenta que
este operador también tiene otro significado: puede cambiar el signo de un número. Esta es
una gran oportunidad para mostrarle una distinción muy importante entre operadores unarios
y binarios (en el lenguaje "C" también hay un operador ternario; hablaremos más sobre esto
un poco más adelante).
int i,j,k;
float x,y,z;
i = 100;
j = 200;
k = i - j;
x = 1.0;
y = 1.0;
z = x - y;

Como de costumbre, vamos a familiarizarnos con un fragmento de código: probablemente


puedas adivinar que k será igual a -100, mientras que z será igual a 0.0.

2.2.8 Menos unario

Al "restar" aplicaciones, el operador menos espera dos argumentos: el izquierdo (un minuendo
en términos aritméticos) y el derecho (un sustraendo). Por esta razón, el operador de resta se
considera uno de los operadores binarios, al igual que los operadores de suma, multiplicación
y división. Pero el operador menos se puede usar de una manera diferente, eche un vistazo al
fragmento.

int i,j;
i = -100;
j = -i;
Como probablemente haya adivinado, a la variable j se le asignará el valor de 100. Usamos el
operador menos como operador unario, ya que solo espera un argumento: el correcto.