Fase 1 |
Editor
<---> disco |
el programa es creado en un editor y almacenado en
disco |
Fase 2 |
Preprocesador
<---> disco |
El prorpocesador procesa el código.
Procesa las líneas que cominezan con #. Crea un versión intermedia sin para ser compilada. Ésta no es visible al usuario. |
Fase 3 |
Compilador
<----> disco |
El compilador crea el código
objeto a partir del resultado de la etapa previa y lo almacena en disco. Éstos son los archivos de extensión .obj |
Fase 4 |
Ligador (linker) <----> disco |
Enlaza el código objeto
con las bilbiotecas y crea el archivo ejecutable en disco. |
Fase 5 |
Cargador (loader) <--- disco ----> Memoria |
Este pone el programa en memoria. |
Fase 6 |
CPU <----> Memoria Entrada y Salida |
Esta es la fase de ejecución del programa. |
#include <stdio.h>El código de este programa también se encuentra aquí ./* imprime la tabla de Fahrenheit-Celsius para fahr = 20,...,300 */
main ()
{int fahr, celsius;}
int lower, upper, step;lower = 0; /* limite inferior de la tabla de temperatura*/
upper = 300; /* limite superior */
step = 20; /* tamaño del incremento */fahr = lower;
while (fahr <= upper) {celsius = 5*(fahr-32)/9;}
printf("%d \t %d \n", fahr, celsius);
fahr = fahr + step;
Cosas a destacar: Biblioteca estándar, función
main, comentarios, declaración, otros tipos de datos (básicos:
char, short, long, double; estructurados: areglos, estructura, uniones),
significado del ";", concatenación de instrucciones, lazos de repetición,
la indentación del código, truncado al dividir enteros.
Discutir versión
en punto flotante (números Reales).
#include <stdio.h>
/* imprime la tabla Fahrenheit-Celsius */
main()
{
for( fahr=0; fahr <= 300; fahr=fahr+20)
printf("%3d %6.1f \n", fahr, (5.0/9.0)*(fahr-32));
En general el lazo while usa la sintaxis:
while (expresión)
sentencias_a_repetir
En general el lazo for usa la sintaxis:
for(expresión1; expresión2; expresión3)
instrucción_a_repetir
La sentencia for es equivalente a la secuencia:
expresión1;
while(expresión2) {
sentencia_a_repetir
expresión3;
}
Aquí
está el código de la versión con for
.
Lazo de repetición do-while:
do
sentencia_a_repetir
while (expresión);
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
int fahr;
for( fahr=LOWER; fahr <= UPPER; fahr=fahr+STEP)
printf("%3d %6.1f \n", fahr, (5.0/9.0)*(fahr-32));
}
La entrada y salida de dexto se maneja como un flujo de caracteres.
Aquí cada delimitador, de línea o fin de archivo, es considerado
como un caracter.
Ejemplo1: Copia
de la entrada en la salida
#include <stdio.h>
/* copia la entrada a la salida; 1a versión */
main()
{
int c;
c = getchar();
while( c != EOF ) { /* != no igual */
putchar(c);
c = getchar();
}
}
Explicar: EOF; cualquier asignación es una
expresión, lo cual da origen a la segunda versión del programa
eco .
Precedencia de operadores
Precedencia en orden decreciente | Asociatividad |
() [] -> . | ---> |
! ~ ++ -- + (unario) - (unario) *(referencia) & (dirección) (tipo) sizeof | ---> |
* / % | ---> |
+ - | ---> |
<< >> | ---> |
< <= > >= | ---> |
== != | ---> |
& | ---> |
^ | ---> |
| | ---> |
&& | ---> |
|| | ---> |
? : | <--- |
= += -= *= /= %= &= ^= |= >>= <<= | <--- |
, | ----> |
Ejemplo 2: Conteo de Caracteres
#include <stdio.h>
/* cuenta los caracteres de la entrada 2da versión */
main ()
{
double nc;
for (nc =0; getchar() != EOF; nc++)
;
printf("%.0f \n", nc);
}
Ejemplo 3: Conteo de Líneas
#include <stdio.h>
/* cuenta las líneas de la entrada */
main ()
{
int c, nl;
nl=0;
while( (c=getchar()) != EOF)
if ( c == '\n')
nl++;
printf("%d\n", nl);
}
#include <stdio.h>
/* cuenta dígitos, espacios blancos, y otros */
main()
{
nWhite = nOthers = 0;
for (i=0; i <10; i++)
nDigit[i]=0;
while( (c=getchar()) != EOF )
if (c >= '0' && c <= '9')
nDigit[c-'0']++;
else if ( c==' ' || c == '\n' || c == '\t')
nWhite++;
else
++nOthers;
printf ("digitos = ");
for (i = 0; i<10 ; ++i)
printf(" %d", nDigit[i]);
printf(", espacios blancos = %d, otros = %d \n",
Explicar: Paso de caracter ASCII a número entero
Patrón de la sentencia if :
if ( expresión1)
sentencia1
else if (expresión2)
sentencia2
...
.....
else
sentencian
El último else es opcional.
Destacar: int a[30], int *b;
Ubicación de a[0];
b=a;
interpretación de b+5; b--; *(b+3), (b+3)[0], (b+3)[4].
/* prototipo de funciones usadas antes de su definición */
int power(int , int );
/* prueba de la función power */
main()
{
int i;
for (i=0; i<10; ++i)
printf("%6d %6d %6d\n", i , power(2,i), power(-3,i));
return 0;
}
/* power: eleva la base a la n-ésima potencia; n >= 0 */
int power (int base, int n)
{
int i, p;
p=1;
for (i=1; i<=n; i++)
p = p*base;
return p;
}
Explicar: En C todos los parámetros de pasan
por valor. Los valores son copiados al interior de la función en
variables temporales. En el caso de los arreglos el nombre del arreglo representa
la dirección de la primera entrada de este.
Variables automáticas: son aquellas que se crean
y tienen existencia sólo durante la ejecución de una función.
Su alcance está limitado a la función que las declara.
Variables externas: Son aquellas que están definidas
fuera de las funciones y mantiene su existencia durante la ejecución
del programa. Las variables externas deben definirse una vez y
"deben" declararse en cada función que desee tener acceso a ella.
La declaración se hace con una sentencia extern explícita.
Bajo ciertas circunstancias la declaración extern puede omitirse.
No es necesario si la definición de una variable externa ocurre
dentro del archivo fuente antes de su uso por una función en particular.
Las variables externas son globales, hay que trarar de no hacer uso de
ellas cuando podemos reemplazarlas por variables automaticas o estáticas.
Estas últimas son aquellas tienen un alcance sólo alinterior
del bloque en que se definen pero mantienen su existencia y valor a lolargo
de la ejecución del programa.
Ejemplo : Determinar la línea más larga de una entrada.
En archivo LongestLine.c
#include <stdio.h>
#include "longestLine.h
"
int max;
char line[MAXLINE];
char longest[MAXLINE];
int getline(void);
void copy(void);
main ()
{
int len;
/* extern int max;
extern char longest[]; estas declaraciones
son opcionales !!*/
max=0;
while ((len=getline())>0)
if (len >max) {
max = len;
copy();
}
if (max>0) /* hubo una linea */
printf("%s", longest);
return 0;
}
En archivo getline.c
#include <stdio.h>
#include "longestLine.h"
/* getline: lee una linea desde entrada estandar */
int getline(void)
{
int c, i;
extern char line[]; /* ojo cuando la declaramos -no definición-
no se pone el tamaño del arreglo */
for (i=0; i<MAXLINE-1 && (c=getchar())!=EOF &&
c != '\n'; i++)
line[i] = c;
if( c== '\n') {
line[i] = c;
i++;
}
line[i]='\0';
return i;
}
En archivo copy.c
/* copy: copia una linea en otra */
void copy (void)
{
int i;
extern char line[], longest[];
i=0;
while((longest[i] = line[i])!='\0')
i++;
}
Explicar: Uso de varios archivos, inclusión de archivos
de headers (encabezado), definición v/s declaración, paso
de parámetros, delimitador de fin de string. salida de strings con
printf(), uso de void y listar u omitir lista de argumentos, importancia
de asociatividad (izq. der) del operador && en getline.
Uso de funciones, uso de parámetros (encapsulación)
Ojo aqui no se usaron parametros para ilustrar el acceso a variables externas,
pero en este problema debió usarse parámetros en la función
copy. Ejercicio: reescribir el programa para eliminar el uso de variables
externas en copy.c y usar parámetros.