Lenguaje C 2023-2
Lenguaje C 2023-2
Lenguaje C 2023-2
Apoyo a Investigación C. P. D.
Servicios Informáticos U. C. M.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-1-
1 INDICE
1 INDICE___________________________________________________________1
2 INTRODUCCION___________________________________________________3
3 ELEMENTOS______________________________________________________5
3.1 Comentarios___________________________________________________________5
3.2 Identificadores_________________________________________________________5
3.3 Constantes_____________________________________________________________5
3.4 Variables______________________________________________________________6
3.5 Operadores____________________________________________________________6
3.6 Sentencias_____________________________________________________________6
3.7 Macros del preprocesador________________________________________________6
4 TIPOS_____________________________________________________________7
5 DECLARACIONES__________________________________________________9
5.1 Alcance_______________________________________________________________9
5.2 Visibilidad_____________________________________________________________9
5.3 Durabilidad____________________________________________________________9
6 OPERADORES____________________________________________________11
6.1 Operadores aritméticos_________________________________________________11
6.2 Operadores lógicos_____________________________________________________11
6.3 Operadores relacionales_________________________________________________11
6.4 Operadores de asignación_______________________________________________12
6.5 Operadores de dirección________________________________________________12
6.6 Operadores de movimiento______________________________________________12
6.7 Prioridad y asociatividad de los operadores________________________________13
7 SENTENCIAS_____________________________________________________14
7.1 Etiquetas de sentencia__________________________________________________14
7.2 Sentencias compuestas__________________________________________________14
7.3 Sentencias de selección__________________________________________________14
7.4 Sentencias de iteración__________________________________________________16
7.5 Sentencias de salto_____________________________________________________17
8 FUNCIONES______________________________________________________19
8.1 Definición_____________________________________________________________19
8.2 Declaración___________________________________________________________19
8.3 Llamadas a funciones___________________________________________________20
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-2-
9 ARRAYS Y CADENAS______________________________________________21
9.1 Arrays unidimensionales________________________________________________21
9.2 Cadenas______________________________________________________________21
9.3 Arrays multidimensionales______________________________________________22
9.4 Inicialización de arrays_________________________________________________22
10 PUNTEROS_______________________________________________________23
10.1 Asignación de punteros_________________________________________________23
10.2 Aritmética de punteros__________________________________________________23
10.3 Punteros y arrays______________________________________________________24
10.4 Arrays de punteros_____________________________________________________24
10.5 Indirección múltiple____________________________________________________25
10.6 Funciones de asignación dinámica, malloc() y free()__________________________25
11 ENTRADA Y SALIDA______________________________________________27
11.1 E/S por consola________________________________________________________27
11.2 E/S por archivos_______________________________________________________29
12 PREPROCESADOR________________________________________________31
13 LIBRERIAS_______________________________________________________33
14 EJERCICIOS______________________________________________________34
15 BIBLIOGRAFIA___________________________________________________51
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-3-
2 INTRODUCCION
El lenguaje C fue inventado e implementado por primera vez por Dennis Ritchie en un
DEC PDP-11 en Bell Laboratories.
Durante muchos años el estándar de C fue la versión proporcionada con la versión cinco
del sistema operativo UNIX. En 1983, el instituto de estándares americanos estableció
un estándar que definiera el lenguaje C, conocido como ANSI C. Hoy día, todos los
principales compiladores de C llevan implementado el estándar ANSI.
C permite la manipulación de bits, bytes y direcciones (los elementos básicos con que
funciona la computadora).
Otras características del C es que posee muy pocas palabras clave (32, donde 27 fueron
definidas en la versión original y cinco añadidas por el comité del ANSI, enum, const,
signed, void y volatile). Todas las palabras clave de C están en minúsculas (C distingue
entre las mayúsculas y minúsculas). En la siguiente tabla se muestran las 32 palabras
clave:
Los programas en C consisten en una o más funciones. La única función que debe estar
absolutamente presente es la denominada main, siendo la primera función que es
llamada cuando comienza la ejecución del programa. Aunque main no forma
técnicamente parte del lenguaje C, hay que tratarla como si lo fuera, pues si se emplea
para nombrar una variable, probablemente confundirá al compilador.
instrucciones del
preprocesador declaraciones
globales
tipo_devuelto main(lista de parámetros)
{
secuencia de sentencias
}
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-4-
…..
…..
tipo_devuelto función_n(lista de parámetros)
{
secuencia de sentencias
}
El programa así escrito se denomina programa fuente y puede estar escrito en uno o
varios ficheros.
Para que el programa pueda ser ejecutado se debe compilar y enlazar (linkar) con todas
aquellas funciones de la biblioteca que se necesiten.
Una vez enlazado el programa objeto, tenemos un programa ejecutable que se puede
ejecutar en el ordenador.
El compilador en las máquinas Alpha del C. P. D. es el DEC OSF/1 Versión 4.0. Para
compilar y enlazar un programa con este compilador basta con hacer
cc nombre_del_programa.c
Los ejemplos del curso siguen la sintaxis aceptada por el estándar ANSI, con lo que son
portables con cualquier otro compilador que lo lleve implementado.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-5-
3 ELEMENTOS
3.1 Comentarios
Los comentarios son textos que no son procesados por el compilador. Sirven como
información al programador.
Para que un texto sea comentario debe estar entre los símbolos /* (marca el comienzo) y
*/ (marca el final de comentario).
3.2 Identificadores
Se usan para referenciar las variables, las funciones, las etiquetas y otros objetos
definidos por el usuario. La longitud del identificador puede variar entre uno o varios
caracteres (se recomienda no más de 31 y si el identificador está envuelto en el proceso
de enlazado al menos los seis primeros deben ser significativos).
El primer carácter debe ser una letra o un símbolo subrayado y los caracteres siguientes
pueden ser letras, números o símbolos de subrayado. Las minúsculas y las mayúsculas
se tratan como distintas.
Un identificador no puede ser igual a una palabra clave de C y no debe tener el mismo
nombre que una función ya escrita o que se encuentre en la biblioteca de C.
3.3 Constantes
Pueden ser:
- Números enteros: Su formato es “signo dígitos marcadores”. El signo puede ser “-“
(negativo) o “+” (positivo, por defecto). Los dígitos se pueden escribir en notación
decimal, octal (base 8, un 0 seguido de una secuencia de números del 0 al 7) o en
hexadecimal (base 16, un 0 seguido por una x (o X) y una secuencia de dígitos del 0
al 9 y de la A B a la F). Los marcadores definen el tipo de entero (ver capítulo
siguiente), la ‘l’ (o L) asocia un entero long y la “u” (o U) de tipo unsigned. Por
ejemplo 1234lu.
Para asignar un identificador a una constante se realiza con la directiva #define (ver
capítulo 12).
3.4 Variables
Una variable es una posición de memoria con nombre que se usa para mantener un valor
que puede ser modificado en el programa. Todas las variables deben ser declaradas
antes de poder usarlas. Una variable puede ser fijada a una constante con la sintaxis
const tipo identificador = valor (por ejemplo const int a=10). También existe otro
modificador del tipo de acceso (volatile) que permite cambiar el valor de una variable
por medios no explícitamente especificados por el programa, por ejemplo la dirección
de una variable global que apunta a un puerto externo (volatile unsigned char
*puerto=0x30;).
3.5 Operadores
Los operadores son palabras o símbolos que hacen que un programa actúe sobre las
variables.
3.6 Sentencias
Una macro es una codificación de instrucciones que implican una o varias acciones. El
preprocesador toma como entrada el programa fuente en C antes que el compilador y
ejecuta todas las macros que encuentra.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-7-
4 TIPOS
Cuando en C, se dice que un objeto es de un tipo, se quiere decir que ese objeto
pertenece a un conjunto específico de valores con los cuales se pueden realizar un
conjunto de operaciones también determinadas.
Existen cinco tipos básicos: carácter, entero, coma flotante, coma flotante de doble
precisión y void.
Los demás tipos se basan en alguno de estos tipos básicos. El tamaño y el rango de estos
tipos de datos varían con cada tipo de procesador y con la implementación del
compilador de C.
El tipo void, o bien declara explícitamente una función como que no devuelve valor
alguno, o bien crea punteros genéricos.
La siguiente tabla muestra todas las combinaciones que se ajustan al estándar ANSI
junto con sus rangos mínimos y longitudes aproximadas en bits.
C utiliza unos tipos de elementos creados, como son las enumeraciones, estructuras,
uniones y estructuras y tipos definidos por el usuario.
Las enumeraciones son listas de constantes enteras con nombre. Para crear una
enumeración se utiliza la palabra reservada enum. La sintaxis es la siguiente:
En una enumeración, el primer valor tiene, por defecto, el valor 0; el segundo nombre 1,
y así sucesivamente. Este valor se puede cambiar por el programador, por ejemplo:
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-8-
struct dir {
char nombre[30];
char calle[40];
char ciudad [20];
};
Para referir a un elemento individual de la estructura se utiliza el operador punto (.), por
ejemplo, dir.nombre = ’Pedro’;
Uniones: es una posición de memoria que es compartida por dos o más variables
diferentes, generalmente de distinto tipo, en distintos momentos. La definición es
similar a la de la estructura. La palabra clave es union:
union etiq {
int i;
char ch
};
En una variable que este definida del tipo etiq, tanto el entero i como el carácter ch
comparten la misma posición de memoria.
5 DECLARACIONES
Todos las variables deben ser declaradas. En las declaraciones es obligado especificar el
tipo.
5.1 Alcance
El alcance sirve para saber en qué región del código una declaración de un objeto está
activa, es decir, el objeto existe.
5.2 Visibilidad
La visibilidad nos indica en qué región del código un objeto está activo. La diferencia
con el alcance es que en una misma región pueden estar dos objetos con el mismo
identificador, ocultando un objeto a otro.
5.3 Durabilidad
6 OPERADORES
Existe otro tipo de operador denominado molde que su función es hacer posible que una
expresión sea de un tipo determinado utilizando la sintaxis
(tipo) expresión;
Siendo tipo uno de los tipos estándar de C (ver capítulo 4). Por ejemplo, si se quiere
asegurar que la expresión x/2 se evalúe de tipo float, se puede escribir: (float) x/2;.
OPERADORES ARITMETICOS
OPERADOR SIGNIFICADO
+ Suma
- Resta
* Producto
/ Cociente de una división
% Resto de una división
OPERADORES LOGICOS
OPERADOR SIGNIFICADO
! Not (no lógico)
&& And (y lógico)
|| Or (ó lógico)
OPERADORES RELACIONALES
OPERADOR SIGNIFICADO
== Igual a
!= No igual a
> Mayor que
< Menor que
>= Mayor o igual que
<= Menor o igual que
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-12-
OPERADORES DE ASIGNACION
OPERADOR SENTENCIA SENTENCIA NO
ABREVIADA ABREVIADA
= = =
++ m++ m=m+1
-- m-- m=m-1
+= m+=n m=m+n
-= m-=n m=m-n
*= m*=n m=m*n
/= m/=n m=m/n
%= m%=n m=m%n
Por ejemplo:
int x=1, y;
y=x++; /* y es 1 y x vale 2 */
int x=1, y;
y=++x; /* x vale 2 e y también vale 2 */
OPERADORES DE DIRECCION
OPERADOR SIGNIFICADO
* Operador de contenido de apuntado u
operador de indirección
& Operador de dirección
Los dos operandos deben ser del tipo entero, y mueve los bits de la expresion1 tantas
posiciones como se lo indique la expresion2 (en este caso hacia la izquierda).
Operador Asociatividad
() [] De izquierda a derecha
- ++ -- ! ~ * & sizeof(tipo) De derecha a izquierda
*/% De izquierda a derecha
+- De izquierda a derecha
<< >> De izquierda a derecha
< <= > >= De izquierda a derecha
== != De izquierda a derecha
& De izquierda a derecha
&& De izquierda a derecha
|| De izquierda a derecha
?: De derecha a izquierda
= *= /= %= += -= &= <<= >>= De derecha a izquierda
, De izquierda a derecha
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-14-
7 SENTENCIAS
Una sentencia es cualquier expresión en C que se espera que tenga alguna consecuencia.
Pueden ser asignaciones, operaciones, llamadas a funciones o combinaciones de ellas.
Una sentencia simple consiste en una expresión acabada en un punto y coma (;).
Sirven para etiquetar una sentencia de forma que el control del programa pueda ser
transferido a ella. Se separan de la sentencia por dos puntos “:”.
La sintaxis es:
etiqueta: sentencia;
Es un conjunto de sentencia simples que se encierran entre los símbolos “{” y “}” para
formar un bloque de código.
Pueden aparecer en cualquier sitio en el que podría aparecer una sentencia simple.
La sintaxis es:
{
sentencia;
sentencia;
….
sentencia;
}
Existen dos tipos, if y switch. Además, el operador “?” es una alternativa para if en
ciertas situaciones.
IF
if (expresion) sentencia;
else sentencia;
Donde sentencia puede ser una sentencia simple, un bloque de sentencias o nada (en el
caso de sentencias vacías). La cláusula else es opcional. Si la expresión del if es cierta
(cualquier valor que no sea 0), se ejecuta la sentencia o el bloque de sentencias que
constituye el objetivo del if; en cualquier otro caso se ejecuta la sentencia o bloque de
sentencias que constituye el objetivo del else, si existe. Siempre se ejecuta el código
asociado al if o al else, nunca ambos.
if(i) {
if(j) sentencia 1;
if(k) sentencia 2; /* este if esta */
else sentencia 3; /* asociado con este else */
}
La alternativa ?
Se puede usar el operador “?” para reemplazar las sentencias if-else con la forma
general:
if(condición) Expresión1;
else Expresión2;
x = 10;
y = x >9 ? 100 : 200;
SWITCH
switch (expresión) {
case constante1:
secuencia de
sentencias; break;
case constante1:
secuencia de
sentencias; break;
case constante1:
secuencia de
sentencias; break;
…..
…..
default:
secuencia de sentencias;
}
Se comprueba el valor de la expresión, por orden, con los valores de las constantes
especificadas en las sentencias case. Cuando se encuentra una correspondencia, se
ejecuta la secuencia de sentencias asociada con ese case, hasta que se encuentra la
sentencia break o el final de la sentencia switch. Si no se incluye la sentencia break,
sigue buscando más correspondencias en las siguientes sentencias case. La sentencia
default se ejecuta si no se ha encontrado ninguna correspondencia. La sentencia default
es opcional, y si no está presente, no se ejecuta ninguna acción al fallar todas las
comprobaciones.
El estándar ANSI específica que una sentencia switch debe permitir al menos 257
sentencias case. En la práctica el número empleado es menor por razones de eficiencia.
Aunque case es una sentencia de etiqueta, no tiene calidad por sí misma fuera de un
switch.
No puede haber dos constantes case en el mismo switch que tengan los mismos valores
(por supuesto que una sentencia switch contenida en otra sentencia switch pude tener
constantes case que sean iguales).
FOR
El incremento define como cambia la variable de control cada vez que se repite el bucle.
Estas tres secciones principales deben ser separadas por punto y coma (“;”). El bulce for
continua ejecutándose mientras que la condición sea cierta. Una vez que la condición es
falsa, la ejecución del programa sigue por la sentencia siguiente al for.
WHILE
DO-WHILE
A diferencia de los bucles for y while, que analizan la condición del bucle al principio
del mismo, el bucle do-while analiza la condición al final del bucle. Esto significa que le
bucle do-while siempre se ejecuta al menos una vez. La forma general es:
do {
sentencia;
} while (condición);
Aunque las llaves no son necesarias cuando sólo hay una sentencia, se utilizan
normalmente para evitar confusiones al programador con el while.
C tiene cuatro sentencias que llevan a cabo un salto incondicional (además de goto, pero
su uso no está bien visto por sus programadores): return, break, exit() y continue.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-18-
RETURN
Se usa para volver de una función. Se trata de una sentencia de salto porque hace que la
ejecución vuelva al punto en que se hizo la llamada a la función. Si hay algún valor
asociado con return, se trata del valor de vuelta de la función. Si no se especifica un
valor de vuelta, se asume que devuelve un valor sin sentido. La forma general es:
return expresión;
Donde expresión es opcional. Se pueden usar tantas sentencias return como se quiera
en una función. Sin embargo, la función termina al encontrar el primero.
BREAK
Tiene dos usos: para finalizar un case en una sentencia switch y para forzar la
terminación inmediata de un bucle, saltando la evaluación condicional normal del ciclo.
Cuando se encuentra la sentencia break dentro de un bucle, el bucle finaliza
inmediatamente y el control sigue en la sentencia posterior al bucle.
EXIT()
CONTINUE
8 FUNCIONES
8.1 Definición
La lista de parámetros es la lista de nombres de variables separados por comas con sus
tipos asociados que reciben los valores de los argumentos cuando se llama a la función.
Una función puede no tener parámetros, en cuyo caso la lista de parámetros está vacía;
sin embargo, los paréntesis son necesarios.
8.2 Declaración
Si una función va usar argumentos, debe declarar variables que acepten los valores de
los argumentos. Estas variables se llaman parámetros formales de la función y se
comportan como variables locales dentro de la función, creándose al entrar en la función
y destruyéndose al salir. La declaración de parámetros aparece después del nombre de la
función al definirla.
Los parámetros formales tienen que ser del mismo tipo que los argumentos usados al
llamar una función (el compilador no dará error pero los resultados serán inesperados).
Al igual que con variables locales, se pueden hacer asignaciones a los parámetros de
una función o usarlos en cualquier expresión válida. Se pueden usar como cualquier otra
variable.
Una función es visible para ella misma y otras funciones desde el momento en que se
define. Es visible para el propio cuerpo de la función, es decir, la recursividad esta
permitida.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-20-
El código de una función es privado a esa función y sólo se puede acceder a él mediante
una llamada a esa función. Las variables definidas dentro de una función son locales (a
no ser que las definamos globales) por lo que no conservan su valor de una llamada a
otra (excepto si se declaran como static, entonces el compilador no las destruye y
almacena su valor para la próxima llamada, aunque la variable tiene limitado el ámbito
al interior de la función).
En C, todas las funciones están al mismo nivel, es decir, no se puede definir una función
dentro de otra función. Esto es por lo que C no es técnicamente un lenguaje estructurado
por bloques.
Las funciones son llamadas para su ejecución desde cualquier parte del código, teniendo
en cuenta que antes deben haber sido declaradas (y por supuesto definidas).
En general, se pueden pasar argumentos a las funciones de dos formas, por valor y por
referencia.
9 ARRAYS Y CADENAS
Un array es una colección de variables del mismo tipo que se referencian por un nombre
común. A un elemento específico de un array se accede mediante un índice. En C todos
los arrays constan de posiciones de memoria contiguas. La dirección más baja
corresponde al primer elemento y la más alta al último. Los arrays pueden tener una o
varias dimensiones. El array más común en C es la cadena, que simplemente es un array
de caracteres terminado por uno nulo.
Los arrays unidimensionales son listas de información del mismo tipo que se guardan en
posiciones contiguas de memoria según el orden del índice.
Los arrays tienen que declararse implícitamente para que el compilador reserve espacio
en memoria para ellos. El tipo declara el tipo de los elementos del array, el tamaño
indica cuántos elementos mantendrá el array.
char p[10];
En este caso hemos declarado un array que tiene diez elementos, desde p[0] hasta p[9].
En C todos los arrays tienen el 0 como índice de su primer elemento.
C no comprueba los límites de los arrays. Se puede pasar cualquier extremo de un array
y escribir en alguna otra variable de datos e incluso en el código del programa.
9.2 Cadenas
Una constante de cadena es una lista de caracteres encerrada entre dobles comillas. Por
ejemplo:
la lista de valores es una lista de constantes separadas por comas cuyo tipo es
compatible con el tipo especificado en la declaración del array. Por ejemplo:
Con las cadenas o arrays de caracteres se hace igual, aunque permite una inicialización
abreviada. Estas dos sentencias producen el mismo resultado:
Los arrays multidimensionales se inicializan del mismo modo que los unidimensionales.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-23-
10 PUNTEROS
Un puntero es una variable que contiene una dirección de memoria. Normalmente, esa
dirección es la posición de otra variable de memoria. Si una variable contiene la
dirección de otra variable, entonces se dice que la primera variable apunta a la segunda.
Si una variable va a contener un puntero, entonces tiene que declararse como tal. Una
declaración de un puntero consiste en un tipo base, un * y el nombre de la variable. La
forma general es:
tipo *nombre;
Después de declarar un puntero, pero antes de asignarle un valor, éste contiene un valor
desconocido; si en ese instante lo intenta utilizar, probablemente se estrellará, no sólo el
programa sino también el sistema operativo. Por convenio, se debe asignar el valor nulo
a un puntero que no este apuntando a ningún sitio, aunque ésto tampoco es seguro.
int x;
int *p1,*p2;
p1=&x;
p2=p1;
Existen sólo dos operaciones aritméticas que se puedan usar con punteros: la suma y la
resta.
Cada vez que se incrementa un puntero, apunta a la posición de memoria del siguiente
elemento de su tipo base. Cada vez que se decrementa, apunta a la posición del
elemento anterior. Con punteros a caracteres parece una aritmética normal, sin embargo,
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-24-
el resto de los punteros aumentan o decrecen la longitud del tipo de datos a los que
apuntan.
Por ejemplo, si asumimos que los enteros son de dos bytes de longitud y p1 es un
puntero a entero con valor actual 2000. Entonces, después de la expresión p1++; p1
contiene el valor 2002, no 2001.
No pueden realizarse otras operaciones aritméticas sobre los punteros más allá de la
suma y resta de un puntero y un entero. En particular, no se pueden multiplicar o dividir
punteros y no se puede sumar o restar el tipo float o el tipo double a los punteros.
Existe una estrecha relación entre los punteros y los arrays. Considérese el siguiente
fragmento:
Aquí, p1 ha sido asignado a la dirección del primer elemento del array cad. Para acceder
al quinto elemento de cad se escribe cad[4] o *(p1+4).
Un nombre de array sin índice devuelve la dirección de comienzo del array, que es el
primer elemento. El compilador traduce la notación de arrays en notación de punteros.
Es decir, al crear un array se genera un puntero (en realidad una constante de puntero)
con el mismo nombre que apunta a la dirección del primer elemento del array.
Los punteros pueden estructurarse en arrays como cualquier otro tipo de datos. La
declaración, por ejemplo, para un array de punteros a enteros de tamaño 10 es:
int *x[10];
Para asignar la dirección de una variable entera llamada var al tercer elemento del array
de punteros se escribe:
x[2]=&var;
*x[2];
Si se quiere pasar un array de punteros a una función, se puede utilizar el mismo método
que se utiliza para otros arrays: llamar simplemente a la función con el nombre del array
sin índices. Así se pasa el puntero que apunta al array.
Se puede hacer que un puntero apunte a otro puntero que apunte a un valor de destino.
Esta situación se denomina indirección múltiple o punteros a punteros.
Una variable que es puntero a puntero tiene que declararse como tal. Esto se hace
colocando un * adicional en frente del nombre de la variable. Por ejemplo, la siguiente
declaración inicial indica al compilador que ptr es un puntero a puntero de tipo float:
float **ptr;
El centro del sistema de asignación dinámica está compuesto por las funciones
(existentes en la biblioteca stdlib.h) malloc(), que asigna memoria; y free() que la
devuelve.
Tras una llamada fructífera, malloc() devuelve un puntero, el primer byte de memoria
dispuesta. Si no hay suficiente memoria libre para satisfacer la petición de malloc(), se
da un fallo de asignación y devuelve un nulo. El fragmento de código que sigue asigna
1000 bytes de memoria:
char *p;
p = (char *) malloc(1000);
int *p;
p= (int *) malloc(50*sizeof(int));
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-26-
11 ENTRADA Y SALIDA
En C no existe ninguna palabra clave para realizar la entrada y salida de datos (E/S). Se
realizan a través de funciones de biblioteca (concretamente, la biblioteca stdio.h, ver
capítulo 13).
Las funciones principales que realizan la entrada y salida sin formato son:
getchar(): Lee un carácter del teclado. Espera hasta que se pulsa una tecla y
entonces devuelve su valor.
putchar(): Imprime un carácter en la pantalla en la posición actual del cursor.
gets(): Lee una cadena de caracteres introducida por el teclado y la sitúa en
una dirección apuntada por su argumento de tipo puntero a carácter.
puts(): Escribe su argumento de tipo cadena en la pantalla seguida de un
carácter de salto de línea.
El siguiente fragmento de código lee un carácter del teclado y lo muestra por pantalla. A
continuación lee una cadena (de 10 caracteres incluido el carácter nulo) y también la
muestra por pantalla:
#include <stdio.h>
main()
{
char cadena[10];
int i;
i=getchar();
putchar(i);
gets(cadena);
puts(cadena);
}
Las funciones principales que realizan la entrada y salida con formato, es decir, se
pueden leer y escribir en distintas formas controladas, son:
En la función printf() (con scanf() no), entre las comillas se pueden poner rótulos
literales mezclados con los caracteres de transmisión.
Donde aparecen las letras N.D o no se pone nada o serán en realidad dos números que
dicen que la transmisión total del valor al menos ocupará N posiciones (si el número
necesita más de N las tomará, si usa menos las dejara en blancos, a menos que se quiera
rellenar con ceros, entonces se pone 0N) y que la parte decimal tendrá como máximo las
D posiciones después de un punto.
Una l precediendo a N (p.e. %l5d) significa que transmitiremos un long int : si, por el
contrario, es una h significa que transmitiremos un short int.
Existe otro tipo de carácter especial, los caracteres de escape , que tienen un
significado especial. Los caracteres de escape son los siguientes:
La lista de argumentos estará separada por comas. Debe existir una correspondencia
biyectiva entre los caracteres de transmisión (aquellos que comienzan con un %) y la
lista de argumentos a transmitir.
Cabe destacar una diferencia en la lista de argumentos entre las funciones printf() y
scanf(). En está ultima función (scanf()), la lista de argumentos va precedida por el
operador de dirección(&), puesto que scanf() requiere que los argumentos sean las
direcciones de las variables, en lugar de ellas mismas.
En C un archivo puede ser cualquier cosa, desde un archivo de disco a un terminal o una
impresora. Se asocia una secuencia con un archivo específico realizando una operación
de apertura, una vez que está abierto, la información puede ser intercambiada entre éste
y el programa. El puntero a un archivo es el hilo que unifica el sistema de E/S con
buffer. Un puntero a un archivo es un puntero a una información que define varias cosas
sobre él, incluyendo el nombre, el estado y la posición actual del archivo. En esencia, el
puntero a un archivo identifica un archivo en disco específico y utiliza la secuencia
asociada para dirigir el funcionamiento de las funciones de E/S con buffer. Para obtener
una variable de tipo puntero a archivo se debe utilizar una sentencia como la siguiente:
FILE *punt;
La función fopen() abre una secuencia para que pueda ser utilizada y le asocia a un
archivo. Su prototipo es:
por ejemplo, si desea abrir un archivo llamado prueba para escritura, escribir:
FILE *fp;
fp=fopen(“prueba”,”w”);
La función fclose() cierra una secuencia que fue abierta mediante una llamada a fopen().
Escribe toda la información que todavía se encuentre en el buffer del disco y realiza un
cierre formal del archivo a nivel del sistema operativo. También libera el bloque de
control de archivo asociado con la secuencia, dejándolo libre para su reutilización. A
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-30-
veces es necesario cerrar algún archivo para poder abrir otro, debido a la existencia de
un límite del sistema operativo en cuanto al número de archivos abiertos. Su prototipo
es:
La función putc() escribe caracteres en un archivo que haya sido abierto previamente
para operaciones de escritura, utilizando la función fopen(). Su prototipo es:
La función getc() escribe caracteres en un archivo que haya sido abierto, en modo
lectura, mediante fopen(). Su prototipo es:
La función fgets() lee una cadena de la secuencia especificada hasta que se lee un
carácter de salto de línea o hasta que se han leído longitud-1 caracteres. Su prototipo es:
La función rewind() inicia el indicador de posición al principio del archivo indicado por
su argumento. Su prototipo es:
Existen otras muchas funciones en la biblioteca estándar de C (ver capítulo 13) como
pueden ser
12 PREPROCESADOR
Los comandos para el procesador se ponen entre las líneas de código fuente pero se
distinguen porque comienzan con el símbolo “#”. La lista de comandos normalizados
del procesador son:
Comando Acción
#define Define una macro.
P.e.: #define CIERTO 1
#error Fuerza al compilador a parar la compilación, mostrando
un mensaje de error
P.e.: #error mensaje_de_error
#include Incluye otro archivo fuente.
P.e.: #include <stdio.h>
#undef Elimina una definición de macro previa.
P.e.: #undef CIERTO
#if Permite la inclusión de texto en función del valor de una
expresión test
#endif Marca el final de un bloque #if.
P.e.: #if expresión-constante
secuencia sentencias
#endif
#else Incluye un texto si el test establecido en el comando #if, o
#ifdef o #ifndef que le precede ha dado resultado falso.
#elif Significa “else if”.
#ifdef y #ifndef Permite la inclusión de texto en función de si ha sido
definida o no previamente un nombre de macro
respectivamente.
#line Cambia los contenidos de _LINE_ y _FILE_, que son
identificadores del compilador predefinidos. _LINE_
contiene el número de línea que se está compliando
actualmente. _FILE_ es una cadena que contiene el
nombre del archivo fuente que se está compilando.
P.e.: #line número “nombre de archivo”
#pragma Definida por la implementación que permite se den varias
instrucciones al compilador.
La línea completa que comienza con “#” es una línea para el procesador. Si se desea
que la siguiente línea del fichero sea continuación de la anterior, esta debe acabarse con
“ \”.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-32-
Las expresiones que se pueden poner en los comandos del preprocesador cuando
ponemos la fórmula “expresión”, debe ser una expresión que diese los mismos
resultados que si la escribiésemos en una línea de C. El resultado debe ser una
constante.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-33-
13 LIBRERIAS
Todas las librerías son declaradas en un fichero cabecera. Para que sea visible al
programa, se añade el comando del preprocesador #include. Por ejemplo
#include <stddef.h>;
Librería Descripción
assert.h Contiene una macro para el diagnóstico dentro de los
programas.
ctype.h Contiene varias funciones para comprobación de tipos y
transformación de caracteres.
errno.h Contiene varias macros usadas para informar de errores.
limits.h Contienen varias macros que definen constantes para el tamaño
de tipo enteros.
float.h Contienen varias macros que definen constantes para el tamaño
de tipo flotante.
locale.h Contienen varias macros, funciones y tipos para unidades
locales, como unidad monetaria, tiempo, dígitos, etc.
math.h Contiene una macro y varias funciones matemáticas.
setjmp.h Contienen declaraciones que proporcionan una forma de evitar
la secuencia normal de llamada y regreso de funciones.
signal.h Contiene un tipo, dos funciones y varias macros para manejar
condiciones excepcionales que aparecen durante la ejecución,
tal como una señal de interrupción de una fuente externa o un
error en la ejecución.
stdarg.h Contiene un tipo y tres macros que proporcionan recursos para
recorrer una lista de argumentos de función de tamaño y tipo
desconocido.
stddef.h Contiene varios tipos y macros que también están definidas en
otras librerías, como size_t.
stdio.h Contiene tipos, macros y funciones para la realización de tareas
de E/S.
stdlib.h Contiene tipos, macros y funciones para la conversión
numérica, generación de números aleatorios, búsquedas y
ordenación, gestión de memoria y tareas similares.
string.h Contiene tipos, macros y funciones para la manipulación de
cadenas de caracteres.
time.h Contiene tipos, macros y funciones para la la manipulación de
información sobre fechas y horas.
Para una descripción con más detalle, ver el manual del compilador DEC C.
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-34-
14 EJERCICIOS
/* Primer programa */
#include <stdio.h>
main()
{
printf("Primer programa\n");
}
#include <stdio.h>
main ()
{
char car;
printf("Escriba un caracter: ");
car=getchar();
printf("\nEl caracter introducido es %c.\n",car);
}
#include <stdio.h>
#define N 3
main()
{
struct agenda
{
char nombre[25];
char telefono[10];
int edad;
};
struct agenda amigos[N]={{"Pepe","913472314",18},
{"Juan","915547623",19},
{"Rosa","917456778",21}};
int i;
for (i=0; i<N; ++i)
{
printf("\nAmigo %s\t telefono %s\t edad %d",amigos[i].nombre,
amigos[i].telefono,amigos[i].edad);
}
printf("\n");
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-35-
#include <stdio.h>
#include <limits.h>
#include <float.h>
main()
{
char a;
short int b;
int c;
long int d;
unsigned char e;
unsigned short int f;
unsigned int g;
unsigned long int h;
float i;
double j;
long double k;
/* Saludo */
#include <stdio.h>
main()
{
char nombre[20];
printf("Hola, me llamo Ordenador, y tu?\n");
scanf("%s",&nombre[0]);
printf("Me alegro de conocerte %s\n",nombre);
}
#include <stdio.h>
void contestar (char []);
main()
{
char nombre[20];
printf("Hola, me llamo Iagoba, y tu?\n");
gets(nombre);
contestar(nombre);
}
void contestar(char *nombre)
{
printf("Me alegro de conocerte %s\n",nombre);
}
#include <stdio.h>
main()
{
float altura, base;
double area;
printf("\nBase del triangulo = ");
scanf("%f",&base);
printf("\nAltura del triangulo = ");
scanf("%f",&altura);
area= 0.5 * (double) altura * base;
printf("\nArea = %g\n",area);
}
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-37-
#include <stdio.h>
main()
{
int menor, numero1, numero2;
printf("\nEscriba el primer numero y pulso INTRO: ");
scanf("%d",&numero1);
printf("\nEscriba el segundo numero y pulso INTRO: ");
scanf("%d",&numero2);
if (numero1 < numero2) menor=numero1;
else menor=numero2;
main()
{
char ch;
int num_rep;
printf("\nEscriba el caracter a repetir: ");
scanf("%c",&ch);
printf("\nEscriba el numero de repeticiones: ");
scanf("%d",&num_rep);
while (num_rep>0)
{
printf("%c",ch);
--num_rep;
}
printf("\n");
}
10. Escriba un programa que imprima una tabla con las cuatro primeras potencias
de los números 1 a 10.
#include <stdio.h>
main()
{
int n;
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-38-
/* Factorial de un numero */
#include <stdio.h>
main()
{
int i, numero, factorial=1;
printf("\nEscriba un numero entero para calcular su factorial: ");
scanf("%d",&numero);
for (i=numero; i>1; --i) factorial *= i; printf("\n
%d! = %d\n",numero,factorial);
}
/* Sistema de temperaturas */
#include <stdio.h>
main()
{
int i;
float c;
for (i=0;i<=300;i+=20)
{
c=(5./9)*(i-32);
printf("%3d grados Farenheit equivalen a %4.4f grados Celsius\
n",i,c);
}
}
/* Tabla ASCII */
#include <stdio.h>
#define INI 33
#define FIL 15
#define COL 20
main()
{
int k, kk, i;
for (k=1; k<FIL; k++)
{
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-39-
14. Escriba un programa que dándole el importe exacto de una cantidad te indica
el mínimo número de monedas que podrías tener. Las monedas son de 1, 5, 10,
25, 50, 100, 200 y 500 pesetas.
#include <stdio.h>
#define LIM 8
int monedas[LIM]= {500, 200, 100, 50, 25, 10, 5, 1};
main()
{
int num, cantidad, numonedas;
printf ("Introduzca el importe exacto: ");
scanf ("%d", &cantidad);
printf ("El cambio optimo es el siguiente: \n");
for (num=0; num<LIM; num++)
{
numonedas=cantidad/monedas[num];
if (numonedas != 0) printf ("%d de %d.\n", numonedas, monedas[num]);
cantidad= cantidad % monedas[num];
}
}
15. Escriba un programa que ordene un vector (de dimensión máxima 15) por el
método de la burbuja.
#include <stdio.h>
#define LIM 15
main ()
{
16. Escriba un programa que compruebe la diferencia entre una variable global,
una variable local y un argumento de función.
#include <stdio.h>
int vglobal=100; /* Se ve en todo el fichero y debe ir con extern
dentro
de la declaracion en las funciones */
void suma1(int x);
void suma2(int x);
main()
{
extern int vglobal;
int vlocal=200;
printf("\nLa variable vglobal en main vale = %d\n", vglobal); printf("\
nLa variable vlocal en main vale = %d\n", vlocal); suma1(vlocal);
suma2(vlocal);
printf("\nLa variable vglobal despues de suma2 vale = %d\n",
vglobal);
printf("\nLa variable vlocal despues de suma2 vale = %d\n", vlocal);
}
void suma1(int x)
{
extern int vglobal;
++x;
++vglobal;
printf("\nLa variable vglobal dentro de suma1 vale = %d\n", vglobal);
printf("\nEl argumento (vlocal) dentro de suma1 vale = %d\n", x);
return;
}
void suma2(int x)
{
extern int vglobal;
++x;
++vglobal;
printf("\nLa variable vglobal dentro de suma2 vale = %d\n", vglobal);
printf("\nEl argumento (vlocal) dentro de suma2 vale = %d\n", x);
return;
}
17. Hacer el ejercicio de presentación (ejercicio 5) con una llamada a una función.
#include <stdio.h>
void contestar (char []);
main()
{
char nombre[20];
printf("Hola, me llamo Ordenador, y tu?\n");
scanf("%s",nombre);
contestar(nombre);
}
void contestar(char *nombre)
{
printf("Me alegro de conocerte %s\n",nombre);
}
#include <stdio.h>
#define CUAD(x) (x*x) /* Definicion de macros */
main()
{
float a;
printf("\nEscriba un numero: ");
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-42-
scanf("%f",&a);
printf("\nSu cuadrado es: %f\n",CUAD(a));
}
#include <stdio.h>
#define ANCHO 77
#define FILAS 4
void linea();
void lados();
main()
{
printf("\n\n\n\n");
linea();
lados();
printf(" *\t\t\t\t Bienvenido a C \t\t\t\t*\n");
lados();
linea(); printf("\n\n\n\
n");
}
void linea()
{
int x;
printf(" ");
for (x=0; x<=ANCHO; ++x) putchar('*');
putchar('\n');
}
void lados()
{
int y;
for (y=0; y<=FILAS; ++y) printf(" *\t\t\t\t\t\t\t\t\t\t*\n");
}
20. Escriba un programa que imprima una tabla con las áreas del círculo y de la
esfera para un radio en el rango de 0 hasta 2 en incrementos de 0.2.
#include <stdio.h>
#define MAX_RADIO 2.0
#define PI 3.141592
main()
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-43-
{
double radio;
puts("\n\t=== Tabla de Areas ===\n");
puts("\tRadio\tCirculo\tEsfera");
puts("\t-----\t-------\t----- - -");
for (radio=0.0; radio <= (double) MAX_RADIO; radio +=0.2)
printf("\t%6.2lf\t%6.3lf\t%6.3lf\n",radio,AreaCirculo(radio),AreaEsfer
a(radio));
}
21. Escriba un programa con una función que borre la pantalla emitiendo una
serie de caracteres de salto de línea.
/* Limpia Pantalla */
#include <stdio.h>
main()
{
int numlin=30;
LimpiaPantalla(numlin);
}
void LimpiaPantalla(int n)
{
while (n-- >0) putchar('\n');
}
#include <stdio.h>
main()
{
long potencia;
int b, e;
printf("\nEscriba una base entera para la operacion b= ");
scanf("%d",&b);
printf("\nEscriba un exponente entero para la operacion e= ");
scanf("%d",&e);
/* Forma iterativa */
potencia=poten_iter(b,e);
printf("\nEl resultado de la potencia en forma iterativa
=%ld\n",potencia);
/* Forma recursiva */
potencia=poten_recu(b,e);
printf("\nEl resultado de la potencia en forma recursiva
=%ld\n",potencia);
if (base==0) return(0);
if (expo==0) return(1);
/* Desarrollo de la recursividad */
p=base*poten_recu(base,expo-1);
return(p);
}
#include <stdio.h>
#define MIN(a,b) ((a < b) ? a : b)
#define MAX(a,b) ((a > b) ? a : b)
main()
{
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-45-
24. Escriba un programa que contenga dos arrays y utilizando punteros genere un
tercer array con la suma de los otros dos.
#include <stdio.h>
#define FILAS 4
#define COLS 5
main()
{
int j,k;
int arr1 [FILAS] [COLS] = { {13,15,17,19,21},
{20,22,24,26,28},
{31,33,35,37,39},
{40,42,44,46,48} };
int arr2 [FILAS] [COLS] = { {10,11,12,13,14},
{15,16,17,18,19},
{20,21,22,23,24},
{25,26,27,28,29} };
int arr3 [FILAS] [COLS];
for (j=0; j<FILAS; j++)
{
for (k=0; k<COLS; k++)
{
*(*(arr3+j)+k) = *(*(arr1+j)+k) + *(*(arr2+j)+k);
printf("%d ", *(*(arr3+j)+k));
}
printf("\n");
}
}
25. Escriba un programa que utilice una función para intercambiar dos valores.
Hacerlo para dos funciones, una con llamada por valor y otra por referencia.
#include <stdio.h>
main()
{
int val1=10, val2=20;
printf("Valores iniciales:\n\tval1 = %d; val2 = %d\n",val1,val2);
IntercambioValor(val1, val2);
printf("\nPaso de parametros por valor:\n\tval1 = %d; val2 =
%d\n",val1,val2);
IntercambioReferencia(&val1, &val2);
printf("\nPaso de Parametros por Referencia:\n\tval1 = %d; val2 =
%d\n",
val1,val2);
}
26. Escriba un programa que pida una cadena por el teclado y la imprima después
de convertir el primer carácter en mayúscula y el resto en minúsculas.
#include <stdio.h>
#include <ctype.h>
#define MAXCADENA 20
main()
{
char tmp[MAXCADENA+1]; /* Se suma 1 para el byte NUL */
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-47-
27. Escriba un programa que lea una cadena desde el teclado y cuente el número
de caracteres de tres categorías: letras (a-z y A-Z), dígitos (0-9) y otros
caracteres. Utilice las funciones isdigit() e isalpha() definidas en la librería
ctype.h.
#include <stdio.h>
#include <ctype.h>
#define MAXCAD 80
main()
{
char linea[MAXCAD], *pc=linea;
int digitos=0, letras=0, otros=0;
printf("\nEscriba una cadena (<%d caracteres):\n", MAXCAD);
gets(linea);
while (*pc != '\0')
{
if (isdigit(*pc)) ++digitos;
else if (isalpha(*pc)) ++letras;
else ++otros;
++pc;
}
printf("\n\tDigitos = %d\n\tLetras = %d\n\tOtros =
%d\n",digitos,letras,otros);
}
28. Escriba un programa que lea una cadena y busque un carácter en ella.
#include <stdio.h>
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-48-
#include <string.h>
main()
{
char caract, cadena[80], *ptr;
printf("Introduzca la cadena donde se va a buscar:\n");
gets(cadena);
printf("Escriba el caracter a buscar:\n");
caract=getchar();
ptr=strchr(cadena, caract);
if (ptr==0) printf("El caracter %c no se encuentra en la cadena.\
n",caract);
else printf("La posicion del caracter es %d.\n", ptr-cadena+1);
}
#include <stdio.h>
#include <string.h>
main()
{
char car, cadena[81];
int posicion;
printf("\nEscriba una cadena [Intro], caracter [Intro], posicion\n");
gets(cadena); scanf("%c\n
%d",&car,&posicion);
insertar(cadena,car,posicion);
puts(cadena);
}
#include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
FILE *origen, *destino;
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-49-
#include <stdio.h>
#define MAXVIA 64
#define MAXLINEA 256
main()
{
int car; /* caracter de entrada */
FILE *pf; /* puntero a fichero */
char via_acceso[MAXVIA]; /* buffer para el nombre del fichero */
char linea[MAXLINEA]; /* buffer de linea para fgets() */
printf("\nNombre de fichero: ");
gets(via_acceso);
if (*via_acceso == '\0') return; /* No se ha introducido ningun
nombre */
pf = fopen(via_acceso, "r");
if (pf == NULL)
{
printf("\nEL fichero no existe o la ruta no es valida.\n");
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-50-
return;
}
while (fgets(linea,MAXLINEA,pf) != NULL) fputs(linea,stdout);
fclose(pf);
}
CURSO BASICO DE PROGRAMACION EN C. Servicios Informáticos U. C. M.-51-
15 BIBLIOGRAFIA
DIGITAL 1994. DEC C. User’s Guide for OpenVMS Systems . Digital Equipment
Corporation.