Fundamentos de Programacion PDF
Fundamentos de Programacion PDF
Fundamentos de Programacion PDF
an0nymous
Fundamentos de Programación
No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Tema 1
Reseña histórica
- Corrección
- Precisión
- Repetitividad
- Finitud
Características esenciales
- Validez
- Eficiencia
Una sentencia es una parte del código fuente que el compilador puede traducir en una
instrucción en código binario. Van separadas por ;
Sentencias (2 tipos):
Palabras reservadas. Son tokens formados por caracteres alfabéticos con un significado
específico. Ej: main
Flujo de control: especificar el orden en el que se han de ejecutar las sentencias. (if, while, for)
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Tipos de errores
Tipos de datos
Literales: son la especificación de un valor concreto de un tipo de dato. Tenemos varios tipos:
Variable global: si se declara antes de main. Su ámbito incluye todas las funciones definidos
después. Permite que las funciones se puedan comunicar a través de ellas y no de los
parámetros. Esto es pernicioso para la programación estructurada, fomentando la aparición de
efectos laterales. Ejemplo de acoplamiento externo.
Cada variable debe estar asociado a un único tipo de dato (el tipo no puede cambiarse durante
la ejecución). El valor que se le puede asignar a una variable depende del tipo de dato con el
que es declarado.
Cuando se declara una variable y no se inicializa, ésta no tiene ningún valor asignado por
defecto. Puesto que desconocemos su valor, lo podremos considerar como basura, y lo
representaremos gráficamente por ?.
Variables a las que solo le permitimos tomar un único valor, fijado de antemano. Es posible
con constantes
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Datos: variables (datos que varían a lo largo del programa) y constantes (no varían).
Lo usual es que un int ocupe la longitud de la palabra del segmento de datos del sistema
operativo. Hoy en día, lo usual es 32 bits (4 bytes) y 64 bits (8 bytes).
¿Qué tipo de dato se usa para representar un literal entero? Depende de la memoria
reservada y los tipos disponibles por cada compilador
++ y –
Incrementan y decrementan,
respectivamente, el valor de la variable
entera sobre la que se aplican (no pueden
aplicarse sobre una expresión).
Reglas de precedencia
Forma de representar números reales: coma flotante. En esta representación la parte entera
se expresa en binario y la parte real se representa usando potencias inversas de 2. Usando este
método NO es posible representar de forma exacta muchos reales. La regla a usar es que, con
32 bits, se consigue una precisión aproximada de 7 dígitos y con 64 bits, se consiguen
aproximadamente 16 dígitos para la parte entera
Los tipos enteros representan datos enteros de forma exacta. B Los tipos reales representan la
parte entera de forma exacta, siempre que trabajemos con menos de 16 dígitos (en una
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
representación con 64 bits) La parte real será sólo aproximada. Además, la aproximación será
mejor cuanto menor sea la parte entera del número.
¿Qué pasa cuando asignamos un real a un entero? Simplemente, se pierde la parte decimal, es
decir, se trunca
Literales de carácter
Toupper(‘a’)->A
Isalpha: función que devuelve true (1) si todos los caracteres de un string son alfabetos.
Isalnum: función que devuelve true (1) si el carácter es alfanumérico, es decir si isalpha e
isdigit también devuelven true. Erguj8t4t34t
Reglas de precedencia
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Tema 2. Estructuras de control
Una estructura condicional es una estructura que permite una ejecución condicional. Existen
tres tipos: Simple, Doble y Múltiple. Una ejecución condicional consiste en la ejecución de una
Si hay varias sentencias, es necesario encerrarlas entre llaves. Dicho de otra forma: si no
ponemos llaves, el compilador entiende que la única sentencia del bloque if es la que hay justo
debajo.
Álgebra de Boole
Leyes de Morgan
Tipo bool como tipo entero. En C, no hay el tipo lógico booleano se hace con un tipo entero.
Cualquier expresión entera que devuelva el cero, se interpretará como false. Si devuelve
cualquier valor distinto de cero, se interpretará como true.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Siempre es true
if ( (a>0) && (b(<0) && (c<1) ) si a = -3, n ciclo largo se evaluará toda la expresión y en ciclo
corto sólo la primera, sabiendo ya que es false. La mayoría de compiladores usan ciclo corto.
Por lo tanto, pondremos primero aquellas condiciones que sean más probables de evaluarse
como false Nota. La misma idea pasa cuando el operador es || pero se ponen primero aquellas
condiciones que sean más probable evaluarse como true.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
La expresión 1.0 == (1.0/3.0)*3.0 podría evaluarse a false
debido a la precisión finita para calcular (1.0/3.0)
(0.333333333).
Switch
Break;
Pre-test
Post-tes
lectura anticipada. Leemos el primer valor con scanf antes de entrar al bucle y comprobamos si
hay que procesarlo (el primer valor podría ser ya el
terminador!)
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Bucles for. Se utilizan para repetir un conjunto de sentencias un número de veces fijado de
antemano. Se necesita una variable contadora, un valor inicial, un valor final y un incremento.
Cuando termina un bucle for, la variable contadora se queda con el primer valor que hace que
la condición del bucle sea falsa
Iteraciones en un for Si incremento = 1, Vinic es menor que Vfinal y la condición es v_c <=
Vfinal
Vfinal - Vinic + 1
- Si incremento = 1, Vinic es menor que Vfinal y la condición es v_c < Vfinal
Vfinal – Vinic
Iteraciones e intervalos
No se debe modificar el valor de la variable controladora, ni el valor final dentro del cuerpo del
bucle.
¿Puede usarse entonces, cualquier condición dentro de la cabecera del for? Sí, pero no es muy
recomendable.
¿podemos suprimir algunas expresiones de la cabecera de un bucle for? La respuesta es que sí,
pero hay que evitarlas SIEMPRE. Oscurecen el código. Pg 97 tema 2
Anidamiento bucles. No hay límite. Deben estar inscritos unos dentro de otros.
Otras estructuras de control: goto / continue / break / exit (no usar, excepto break)
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Tema 3
No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Funciones. Objetivo: descomponer la
resolución de un problema en tareas
menos complejas. Cada tarea será
resuelta por un algoritmo, y éste
vendrá encapsulado en una función.
Los parámetros formales son aquellos especificados en la cabecera de la función. Hay que
especificar su tipo de dato. Sólo se conocen dentro de la función.
Flujo de control. Cuando se llama a la función, el parámetro formal recibe la asignación del
parámetro actual. Esto es Paso por valor. Cuando se ejecuta toda la función devuelve return
<expresión> al sitio en el que fue la llamada. La llamada a una función es una expresión.
- Reutilización
- Código menos propenso a errores
- Actualización
- Abstracción
Scope o ámbito de un dato v es el conjunto de todas las funciones que pueden referenciar a v.
Pila. Entorno que se crea en una zona de memoria específica cada vez que se llama a una
función. Las modificaciones en el parámetro formal no afectan al actual (si lo hiciese: paso por
referencia)
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Funciones void. Resuelve la tarea de realizar la presentación del programa por pantalla, pero
no calcula (devuelve) ningún valor. Su llamada constituye una sentencia, no una expresión. No
hay sentencia return.
Las constantes, literales y expresiones no pueden ser parámetros actuales pasados por
referencia. Deben pasarse por valor. Pasamos por referencia los datos que vamos a modificar.
Pero obviamente, si tienen algún valor previamente establecido, podemos acceder a él.
Resumen:
- Los parámetros por valor son datos que necesita conocer una función (son entradas).
- Los para. por referencia corresponden a datos modificados por la función, son salidas.
También pueden ser datos de entrada o salida si la función utiliza ese parámetro.
Una función de cálculo nunca debe imprimir mensajes. Se hace en la función que la llama.
¡! Una función void puede incluir una sentencia return; (sin expresión), para salir de la
ejecución de la función en ese momento.
Orden construir funciones (pg 102, 3). Diseño descendente / modular (pg 112) / Integración
ascendente
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Tema 4
Leer vector: leer útil del vector antes de llamar a la función void. Se utilizará un bucle.
Útil: Número de componentes usadas. Resto son 0. Índices componentes usadas (0, útil-1)
Inicializar vector
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Búsqueda secuencial: (precondición: útil de v de estar en el rango correcto)
Ordenación interna: Todos los datos están en memoria principal durante el proceso de
ordenación. (Inserción / Selección / Intercambio directo o burbuja)
Ordenación externa: Parte de los datos a ordenar están en memoria externa mientras que otra
parte está en memoria principal siendo ordenada
Ordenación por selección: En cada iteración, se selecciona la componente más pequeña del
sub-vector derecha y se coloca al final del sub-vector izquierdo.
Ordenación por intercambio directo (burbuja): Al igual que antes, a la izquierda se va dejando
un subvector ordenado. Desde el final y hacia atrás, se van comparando elementos dos a dos y
se deja a la izquierda el más pequeño (hay que intercambiarlos).
Cadenas de caracteres
Al declarar un string, podemos darle un valor inicial como cualquier otro vector
Biblioteca string:
con un vector de char sí podemos usar printf, con uno noma, no.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Lectura char con scanf: Si la cadena que se desea introducir contiene, la variable contendrá los
No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
caracteres hasta el primer separador. Se soluciona con fgets.
MATRICES
Declaración
Todas las posiciones de una matriz están realmente contiguas en memoria. Sea m una matriz,
m contiene la dirección de memoria de la primera componente. Para saber dónde está m[i][j],
el compilador necesita saber cuánto vale DIM_COL_m, pero no DIM_FIL_m.
Al pasar una matriz como parámetro, debemos incluir la constante de dimensión de las
columnas. Además, esta ha de ser un define o un literal y se copiará la dirección de memoria
que contiene la matriz pasada como parámetro actual.
TEMA 5
Los vectores almacenan de forma compacta información del mismo tipo sobre una misma
entidad. Los registros (struct) almacenan de forma compacta información de distinto tipo
sobre una misma entidad.
- Dentro de una función. Sólo puede ser usado dentro de la función (poco usual)
- Al principio del fichero. Será accesible por todas las funciones definidas con posterioridad
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Las variables de tipo struct pueden definirse en los mismos
sitios que cualquier otra variable.
Variable: un_alumno
A un vector no se le puede asignar otro vector, a un struct sí se le puede asignar otro struct,
copiándose todos los valores de todos los campos. Curiosamente, si el struct contiene un
vector, se asignan todas las componentes una a una (recordad que los vectores, tal cual, no
podían asignarse entre sí).
Es posible pasar un struct completo como parámetro a una función, puede hacerse por valor o
por referencia.
- Paso por valor struct: se realiza una copia del parámetro actual en el parámetro formal
La modificación del parámetro formal no altera el actual, igual que con los campos.
Duplica la memoria en pilasol: paso por referencia constante
Una función también puede devolver un struct. Declaramos una variable local tipo struct y al
final ejecutamos un return.
- Paso por referencia. El parámetro formal va ligado al actual. Si pasamos por referencia
un struct, las modificaciones de los campos del formal, serán modificaciones de los
campos del actual.
- Paso por referencia constante. Se puede modificar el puntero, pero no el objeto al que
apunta.
Si vamos a crear una función que acceda a las componentes del struct, pasaremos todo el
struct y no las componentes individualmente.
Tema 6
Declaración
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Al evaluar *ptr, el compilador accede a tantos bytes como indique <tipo base>, a partir de la
dirección de memoria contenida en ptr.
Como * es una variable corriente, podemos hacerle lo que queramos, como por ejemplo
pasarla por valor o por referencia.
Imprimiría basura
Operador flecha. (->) Obtiene el campo de una struct apuntada por un puntero
Asignación entre dos structs copia campo a campo, por tanto, si el campo es un puntero se
copiará la dirección de memoria que contiene.
Puntero NULL (0): es un valor de un puntero (dirección de memoria) especial sobre el que
tenemos la certeza de que no es la dirección reservada para ninguna variable.
Cuando pasamos un puntero por valor, estamos pasando una copia del contenido del puntero
(dir. memoria)
Las modificaciones del puntero que hagamos dentro de una función (el parámetro formal), no
afectan al puntero pasado como parámetro actual (como cualquier otro paso por valor
puntero)
Paso por referencia puntero: Además de poder modificar la variable apuntada por el puntero
(como en el paso por valor), también podemos modificar el puntero que pasen como
parámetro actual.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Podemos pasar un vector fijo cómo parámetro a un puntero y pasar como parámetro actual un
puntero cualquiera no constante.
La reserva dinámica de memoria con malloc, NO se realiza en la pila sino en otra zona llamada
Heap.
Todas las variables locales a una función se almacenan en la pila y se pierden al terminar la
función. Esto también ocurre con un puntero local. La memoria que reservemos al ejecutar
malloc sobre un puntero, permanece en el Heap cuando termine de ejecutarse la función
Para crear un vector dinámico tendremos que usar malloc e indicar el nº de componentes. Una
vez usadas las posiciones se destruyen con free.
¿Cómo se pasa como parámetro un vector dinámico? Basta con pasar el puntero a la primera
posición. Es lo mismo que ocurría con los vectores fijos.
Para construir un vector dinámico dentro de una función, hacemos el malloc dentro de la
función y devolvemos la dirección de memoria devuelta por malloc
Intentad construir funciones que eviten hacer copias locales de vectores, ya que pueden ser
muy grandes y desbordarse la memoria.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
Estructura de datos para designar un tipo definido por nosotros, que nos permita representar
No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
(almacenar) y manejar (operar) información relativa a una entidad.
Listas enlazadas. Crear una estructura de datos que me permita ir reservando dinámicamente
componentes, aumentando o disminuyendo el número de estas, de una forma eficiente.
Para añadir un nodo, debemos crearlo y engancharlo con el nodo anterior. Para ello, es
necesario modificar el campo next del último nodo.
El puntero inicio solo se modifica cuando se crea el primer nodo. La creación del resto de los
nodos dentro del bucle, no cambia el valor del puntero inicio.
Recorrido de una lista. Una vez creada una lista enlazada, la recorreremos con un puntero
(actual) que vaya apuntando a los distintos nodos, hasta llegar al último (NULL).
Si una función necesita acceder a los nodos de una lista enlazada, usualmente le pasaremos un
puntero al primer nodo (inicio).
Si una función necesita determinar que nodo cumple una propiedad determinada, devolverá
un puntero a dicho nodo.
¿Puedo empezar a borrar desde el último hacia atrás? No, ya que el problema es que un nodo
no guarda como información la dirección del nodo anterior.
¿Qué hacemos entonces para liberar una lista? Antes de borrar el nodo actual debemos
guardar la dirección del siguiente nodo en un puntero auxiliar.
Lista doblemente enlazada: lista donde en cada nodo tenemos un enlace al nodo siguiente y
otro al anterior.
Añadir nodo a una lista enlazada: recorremos la lista para buscar el final y añadir ahí. Usamos
un puntero último apuntando al último nodo y así añadir sin tener que recorrer la lista.
Siempre consideramos primero si es viable añadir por el principio, pues es más fácil.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
EXAMEN FP 2020 SOLUCIONES
1. Sobre la cohesión de una función: cuantas menos tareas haga una función mayor será
la cohesión (b)
2. Si hacemos int v[3]={1,2} v[0]=1, v[1]=2, v[3]=0 (b)
3.
4. Sobre los struct se pasan por referencia o por valor según decida el programador
5. ¿Qué almacena una variable tipo puntero? Todas son correctas (a)
o La dirección de memoria donde hay un dato
o La dirección de memoria donde comienza a almacenarse una variable
o Un número entero habitualmente de 32 o 64 bits que representa una
dirección de memoria.
6. En qué condiciones el tamaño en bits que ocupa un entero será mayor que el tamaño
en bits que ocupa un float. Nunca, el tamaño que ocupa un entero puede ser mayor
que el que ocupa un float. (d)
7.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963
11. Si el ++ está después de la
variable, primero evalúa la
condición y después
incrementa, si está delante
de la variable, primero
incrementa y luego evalúa.
12. ¿Cómo podemos calcular lo
que hay que sumar a un
carácter en mayúsculas para
obtener el correspondiente
carácter en minúsculas?
Distancia = ’z’-’Z’ (a)
13. Sobre las variables globales: son la principal fuente de efectos colaterales en un
programa. (d)
14. Cuando leemos un vector de entrada debemos: leer el útil del vector en el programa
principal y las componentes del vector en una función. (a)
15. En el paso por referencia ninguna de las respuestas es correcta (c) Las constantes,
literales y expresiones no pueden ser parámetros actuales pasados por referencia.
Deben pasarse por valor. El parámetro actual NO se copia sobre el parámetro formal.
16. (d) Hay un ; después del for
17. El operador ->: obtiene el campo de una struct apuntada por un puntero. (a)
18. Infinitas iteraciones. Ninguna de las anteriores es correcta (d)
19. (b)
20. (d)Todas son correctas. Añadir nodo a una lista enlazada: recorremos la lista para
buscar el final y añadir ahí. Usamos un puntero último apuntando al último nodo y así
añadir sin tener que recorrer la lista. Siempre consideramos primero si es viable añadir
por el principio, pues es más fácil.
21. sobre el anidamiento con estructuras condicionales: se puede anidar cuantas veces se
desee (a)
22. (c)
23. Sobre el paso por referencia: si modificamos el parámetro formal se modifica el
parámetro actual (b)
24. ¿Cómo pasaríamos un vector por valor a una función? De ninguna forma, los vectores
no se pueden pasar por valor.
25.
Primero asigna,
después evalúa.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-3752963