Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Curso básico programación en C, Apuntes de Ingeniería de Telecomunicaciones

Asignatura: Programació, Profesor: , Carrera: Enginyeria de Sistemes de Telecomunicació, Universidad: UPC

Tipo: Apuntes

2013/2014

Subido el 16/10/2014

konoth
konoth 🇪🇸

2 documentos

1 / 52

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
CURSO BASICO DE PROGRAMACION EN C
Apoyo a Investigación C. P. D.
Servicios Informáticos U. C. M.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34

Vista previa parcial del texto

¡Descarga Curso básico programación en C y más Apuntes en PDF de Ingeniería de Telecomunicaciones solo en Docsity!

CURSO BASICO DE PROGRAMACION EN C

Apoyo a Investigación C. P. D. Servicios Informáticos U. C. M.

1 INDICE

2 INTRODUCCION

El lenguaje C fue inventado e implementado por primera vez por Dennis Ritchie en un DEC PDP-11 en Bell Laboratories.

Es el resultado de un proceso de desarrollo comenzado con un lenguaje anterior denominado B, inventado por Ken Thompson. En los años 70 el lenguaje B llevó al desarrollo del C. En 1978, Brian Kernighan y Dennis Ritchie publicaron el libro The C Programming Language que ha servido hasta la actualidad como definición eficiente de este lenguaje.

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.

El lenguaje C se denomina como un lenguaje de nivel medio, puesto que combina elementos de lenguajes de alto nivel (Fortran, Pascal, Basic…) con el funcionalismo del lenguaje ensamblador.

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:

auto break case char const continue default do

double else enum extern float for goto if

int long register return short signed sizeof static

struct switch typedef union unsigned void volatile while

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.

La forma general de un programa en C es:

instrucciones del preprocesador declaraciones globales tipo_devuelto main(lista de parámetros) { secuencia de sentencias }

tipo_devuelto función_1(lista de parámetros) { secuencia de sentencias } tipo_devuelto función_2(lista de parámetros) { secuencia de sentencias }

…..

….. 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.

El proceso de compilar consiste en traducir el programa fuente a código o lenguaje máquina.

El proceso de linkaje (enlazado) consiste en añadir rutinas (propias o bibliotecas existentes en el mercado) que también están en código máquina, es decir, están en objeto.

Una vez enlazado el programa objeto, tenemos un programa ejecutable que se puede ejecutar en el ordenador.

Estos procesos son realizados por un programa llamado compilador.

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

para crear, si no hay errores, un ejecutable (a.out). Existen múltiples opciones en el compilador que se pueden comprobar con el comando de ayuda de los sistemas operativos.

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.

  • Caracteres: Su forma es ‘carácter’ (carácter entre apostrofos). El carácter puede ser escribible (es imprimible desde teclado) o de escape en los que hay que poner un carácter especial () para avisar al compilador. Todos los caracteres escribibles se pueden poner en forma de escape con el código octal correspondiente (‘a’ es igual a ‘\141’). El carácter nulo (NULL) se puede representar como ‘\0’. Este carácter es puesto siempre por el compilador al final de cualquiera cadena de caracteres.
  • Cadenas de caracteres: Es una secuencia de caracteres (escribibles o de escape) encerrada entre dobles comillas.

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.

En C existen seis tipos de operadores. Aritméticos, relacionales, de asignación, lógico, de dirección y de movimiento.

3.6 Sentencias

Una sentencia es una expresión en C donde se esperan unas consecuencias, normalmente son asignaciones, operaciones, llamadas a funciones, etc.

3.7 Macros del preprocesador

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.

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.

Tipo Tamaño en bits Rango char 8 -127 a 127

unsigned char 8 0 a 255 signed char 8 -127 a 127 int 16 -32767 a 32767 unsigned int 16 0 a 65535 signed int 16 -32767 a 32767 short int 16 -32767 a 32767 unsigned short int 16 0 a 65535 signed short int 16 -32767 a 32767 long int 32 -2147483647 a 2147483647 signed long int 32 -2147483647 a 2147483647 unsigned long int 32 0 a 4294967295 float 32 seis dígitos de precisión double 64 diez dígitos de precisión long double 64 diez dígitos de precisión Nota: En el capítulo 3 del manual del compilador DEC C existe una tabla con sus tamaños y rangos.

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:

enum identificador {lista de nombres};

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:

5 DECLARACIONES

La declaración de objetos en C tiene como finalidad dar a conocer el tipo y propiedades de los identificadores.

En general la forma de una declaración es:

(durabilidad) tipo identificador (=expresión de inicialización);

Por ejemplo , static int n=10;.

Todos las variables deben ser declaradas. En las declaraciones es obligado especificar el tipo.

De cada objeto en un programa C se puede establecer tres propiedades que le afectan en su relación: el alcance, la visibilidad y la durabilidad.

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.

Si la declaración es realizada en un bloque de código entre llaves, el alcance es la región que va entre las llaves. Si se declara en la parte de arriba del fichero (normalmente) o en una parte que no va entre llaves, el alcance se establece en todo el fichero. Los identificadores establecidos con la sentencia # define tienen alcance durante todo el fichero o hasta que lo elimina la sentencia # undef. Las etiquetas de sentencia (ver capítulo 7) tienen como alcance el cuerpo de la función donde se han establecido.

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

La durabilidad es el tiempo de ejecución del programa donde el objeto existe en la memoria. La durabilidad puede ser:

  • Estática: El objeto perdura desde la compilación hasta el final. Esta durabilidad la tienen todas las funciones declaradas, las variables no declaradas en ningún cuerpo de función (incluido main ) y las variables declaradas con static.
  • Local: El objeto es creado en la entrada de un bloque y es borrado a la salida. Esta durabilidad la tienen los argumentos formales y las variables declaradas con auto

(es la declaración por defecto y no se suele poner). Las variables declaradas en un bloque son (a menos que se especifique) variables locales.

Existen otros dos tipos de durabilidad:

extern : Los objetos especificados tienen durabilidad static e informa al enlazador de programas para que realice las unificaciones pertinentes entre ficheros. Es decir, convierten su alcance al total del programa. La declaración del mismo objeto en otros ficheros se toma como referencia y debe tener obligatoriamente el especificador extern. Si se pone un valor de inicialización, se debe inicializar en la declaración de la variable que no lleva extern.

Register : Se puede utilizar para variables locales y argumentos de funciones. Establece una durabilidad local pero informa de un uso intensivo de memoria, haciendo que el compilador le asocie un acceso de memoria rápido.

6.4 Operadores de asignación

OPERADORES DE ASIGNACION

OPERADOR SENTENCIA

ABREVIADA

SENTENCIA NO

ABREVIADA

++ m++ m=m+ -- m-- m=m- += 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

Los operadores de asignación ++ y – pueden ir antes o delante de una expresión formando una nueva expresión. Estas expresiones se denominan post-incrementos o pre-incrementos (decrementos si el operador es --) y son expresiones compuestas, normalmente son del tipo y=x++; ( y=++x; ).

Existen una diferencia entre el post-incremento y el pre-incremento. El post-incremento primero suma uno a la variable (x en el ejemplo) y luego asigna ese valor (y en el ejemplo), mientras con el pre-incremento, la asignación es anterior.

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 */

6.5 Operadores de dirección

OPERADORES DE DIRECCION

OPERADOR SIGNIFICADO

  • Operador de contenido de apuntado u operador de indirección & Operador de dirección

6.6 Operadores de movimiento

Existe un último tipo de operadores, no comentado hasta el momento, los operadores de movimiento (<<, movimiento a la izquierda y >>, a la derecha). Su función es desplazar los bits de la palabra de memoria dada tantos espacios como se le indiquen a derecha o izquierda. La forma general es:

expresion1 << expresion

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).

Por ejemplo, sea x un entero con representación interna: 00010001110011000101010111111111 x<<4; da como resultado: 00011100110001010101111111110000

6.7 Prioridad y asociatividad de los operadores

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

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.

Un if anidado es un if que es el objeto de otro if o else. Son muy comunes en la programación. Un sentencia else siempre se refiere al if más próximo que esté en el mismo bloque que el else y que no esté asociado con un if. Por ejemplo:

if(i) { if(j) sentencia 1; if(k) sentencia 2; /* este if esta / else sentencia 3; / asociado con este else */ }

El estándar ANSI específica que al menos se deben permitir 15 niveles de anidamiento. En la práctica, la mayoría de los compiladores permiten bastantes más.

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 ;

la_?_ es un operador ternario, ya que necesita tres operandos y tiene la forma general:

Condición? Expresión1 : Expresión2;

Donde Condición , Expresión1 y Expresión2 son expresiones. El valor de una expresión con_?_ se determina de esta forma, se evalúa Condición , si es cierta se evalúa Expresión y se convierte en el valor de la expresión completa. Si Condición es falsa, se evalúa Expresión2 y su valor se convierte en el valor de la expresión completa. Por ejemplo:

x = 10; y = x >9? 100 : 200;

En el ejemplo a “ y ” se le esta asignando el valor 100.

SWITCH

Es una sentencia de selección múltiple, que compara sucesivamente el valor de una expresión con una lista de constantes enteras o de caracteres. Cuando se encuentra una

correspondencia, se ejecutan las sentencias asociadas con la constante. La forma general es:

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.

La sentencia switch se diferencia de la sentencia if en que sólo puede comparar la igualdad, mientras que if puede evaluar expresiones relacionales o lógicas.

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).

Si se utilizan constantes de tipo carácter en la sentencia switch , se convierten automáticamente a sus valores enteros.

7.4 Sentencias de iteración

También denominadas bucles. Permiten realizar un conjunto de instrucciones hasta que se alcance una cierta condición (que puede estar predefinida como en el bucle for ; o no haber final predeterminado, como en los bucles while y do-while ).

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()

Igual que se puede interrumpir un bucle, se puede salir anticipadamente de un programa usando la función exit() de la biblioteca estándar. Esta función da lugar a la terminación inmediata del programa, forzando la vuelta al sistema operativo. La forma general de la función exit() es:

void exit (int código_de_vuelta);

El valor de código_de_vuelta es el que se devuelve al proceso de llamada, que normalmente es el sistema operativo. Generalmente se usa un cero como código de vuelta para indicar que se trata de una terminación normal del programa. Se utiliza otros argumentos para indicar algún tipo de error.

CONTINUE

Funciona de forma similar a break. Sin embargo, en vez de forzar la terminación, continue fuerza una nueva iteración del bucle y salta cualquier código que exista entremedias. Para el bucle for , continue hace que se ejecuten las partes de prueba condicional y de incremento del bucle. Para los bucles while y do-while , el control del programa pasa a la prueba condicional.

8 FUNCIONES

Las funciones son los bloques constructores de C y el lugar donde se da toda la actividad del programa.

8.1 Definición

La forma general de definición de una función es:

tipo nombre(lista de parámetros) { cuerpo de la función }

El tipo especifica el tipo de valor que devuelve la sentencia return de la función. El valor puede ser cualquier tipo válido; si no se especifica ninguno, se asume un resultado entero.

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

Cada función debe ser declarada. Su forma general es:

tipo nombre_función (lista de tipos (y nombres) de los argumentos);

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.