Bloque 1 - Conceptos Básicos
Algoritmos, lenguajes de programación, programas y sus elementos, tipos de datos y operadores, entrada y salida (printf / scanf), conceptos básicos de macros e introducción a los punteros.
La programación busca resolver problemas mediante la construcción de programas ejecutables en un computador.
Programa
- Conjunto unitario de instrucciones que permite a una computadora realizar funciones diversas, como el tratamiento de textos, el diseño de gráficos, la resolución de problemas matemáticos, el manejo de bancos de datos, etc.
- Codificación en cualquier lenguaje de programación específico de uno o varios algoritmos.
Computador
Máquina electrónica que, mediante determinados programas, permite almacenar y tratar información, y resolver problemas de diversa índole.
Los lenguajes de programación están diseñados de forma que sólo se requiere que los programadores indiquen sus intenciones explícitamente.
Algoritmos
Conjunto ordenado y finito de operaciones que permite hallar la solución de un problema.
Condiciones necesarias:
- Finitud.
- No ambigüedad.
Propiedades deseables:
- Generalidad.
- Eficiencia.
- Independencia del medio de ejecución.
Representación de algoritmos
- Lenguaje natural.
- Pseudocódigo.
- Diagramas de flujo u ordinogramas.
- Diagramas N-S (Nassi-Schneiderman).
- Métodos formales matemáticos.
Diagramas de flujo u ordinogramas
Un diagrama de flujo es la representación gráfica de un algoritmo o proceso.
Forma | Nombre | Forma | Descripción |
---|---|---|---|
Línea de flujo | Flecha | Línea saliendo de un símbolo y apuntando a otro. | |
Terminal | Óvalo | Inicio o fin de un programa o subprocesos. | |
Proceso | Rectángulo | Conjunto de operaciones que cambian el valor, forma o ubicación de datos. | |
Decisión | Rombo | Muestra una operación condicional que determina cuál de los dos caminos tomará el programa. La operación es comúnmente una pregunta de sí/no o una prueba de verdadero/falso. | |
Entrada | Paralelogramo | Proceso de hacer entrar datos en la forma de ingresar datos. | |
Salida | Hoja de papel impresa | Proceso de hacer salir datos, en la forma de mostrar resultados. |
Pseudocódigo
Descripción de alto nivel compacta e informal del principio operativo de un programa informático u otro algoritmo.
Utiliza las convenciones estructurales de un lenguaje de programación real, pero está diseñado para la lectura humana en lugar de la lectura mediante máquina, y con independencia de cualquier otro lenguaje de programación.
Lenguajes de programación
Tipos de lenguajes de programación
Generaciones de los lenguajes de programación
- Primera generación: Lenguaje máquina.
- Segunda generación: Lenguajes de ensamblador.
- Tercera generación: Lenguajes de alto nivel.
- Lenguajes compilados.
- Lenguajes interpretados.
- Lenguajes híbridos.
Lenguajes compilados y lenguajes interpretados
Ejecución de un programa compilado:
- Se realiza previamente la compilación del programa fuente en la versión equivalente del programa en lenguaje
máquina.
- Esta versión se conoce como programa objeto.
- El programa objeto se une, eventualmente, con los subprogramas de biblioteca descritos en el programa fuente
para obtener el programa ejecutable.
- Esto lo realiza el montador de enlaces (linker).
- Se inica el programa ejecutable.
Ejecución de un programa interpretado:
- Se iteran los siguientes pasos:
- Obtención de la siguiente instrucción a ejecutar del código fuente.
- Análisis de la instrucción y determinación de las acciones a ejecutar.
- Ejecución de las correspondientes acciones.
Propiedades deseables de los lenguajes de programación
- Claridad.
- Buena definición.
- Independencia de la máquina.
- Notación estándar.
- Niveles de abstracción.
- Control de errores.
- Verificación de programas.
Paradigmas de programación
- Imperativa.
C
,Pascal
,Cobol
,Fortran
…
- Orientada a Objetos.
Java
,C++
,C#
,.NET
…
- Funcional.
LISP
,Scheme
,ML
…
- Lógica o declarativa
PROLOG
…
- Concurrente.
- Tiempo real.
Instrucciones
- Asignación: Evaluar una expresión y almacenar el resultado en una variable.
a = b + c
.
- Entrada / Salida: Transferencia de información con el exterior a través de dispositivos de entrada (teclado,
ficheros, etc.) y salida (monitor, impresora, etc.).
printf
,scanf
…
- Control de flujo:
- Condiciones:
if
,if-else
,switch
… - Bucles:
while
,do-while
,for
…
- Condiciones:
- Llamada y retorno de subrutinas: Dividir el programa en pequeñas unidades que se ejecutarán cuando convenga.
Elementos
- Alfabeto: conjunto de símbolos válidos para construir textos en el lenguaje.
- Palabras clave:
if
,else
,while
… - Caracteres:
a
…z
,A
…Z
,#
,?
… - Dígitos:
0
…9
. - Otros símbolos:
.
,,
,'
,;
,()
,{}
…
- Palabras clave:
- Léxico: vocabulario formado a partir del alfabeto.
- Sintaxis: conjunto de reglas gramaticales que permiten derivar frases correctas en el lenguaje.
- Notaciones para expresar las reglas:
- Backus-Naur.
- Grafo Sintáctico.
- Notaciones para expresar las reglas:
- Semántica: conjunto de reglas que permiten derivar frases con sentido o significado en el lenguaje.
Notación BNF
Creada por J. Backus y P. Naur para describir la sintaxis del lenguaje ALGOL 60.
Para describir el lenguaje se utilizan reglas que se construyen con tres tipos de símbolos:
- Metasímbolos: propios de la notación BNF.
- Símbolos terminales: se usan en el texto del programa tal y como aparecen en la regla (sin comillas).
- Símbolos no terminales: resto de símbolos. Se definen utilizando combinaciones de símbolos terminales, no terminales y metasímbolos
Metasímbolo | Significado |
---|---|
::= | Se define como |
| | Opción alternativa |
(a | b) | a ó b pero no ambos |
[palabra] | 0 ó 1 vez palabra |
{palabra} | 0 ó más veces palabra |
'xyz' | Símbolo terminal |
. | Final de la regla |
Definición de un dígito con 10 reglas:
Definición de un dígito con una única regla:
Definición de un número entero:
Definición de un identificador:
Diagramas de Conway
Herramienta gráfica para describir la sintaxis de un lenguaje.
Se utilizan también símbolos terminales y no terminales:
- Símbolos terminales: se representan por un círculo o rectángulo redondeado.
- Símbolos no terminales: se representan mediante un rectángulo.
Ambos símbolos se enlazan con flechas que indican el orden en que se debe realizar la interpretación de los diagramas.
Programas
Tipos de programas
- Programas de aplicación.
- Editores.
- Compiladores.
- Traductores.
- Montadores de enlace (linkers).
- Sistemas operativos.
- Programas de servicio.
Sistema Operativo
Conjunto de programas que tienen como objetivo:
- Facilitar la utilización del computador:
- Acceso a los usuarios autorizados.
- Edición de ficheros de texto.
- Configuración y ejecución de programas.
- Seguridad y protección
- Gestión óptima de la máquina:
- Gestión de memoria.
- Control de dispositivos periféricos.
- Acceso a ficheros.
- Asignación de recursos y ordenación de tareas.
Elementos de un programa
Un programa se crea utilizando un alfabeto de símbolos (léxico) para construir:
- Identificadores.
- Etiquetas.
- Directivas remotas, de interface y de implementación.
- Constantes.
- Números sin signo, números reales…
- Cadenas de caracteres (strings) y variables.
Símbolos predefinidos
Símbolos predefinidos: conjunto de símbolos que constituyen el alfabeto del lenguaje.
En el caso de varios lenguajes de programación es el juego de caracteres ASCII.
Tabla ASCII de 7 bits:
- Cada símbolo una posición.
- Un número entero asociado a cada carácter.
- Los códigos 0-31 y 127 no son imprimibles.
- La diferencia entre el código ASCII de una letra mayúscula y su correspondiente minúscula es de 32.
Símbolos especiales
Símbolos especiales: símbolos con un significado especial dentro del lenguaje que se usan para representar delimitadores, operadores y otros elementos sintácticos.
Palabras reservadas
Palabras reservadas (keywords) se utilizan para especificar nombres de instrucciones, funciones de librería, tipos de datos, operadores, etc.
- No se pueden redefinir para usarlas como identificadores.
* palabras reservadas a partir del compilador
C99
.
Identificadores
Identificadores: son nombres que pueden utilizarse para denominar una función, una constante, una variable, un tipo, una función, una interfaz…
El nombre debe ser apropiado y tener un significado adecuado al uso destinado para el identificador.
Constantes
Constantes: identificadores que se corresponden a un valor constante que no varía durante la ejecución del programa.
Variables
Variables: identificadores que se corresponden a valores que pueden cambiar durante la ejecución de un programa, permaneciendo dentro del rango establecido para su tipo.
Cuando se declara una variable:
- Se presenta el identificador, antes no existía.
- Se reserva la memoria necesaria para el tipo de datos de la variable.
- Se asocia el identificador con la dirección de memoria donde comienza.
- Se asocia el identificador con una cierta interpretación de memoria.
No adoptan valores hasta que el programa se los asigna, por ello es fundamental inicializarlas:
- En una instrucción de asignación.
- En la declaración.
- Mediante entrada por teclado.
- Llamando a una función.
Los tipos de variable y valor tienen que ser los mismos o compatibles.
Comentarios
Sirven para documentar los programas, y no ejecutan ninguna acción.
Los comentarios pueden intercalarse en cualquier lugar de un programa.
Los símbolos y formato de los comentarios dependen del lenguaje de programación utilizado.
Tipos de Datos y Operadores
Clasificaciones de los Tipos de Datos
Según sean sus constituyentes:
- Simples.
- Numéricos.
- Caracteres.
- Punteros.
- Compuestos.
- Estructurados.
- No estructurados.
Según quien los haya definido:
- Predeterminados.
- Definidos por el usuario.
- Enumerados.
Según la relación entre los valores de referencia:
- Ordinales.
- No ordinales.
Según la denominación:
- Con nombre.
- Sin nombre (Anónimos).
Tipos de Operadores
-
Aritméticos: proporcionan una ecuación para calcular un valor.
+
,-
,*
,/
,%
.
-
Relacionales: comparan dos expresiones de tipo ordinal, real, cadena de caracteres o conjunto, obteniendo un resultado de tipo lógico.
<
,>
,<=
,>=
,==
(igual),!=
(distinto).
-
Lógicos: evalúan una o más expresiones lógicas, obteniendo como resultado otro valor lógico.
&&
(AND lógico),||
(OR lógico).!
(NOT).
-
Lógicos binarios: permiten manejar cada bit, de forma individual, en una palabra de memoria.
&
(AND binario),|
(OR binario),^
( XOR ).
Los distintos tipos de operadores tiene diferente precedencia y asociatividad que depende del lenguaje de programación.
Efectos secundarios
Se dice que una función o expresión tiene efecto colateral o efecto secundario si esta, además de retornar un valor, modifica el estado de su entorno.
Conversión de tipos
En una expresión de asignación o una operación, pueden existir operandos de distinto tipo.
En estas situaciones se realiza una conversion de tipos, que puede ser:
- implicita si la realiza el propio compilador.
- explicita si la realiza en programador (casting).
Para realizar una conversión explícita, (casting) se especifica el tipo de dato entre paréntesis delante de la expresión o variable a convertir.
Definición de tipos
Para crear un nuevo tipo de datos en C, se utiliza la palabra reservada typedef
:
Tamaño de los Tipos de Datos
El operador sizeof
, devuelve el tamaño en bytes que ocupa un determinado tipo de datos o una variable.
Rangos de los Tipos de Datos
Rangos de los Enteros
Rangos en una máquina de 64 bits:
Tipo | Mínimo | Máximo |
---|---|---|
short int | –32,768 | 32,767 |
unsigned short int | 0 | 65,535 |
int | –2,147,483,648 | 2,147,483,647 |
unsigned int | 0 | 4,294,967,295 |
long int | –263 | 263–1 |
unsigned long int | 0 | 264–1 |
Estos valores están definidos en
<limits.h>
.
Rangos de los Flotantes
Las características de float
y double
corresponden a un estándar IEEE:
Tipo | Mínimo | Máximo | Precisión |
---|---|---|---|
float | 1.17549 × 10–38 | 3.40282 × 1038 | 6 digitos |
double | 2.22507 × 10–308 | 1.79769 × 10308 | 15 digitos |
Por defecto, las constantes de números en punto flotantes se almacenan como números de doble precisión.
- Para indicar que solo se desea una precisión simple se pone a letra
F
(of
) al final de la constante. - Para indicar que una constante debe almacenarse en un formato doble largo, se pone la letra
L
(ol
) al final.
Tipo char
Cuando aparece un carácter (tipo char
) en un cálculo, C usa su valor entero.
La salida de este programa es: a A 97 65
.
C permite trabajar a la vez como int
y como char
un carácter.
Notaciones comprimidas
Notación larga | Notación comprimida |
---|---|
a = a + b | a += b |
a = a - b | a -= b |
a = a * b | a *= b |
a = a / b | a /= b |
a = a % b | a %= b |
a = a + 1 | a++ o ++a * |
a = a - 1 | a-- o --a * |
- Las expresiones
++
y--
antes de la variable la modifican inmediatamente. - Las expresiones
++
y--
después de la variable devuelven su valor actual y luego la modifican.
Entrada / Salida
Función printf
La función printf
tiene asociado un formato: format string, seguido de los valores (variables que tienen que
mostrarse por pantalla).
La cadena de formato puede contener tanto caracteres ordinarios como especificaciones de conversión, que comienzan con
el carácter %
.
- Una especificación de conversión es un marcador de posición que
representa un valor que se debe completar durante la impresión.
%d
se usa para valores enteros .%f
se usa para valores flotantes.%c
se usa para caracteres.
Los caracteres ordinarios en una cadena de formato se imprimen como aparecen en la cadena.
Ejemplo:
Salida:
Consideraciones de conversión
Los compiladores no están obligados a:
- Verificar que el número de especificaciones de conversión en una cadena de formato coincida con el número de elementos de salida.
- Verificar que una especificación de conversión sea apropiada.
- Si el programador usa una especificación incorrecta, el programa producirá una salida sin sentido.
Una especificación de conversión puede tener la forma %m.pX
o %-m.pX
, donde m
y p
son constantes enteras y X
es una letra que indica el tipo de dato.
m
yp
son opcionales.- Si se omite
p
, también se elimina el punto que separam
yp
.
- Si se omite
m
, el ancho de campo mínimo, especifica el número mínimo de caracteres para imprimir.- Si el valor a imprimir requiere menos de
m
caracteres, se justifica a la derecha dentro del campo. - Poner un signo menos delante de
m
causa justificación a la izquierda. - Si el valor que se va a imprimir requiere más de
m
caracteres, el ancho del campo se expande automáticamente al tamaño necesario.
- Si el valor a imprimir requiere menos de
p
indica el número mínimo de dígitos para mostrar.- Si se omite
p
, se supone que es 1.
- Si se omite
Enteros
X
esd
.- Si
p
es más grande de lo necesario, se agregan ceros adicionales al comienzo del número.
Flotantes
X
puede ser:e
para formato exponencial.p
indica cuántos dígitos deben aparecer después del punto decimal.- El valor predeterminado es 6.
- Si
p
es 0, no se muestra ningún punto decimal.
f
para formato decimal fijo.p
tiene el mismo significado que para el especificadore
.
g
para formato exponencial o formato decimal fijo, según el tamaño del número.p
indica el número máximo de dígitos significativos que se mostrarán.- La conversión
g
no mostrará ceros finales. - Si el número no tiene dígitos después del punto decimal, no muestra el punto decimal.
Ejemplos
Secuencias de escape
El código \
que se usa en las cadenas de formato se llama secuencia de escape.
Las secuencias de escape permiten que las cadenas contengan caracteres no imprimibles (caracteres de control) y caracteres que tienen un significado especial.
Algunas secuencias de escape son:
\a
: Alert (bell).\b
: Backspace.\n
: New line.\t
: Horizontal tab.\"
: Permite incluir"
dentro de una cadena.\\
: Permite incluir\
dentro de una cadena.
Función Scanf
scanf
lee la entrada de acuerdo a un formato particular.
Una cadena de formato scanf
puede contener tanto caracteres ordinarios como especificaciones de conversión.
- Las conversiones permitidas con
scanf
son esencialmente las mismas que las utilizadas porprintf
.
scanf
intenta hacer coincidir grupos de caracteres de entrada con las especificaciones de conversión en la cadena de
formato.
- Para cada especificación de conversión, intenta localizar un elemento del tipo apropiado en los datos de entrada, omitiendo espacios en blanco si es necesario.
- Luego lee el elemento y se detiene cuando alcanza un carácter que no puede pertenecer al elemento.
- Si el elemento se leyó correctamente, continúa procesando el resto de la cadena de formato.
- Cuando busca un número, ignora los caracteres de espacio en blanco (espacio, tabulación horizontal y vertical, avance de página y nueva línea).
Conceptos básicos de macros
Directivas
La estructura básica de un programa en C es:
Antes de compilar un programa, primero lo edita un preprocesador.
Los comandos destinados al preprocesador se denominan directivas.
- En C siempre comienzan con un
#
. Y no hay;
ni otro marcador especial al final.
Ejemplo:
<stdio.h>
es un encabezado que contiene información sobre la biblioteca de E/S estándar de C.
Definición de macros
Mediante la directiva #define
, se pueden definir costantes que utilizar en el resto del programa.
Por ejemplo, si se emplea varias veces el valor de π
, se puede escribir:
El preprocesador del compilador sustituye PI
por su valor (3.1415926
) en todo el texto del programa.
Introducción a los Punteros
Variables tipo Puntero
El primer paso para comprender los punteros es visualizar lo que representan a nivel de máquina:
- En la mayoría de las computadoras modernas, la memoria principal se divide en bytes, con cada byte capaz de almacenar ocho bits de información.
- Cada byte tiene una única dirección.
- Si hay n bytes en la memoria, se puede interpretar en las direcciones como números que van de 0 a n-1.
Cada variable en un programa ocupa uno o más bytes de memoria.
La dirección del primer byte se dice que es la dirección de la variable.
Las direcciones se pueden almacenar en variables de puntero especiales.
- Cuando se almacena la dirección de una variable en una variable de puntero se dice que la variable puntero apunta a la otra variable.
Declaración de punteros
Cuando se declara una variable de puntero, su nombre debe ir precedido por un asterisco *
:
Ejemplo:
int *p;
p
es una variable de puntero capaz de apuntar a objetos de tipo int
.
Se usa el término objeto en lugar de variable, ya que p
podría apuntar a un área de la memoria que no pertenece a
una
variable.
Las variables de puntero pueden aparecer en declaraciones junto con otras variables:
int i, j, a[10], b[20], *p, *q;
C requiere que cada variable de puntero apunte solo a objetos de un tipo particular (el tipo referenciado).
- No hay restricciones sobre lo cual puede ser el tipo referenciado.
Operadores de Dirección e Indirección
C proporciona un par de operadores diseñados específicamente para su uso con punteros:
- Para encontrar la dirección de una variable, se usa el operador
&
(dirección). - Para obtener acceso al objeto al que apunta un puntero (contenido), se usa el operador
*
(indirección).
Una forma de inicializar una variable de puntero es asignarle la dirección de una variable:
int i, *p;p = &i;
Asignar la dirección de i
(&i
) a la variable p
hace que p
apunte a i
.
También es posible inicializar una variable de puntero en el momento en que se declara:
int i, *p = &i;
Código diagrama
flowchart LR subgraph p &i end subgraph i vc[?] end &i --> i
Una vez que una variable de puntero apunta a un objeto, se puede usar el operador *
(indirección) para acceder a lo
que está almacenado en el objeto.
Si p
apunta a i
, se puede imprimir el valor de i
de la siguiente manera:
printf("%d\n", *p);
Si varios punteros apuntan a la misma variable, se puede modificar el valor de esta variable mediante el operador de
indirección *
y de cualquiera de los punteros.
Cualquier número de variables de puntero puede apuntar al mismo objeto.