0% encontró este documento útil (0 votos)
165 vistas

Resumen Algoritmo 1 UNLAR

El documento describe los conceptos básicos de los algoritmos y el lenguaje de programación C. Explica que un algoritmo es una secuencia de instrucciones para resolver un problema, y que los lenguajes de programación como C permiten codificar algoritmos para su ejecución en una computadora. Describe algunas características clave de C, como sus tipos de datos primitivos, variables, constantes, y funciones para entrada y salida.

Cargado por

Enzo Ochoa
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
165 vistas

Resumen Algoritmo 1 UNLAR

El documento describe los conceptos básicos de los algoritmos y el lenguaje de programación C. Explica que un algoritmo es una secuencia de instrucciones para resolver un problema, y que los lenguajes de programación como C permiten codificar algoritmos para su ejecución en una computadora. Describe algunas características clave de C, como sus tipos de datos primitivos, variables, constantes, y funciones para entrada y salida.

Cargado por

Enzo Ochoa
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 22

Algoritmo: Secuencia finita de instrucciones, reglas o pasos que describen en forma precisa las

operaciones que se debe realizar para llevar a cabo una tarea en tiempo finito (tiene un inicio y un
fin). Los algoritmos están presentes en nuestra vida cotidiana y, aún sin saberlo, aplicamos
algoritmos cada vez que se nos presenta un problema sin importar cuál sea su grado de
complejidad. Por ejemplo, “cruzar la calle”:
 Esperar a que la luz del semáforo peatonal esté en verde (esperarSemaforo);
 Cruzar la calle (cruzarCalle);
Características de un Algoritmo
 Ser preciso: Tienen que estar ordenadas lógicamente
 Ser definido: El ordenador solo desarrollara las tareas programadas con los datos
suministrados
 Ser finito: El número de pasos debe ser limitado// Esto no siempre se cumple porque
existen programas que se ejecutaran eternamente como ser el programa que calcula los
números primos.
 Ser Formal: Tiene que expresarse de formar adecuada.
 Ser Correcto: Debe satisfacer la necesidad o solucionar el problema para el cual fue
diseñado
 Ser Eficiente: En cuanto menos recursos de la computadora requiera será más eficiente el
algoritmo.
Lenguajes de Programación C: Los lenguajes de programación son lenguajes formales que se
componen de un conjunto de palabras, Podemos utilizar un lenguaje de programación para
escribir o codificar nuestro algoritmo y luego, con un programa llamado “compilador”, podremos
generar los “unos y ceros” que representan sus acciones.
Existen lenguajes de Alto nivel que son los que mas se parecen al lenguaje humano fáciles de
comprender y los de bajo nivel que se acercan más al lenguaje máquina, el lenguaje “C” es un
lenguaje de propósito general, desarrollado en 1972 por Dennis Ritchie en los Laboratorios Bell,
es considerado como un lenguaje de bajo nivel.
Cuando escribimos las acciones de un algoritmo en algún lenguaje de programación decimos que
lo estamos “codificando”. Generalmente, cada acción se codifica en una línea de código. Al
conjunto de líneas de código, que obtenemos luego de codificar el algoritmo, lo llamamos “código
fuente”. Una ves el algoritmo ha sido codificado y compilado puede ser ejecutado en una
computadora y pasa a ser llamado programa.
Los lenguajes de programación proveen bibliotecas o conjuntos de funciones a través de las
cuales se ofrece ciertas funcionalidades. Programando en “C”, por ejemplo, cuando necesitemos
mostrar un mensaje en la pantalla utilizaremos la función “printf” y cuando queramos leer datos a
través del teclado utilizaremos la función “scanf”. Ambas funciones forman parte de la biblioteca
estándar de entrada/salida de “C”, también conocida como “stdio.h”
Llamamos “consola” al conjunto compuesto por el teclado y la pantalla de la computadora en
modo texto. Cuando hablemos de ingreso de datos por consola nos estaremos refiriendo al
teclado y cuando hablemos de mostrar datos por consola estaremos hablando de la pantalla,
siempre en modo texto.

 El lenguaje de programación C fue creado por Brian Kernighan y Dennis Ritchie a


mediados de los años 70. (1972)
 Todo programa de C consta, básicamente, de un conjunto de funciones, y una función
llamada main, la cual es la primera que se ejecuta al comenzar el programa, llamándose
desde ella al resto de funciones que componen nuestro programa.
 El lenguaje C posee un número reducido de palabras reservadas (tan solo 32) que define
el standard ANSI-C.
Proceso de compilación de un programa en C
Directiva #Include: La
directiva de preprocesador se
usa en los lenguajes C para
incluir las declaraciones de otro
fichero en la compilación. En la
programación en C es posible
utilizar funciones que no estén
incluidas en el propio programa.
Para ello utilizamos la directiva
#include, que nos permite
añadir librerías o funciones que
se encuentran en otros ficheros
a nuestro programa. Para
indicar al compilador que vamos a incluir ficheros externos podemos hacerlo de dos maneras
(siempre antes de las declaraciones).
Indicándole al compilador la ruta donde se encuentra el fichero.
#include "misfunc.h"
#include "c:\includes\misfunc.h"
Indicando que se encuentran en el directorio por defecto del compilador.
#include <misfunc.h>
Comentarios: Un comentario sirve para generar anotaciones al programador en el código del
programa sobre su función, para activar o desactivar funciones entre otros ( // ; /* */ ).
Identificadores para Variables constantes y funciones en C: Un identificador es el nombre
que damos a las variables y funciones, está formado por letras en mayúsculas o minúsculas,
guion bajo y dígitos. Como restricción el primer carácter tiene que ser una letra y no acepta los
acentos ni la Ñ. Ej: Numero17=45
Sentencia: Es una sección de código que representa un comando o acción, la cual el lenguaje de
programación que estemos usando puede ejecutar. Printf(“hola mundo”); es una sentencia.
Variables: Los datos son almacenados en variables y en C como en otros lenguajes estas deben
tener un tipo de dato que es referenciado mediante un identificador (nombre de la variable). Una
variable sólo puede pertenecer a un tipo de dato. Para poder utilizarla, primero tiene que ser
declarada. Es posible inicializar y declarar más de una variable del mismo tipo en la misma
sentencia. Las variables pueden ser de dos tipos según el lugar en que las declaremos: globales
o locales. Fuera de todas las funciones del programa, son las llamadas variables globales,
accesibles desde cualquier parte del programa. La variable global se declara antes de la main().
Puede ser utilizada en cualquier parte del programa y se destruye al finalizar éste.
La variable local se declara después de la main(), en la función en que vaya a ser utilizada. Sólo
existe dentro de la función en que se declara y se destruye al finalizar dicha función.
C tiene pocos tipos de datos: Para hacer uso de variables debemos declararlas previamente
con algún tipo de dato, dependiendo del tipo será el espacio que ocupará en memoria RAM.
 Char 1 Byte. Contiene un carácter (o un número entre 0 y 255)
 Int 2 Byte. Un entero.
 Float 4 Byte. Un real
 Double 8 Byte. Un real en doble precisión
 // Estos es una anotación Void no devuelve nada
El byte: La memoria se mide en bytes. Un byte constituye la mínima unidad de información que
podemos almacenar en la memoria. En la actualidad, las computadoras traen grandes cantidades
de memoria expresadas en múltiplos del byte. Por ejemplo:
 1 gigabyte representa 1024 megabytes
 1 megabyte representa 1024 kilobytes
 1 kilobyte representa 1024 bytes.
A su vez, 1 byte representa un conjunto de 8 bits (dígitos binarios). Por lo tanto, en un byte
podemos almacenar un número binario de hasta 8 dígitos.
Calificadores de Datos en C: Los calificadores de tipo son las palabras clave que tienen la
misión de modificar el rango de valores de un determinado tipo de variable. Estos calificadores
son cuatro:
Signed: Le indica a la variable que va a llevar signo. Es el utilizado por defecto
Tipo Tamaño Rango de valores
signed char 1 byte -128 a 127
signed int 2 byte -32768 a 32767
Unsigned: Indica a la variable que no va a llevar signo (sin valores negativos).
unsigned char 1 byte 0 a 255
unsigned int 2 byte 0 a 65535
Short: Rango de valores en formato corto (limitado). Es el utilizado por
defecto.
short char 1 byte -128 a 127
short int 2 byte -32768 a 32767
Long: Rango de valores en formato largo (ampliado). El doble de lo normal
long int 4 byte -2.147.483.648 a 2.147.483.647
long double 10 byte -3`36 E-4932 a 1`18 E+4932
Las constantes: Los algoritmos resuelven situaciones problemáticas que surgen de la realidad,
donde existen valores que nunca cambiarán. Dos ejemplos típicos son los números PI  y E cuyas
aproximaciones son: 3.141592654 y 2.718281828 respectivamente.
La Directiva #Define: En C las constantes se
declaran con la directiva #define, esto significa
que esa constante tendrá el mismo valor a lo
largo de todo el programa. Al contrario que las
variables, las constantes mantienen su valor a lo
largo de todo el programa. Para indicar al
compilador que se trata de una constante,
usaremos la directiva #define. La directiva
#define no sólo nos permite sustituir un nombre por un valor numérico, también por una cadena
de caracteres. El valor de una constante no puede ser modificado de ninguna manera.
El modificador Const: Si a la declaración de una variable le aplicamos el modificador const su
valor ya no podrá ser modificado. Por ejemplo: const int temperaturaMaxima = 45;
Luego, cualquier intento de asignar otro valor a la variable temperaturaMaxima en el código del
programa generará un error de compilación.
Secuencias de
Códig Significado escape en C saltos
o de línea.
\n Salto de línea
\b Retroceso Las secuencias de
\t Tabulación horizontal escape se utilizan
\v Tabulación vertical para definir ciertos
\\ Contra barra caracteres especiales
\f Salto de página dentro de cadenas de texto. Ciertos caracteres no representados
\' Apóstrofe
gráficamente se pueden representar mediante lo que se conoce
\" Comillas dobles
como secuencia de escape.
\0 Fin de 1 cadena texto
Operadores: Tenemos operadores aritméticos, relacionales y
lógicos.

Aritméticos Operadores relacionales Operadores Lógicos


Símbolo Operación Ej Símbol Operación Ej Símbol Operación
+ Suma a+b < Menor que a<b && AND
- Resta a-b > Mayor que a>b ! Negación
a ==
* Multiplicación a*b == Igual || OR
b
/ División a/b != No igual a 1= b
Menor o igual a <=
** Potencia a ** b <=
que b
a >=
% Resto de división a % b >= Mayor o igual que
b
Contadores: Son un tipo de variables que tienen un incremento constante (IC).
cont = cont + IC cont = cont + 1
Acumuladores: Son un tipo de variables que tienen un incremento variable (IV).
acu = acu + IV acu = acu + a
La diferencia entre un acumulador y un contador es que el contador se incrementa de a 1 en
cambio el acumulador se incrementa de a “n” siendo “n” una variable. Obviamente, un contador
es un caso particular de acumulador.
Función “printf” Esta permite mostrar datos
en la consola, la salida puede estar compuesta
por un texto fijo (texto literal) o por una
combinación de texto literal y contenido
variable como veremos en el siguiente
programa.
La salida de este programa es: “Mi nombre es Pablo, tengo 39 anios y mido 1.70 metros.”
La función printf intercalo los valores de la variable nombre, edad y altura dentro del texto literal,
en las posiciones indicadas con los % (marcadores de posición).
La cadena que contiene el texto literal con los marcadores de posición se llama “máscara” y es el
primer argumento que recibe printf. A continuación, le pasamos tantos argumentos como
placeholders tenga la máscara.
printf("Mi nombre es %s, tengo %d anios y mido %lf metros.\n", nombre, edad, altura);
%c Un único carácter Cada marcador debe ir acompañado de un
carácter que representa un tipo de datos.
% Un entero con signo, en base decimal
d Por último, pasamos la lista de variables cuyos
valores se intercalarán en el texto que
% Un entero sin signo, en base decimal
queremos que printf escriba en la consola.
u
La función de biblioteca scanf: Esta función
% Un entero en base octal
permite leer datos a través del teclado y los
o
asigna en las variables que le pasemos como
%x Un entero en base hexadecimal argumento. Analicemos el código del siguiente
programa donde se le pide al usuario que
% Un real en coma flotante, con
ingrese datos de diferentes tipos.
e exponente
Scanf recibe como primer argumento una
%f Un real en coma flotante, sin exponente
máscara que indica el tipo de los datos que la
%s Una cadena de caracteres función debe leer. Los marcadores coinciden
% Un puntero o dirección de memoria con los que utiliza printf, por tanto con %s le
p indicamos que lea una cadena de caracteres y
con %d y %lf le indicamos que lea un entero y
un flotante respectivamente. Para que una
función pueda modificar el valor de un argumento tenemos
que pasarle su referencia o su dirección de memoria, esto
lo obtenemos anteponiendo el operador & (léase “operador
ampersand”) al identificador de la variable cuyo valor
queremos que la función pueda modificar.
El caso de las cadenas de caracteres es diferente, las
cadenas se manejan como arrays de caracteres. Si bien
este tema lo estudiaremos más adelante, es importante saber que el identificador de un array es
en sí mismo su dirección de memoria, razón por la cual no fue necesario anteponer el
operador “&” a la variable nombre para que scanf pueda modificar su valor.
El operador de dirección &: El operador & se llama “operador de dirección” y aplicado a una
variable nos permite obtener su referencia o dirección de memoria.
Tendremos que utilizar este operador cada vez que necesitemos que una función pueda modificar
el valor de alguna variable que le pasemos como argumento.
Estructuras de control:
Secuencial, selección e
iteración: Las estructuras de
control permiten modificar el flujo
de ejecución de las instrucciones
de un programa, a través de: if,
else, switch, while, do while y for.
El teorema de la programación estructurada describe tres estructuras básicas de control con las
que demuestra que es posible resolver cualquier problema computacional.
Estructura secuencial: Consiste en ejecutar, secuencialmente, una acción simple detrás de otra.
Recordemos, también, que se considera acción simple a las acciones de leer, escribir, asignar
valor a una variable e invocar a un módulo o función.
Estructura de decisión selectiva: La estructura de decisión permite decidir entre ejecutar uno u
otro conjunto de acciones en función de que se cumpla o no una determinada condición lógica.
Cuando en una estructura de decisión utilizamos dentro otra estructura de decisión, decimos que
ambas son estructuras anidadas.
Estructura Condicional – IF: La estructura selectiva “if” permite que el flujo del programa siga
por un camino específico si se cumple una condición determinada. Si al evaluar la condición el
resultado es verdadero, entonces se sigue por un camino específico. En cambio, si la evaluación
es falsa (else) se puede seguir por otro camino, si lo he definido de esa manera o terminar dicha
estructura.
Estructuras Repetitivas: En la práctica, durante la solución de problemas, es muy común
encontrar, operaciones que se deben ejecutar un número determinado de veces. Si bien las
instrucciones son las mismas, los datos varían. El conjunto de instrucciones que se ejecuta
repetidamente recibe el nombre de ciclo.
Todo ciclo debe terminar luego de repetirse un número finito de veces. Dentro del conjunto de
instrucciones siempre debe existir una condición de parada o fin de ciclo. En cada iteración del
mismo son evaluadas las condiciones necesarias para decidir si se debe seguir ejecutando o si
debe detenerse.
Estructuras Repetitivas – for: Ésta es la orden que usaremos para crear partes del programa
que se repitan un cierto número de veces. Así, para contar del 1 al 10, tendríamos 1 como valor
inicial, <=10 como condición de repetición, y el incremento sería de 1 en 1. El formato de “for” es:
for (valorInicial; CondiciónRepetición;
Incremento) { Sentencia; }
Por tanto, el programa quedaría:
int contador;
for (contador = 1; contador<=10; contador++)
 { printf(“Repetición número %d”, contador); }

Estructuras Repetitivas while:


La sentencia se
repetirá mientras la condición sea
cierta. Si la condición es falsa ya
desde un principio, la sentencia no se ejecuta nunca. En este caso se ingresa un valor mayor a 0
y se informa si el valor es par o impar.
Estructuras Repetitivas do while: Este es el otro formato que puede tener la orden “while”: la
condición se comprueba al final. El punto en que comienza a repetirse se indica con la orden “do”.
En esta la condición se ejecuta al menos una vez, luego si el while se cumple no se ejecutara el
do y finaliza pero si no se cumple se ejecuta el do hasta que la condicion en el while se cumpla.
Como ejemplo, vamos a ver cómo sería el típico
programa que nos pide una clave de acceso y
nos deja entrar hasta que tecleemos la clave
correcta. En este caso, se comprueba la
condición al final, de modo que se nos
preguntará la clave al menos una vez. Mientras
que la respuesta que demos no sea la correcta,
se nos vuelve a preguntar. Finalmente, cuando
tecleamos la clave correcta, el ordenador
escribe “Aceptada” y termina el programa.

Sentencia
Continue: Se utiliza dentro de un bucle. Cuando el programa llega a
una sentencia CONTINUE no ejecuta las líneas de código que hay a
continuación y salta a la siguiente iteración del bucle.
En el ejemplo muestra por consola del 1 al 10 excepto el 5.
Sentencia Break: La instrucción de salto break se usa para interrumpir (romper) la ejecución
normal de un bucle, es decir, la instrucción break finaliza (termina) la ejecución de un bucle y, por
tanto, el control del programa se transfiere (salta) a la primera instrucción después del bucle.
Sentencia Goto: Otro comando que tiene el lenguaje C es el goto. Este comando nos permite
saltar en forma incondicional a cualquier otra parte de la misma función. La sentencia goto no es
aconsejada en la metodología de programación estructurada pero su uso en casos especiales
nos permite crear código más conciso. Un caso común donde se la utiliza es cuando queremos
salir de una serie de for anidados a un bloque de la misma función, pero fuera de dichos for (tener
en cuenta que el comando break solo sale del for que la contiene)
Funciones: Las funciones son bloques de códigos utilizados para dividir un programa en partes
mas pequeñas, cada una de las cuales tendrá una tarea determinada.
tipo_funcion nombre_funcion (tipo y nombre de argumentos) { bloque de sentencias }
Tipo de función: puede ser cualquier tipo de los que conocemos, el valor devuelto por la función
será de este tipo. La función devolverá un valor de tipo entero ( int ) por defecto si no indicamos el
tipo y si no queremos que retorne ningún valor deberemos indicar el tipo vacío ( void ).
Nombre_funcion: es el nombre que le daremos a la función.
Tipo y nombre de argumento: Los argumentos de una
función no son mas que variables locales que reciben un
valor. Este valor se lo enviamos al hacer la llamada a la
función. Pueden existir funciones que no reciban
argumento.
Bloque de sentencias: es el conjunto de sentencias que serán ejecutadas cuando se realice la
llamada a la función.
Las funciones pueden ser llamadas desde la función main o desde otras funciones. Al finalizar la
ejecución de esta sus variables locales se destruirían.
Declaración de una función o prototipo de una función: al
igual que las variables las funciones también son
declaradas, a esto se llama prototipo de una función,
pueden escribirse antes de la función main o bien en otro
fichero. En el caso de hacerlo en otro fichero se lo
indicaremos al compilador con la directiva #include. En el
programa anterior muestra el num 10 de la variable local
en main y al llamar a void función muestra el num 5 de la
variable global.
Función return: las funciones pueden retornar un valor.
Esto se puede hacer con return, que al finalizar la
ejecución devuelva un valor. Return (valor o expresión);
El valor devuelto por la función tiene que asignarse a una variable para que no se pierda.
Macros: Las macros son directivas de preprocesador con las que podemos relacionar un nombre
con una expresión. Por ejemplo: #define MAX(x,y) x>y?x:y #define MIN(x,y) x<y?x:y
El preprocesador de C
reemplazará cada macro
por la expresión que
representa. Así, podemos
invocar a macro MAX de
la siguiente manera:
mayor = MAX(a,b);
donde a y b son
argumentos que le
pasamos a la
macro MAX. El
preprocesador
reemplazará la línea
anterior por la siguiente
línea:
mayor = a>b?a:b
Selección múltiple (switch): La estructura permite tomar una decisión en función de que el valor
de una variable o el resultado de una expresión numérica entera coincidan o no con alguno de los
valores indicados en diferentes casos o con ninguno de estos. Gráficamente, la representaremos
así: ↑
Este gráfico debe interpretarse de la siguiente manera: si el valor de unaVariable es 1 entonces
se ejecutarán las acciones accion1, accion2 y accion3. En cambio, si unaVariable vale 2 se
ejecutarán las acciones accion4 y accion5. Podemos agregar tantos casos como necesitemos.
Por último, podemos indicar la opción default que representa a todos los otros casos que no
fueron indicados explícitamente.
Los casos deben representarse con valores numéricos literales o constantes. El caso default es
opcional.
Ejemplo: Leer un valor
numérico que representa un
día de la semana. Se pide
mostrar por pantalla el nombre
del día considerando que el
lunes es el día 1, el martes es
el día 2 y así, sucesivamente.
Este problema se puede
resolver fácilmente utilizando
una estructura de selección
múltiple como veremos a
continuación:
En el diagrama leemos el número de día en la variable nroDia y luego, utilizamos una estructura
de selección múltiple (switch) con los casos 1, 2, 3, 4, 5, 6 y 7.
Si el usuario ingresó el número de día 1, entonces la estructura ingresará por el caso case
1 donde le asignamos la cadena “Lunes” a la variable dia. Análogamente, si el usuario ingresa el
valor 2, entraremos por case 2 y le asignaremos a dia la cadena “Martes” y así, sucesivamente.
Es muy importante poner la sentencia break al finalizar el conjunto de acciones que se ejecutan
dentro de cada caso ya que si la omitimos se ejecutarán secuencialmente todas las acciones de
todos los casos subsiguientes.
Es decir, supongamos que el usuario ingresa el día número 5 y omitimos poner los breaks
entonces el programa ingresará por case 5, asignará “Viernes” a dia, luego le asignará “Sábado” y
luego “Domingo”. Por lo tanto, la salida será: 5 es Domingo
Para asignar el nombre de cada día a la variable dia, no utilizamos el operador de asignación, lo
hacemos a través de la función strcpy. Esto lo explicaremos a continuación.
Arrays, arreglos, cadenas o vectores en C - Ejemplos y uso: Los arrays son variables
estructuradas como cadena de caracteres, donde cada elemento se almacena de forma
consecutiva en un número de notaciones.
Un array es un identificador que referencia un conjunto de datos del mismo tipo. Imagina un tipo
de dato int; podremos crear un conjunto de datos de ese tipo y utilizar uno u otro con sólo cambiar
el índice que lo referencia. El índice será un valor entero y positivo. En C los arrays comienzan
por la posición 0.
ARRAY Unidimensional (Vector): Un array es un conjunto de datos del mismo tipo ordenados
de forma lineal una detrás del otro y el array unidimensionales también llamado vector sólo utiliza
un índice para referenciar a cada uno de los elementos. Su declaración será: tipo nombre
[tamaño];
El tipo puede ser cualquiera de los ya conocidos
y el tamaño indica el número de elementos del
vector (se indica entre corchetes [n]). En el ej
puedes observar que la variable “i” es utilizada
como índice, el primer for sirve para rellenar el
vector y el segundo para visualizarlo. Como ves,
las posiciones van de 0 a 9 (total 10 elementos).
Podemos inicializar (asignarle
valores) un vector en el momento de
declararlo. Si lo hacemos así no es
necesario indicar el tamaño. Su
sintaxis es: tipo nombre []={ valor 1, valor 2...}
Una particularidad con los vectores de tipo char (cadena de caracteres), es que deberemos
indicar en que elemento se encuentra el fin de la cadena mediante el carácter nulo (\0). Esto no lo
controla el compilador, y tendremos que ser nosotros los que insertemos este carácter al final de
la cadena.
Por tanto, en un vector de 10 elementos de tipo char podremos rellenar un máximo de 9, es decir,
hasta vector[8]. Si sólo rellenamos los 5 primeros, hasta vector[4], debemos asignar el carácter
nulo a vector[5]. Es muy sencillo: vector[5]='\0';
Asignación de valores alfanuméricos (función strcpy): Como comentamos anteriormente las
cadenas de caracteres tienen un tratamiento especial ya que en C se implementan
sobre arrays (conjuntos) de caracteres.
Por este motivo, no podemos utilizar el operador de asignación = para asignarles valor. Tenemos
que hacerlo a través de la función de biblioteca strcpy (definida en el archivo “string.h”).
Esta función toma cada uno de los caracteres de la cadena “Hola” y los asigna uno a uno a los
elementos del conjunto s. Gráficamente, podemos verlo así:
Definimos un array de 10 caracteres (o un conjunto de 10 variables de tipo char) char s[10];
Asignamos uno a uno los caracteres de la cadena “Hola” a los caracteres de s. strcpy(s, "Hola");

Además, strcpy agrega el carácter especial '\0' (léase “barra cero”) que delimita el final de la
cadena. Es decir que si bien s tiene espacio para almacenar 10 caracteres nosotros solo estamos
utilizando 5. Cuatro para la cadena “Hola” más 1 para el '\0'.
Vale decir entonces que en un array de n caracteres podremos almacenar cadenas de, a lo sumo,
n-1 caracteres ya que siempre se necesitará incluir el carácter de fin de cadena '\0' al final.
Aquí utilizamos el operador
de asignación = para
asignar el valor “Pablo” a la
variable nombre. Esto solo
se puede hacer al momento
de definir la variable.
Incluso, como no hemos
dimensionado la cantidad de caracteres que el array nombre puede contener, C dimensionará el
conjunto de caracteres con tantos elementos como sea necesario para mantener la cadena
Aquí estamos intentando
asignar “Pablo” a nombre,
pero en una línea posterior a
la declaración de la variable
lo cual no es válido y al
compilar obtendremos un
error.
La manera correcta de
hacerlo sería la siguiente
con “string.h” y strcpy()

Matrices (Array) Bidimensional y Tridimensional: Una matriz es un vector de vectores o un


también llamado array bidimensional. Una matriz bidimensional es una lista de matrices
unidimensionales. Una matriz es un array multidimensional. Se definen igual que los vectores
excepto que se requiere un índice por cada dimensión.
Su sintaxis es la siguiente: tipo nombre [tamaño 1]
[tamaño 2]...;
Una matriz bidimensional se podría representar
gráficamente como una tabla con filas y columnas.
La matriz tridimensional se utiliza, por ejemplo, para
trabajos gráficos con objetos 3D.
En el ej se rellena y visualiza una matriz bidimensional.
Se necesitan dos bucles para cada una de las
operaciones. Un bucle controla las filas y otro las
columnas.
Si al declarar una matriz también queremos inicializarla, habrá que tener en cuenta el orden en el
que los valores son asignados a los elementos de la matriz. Veamos algunos ejemplos:
int numeros[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
quedarían asignados de la siguiente manera:
numeros[0][0]=1 numeros[0][1]=2 numeros[0][2]=3 numeros[0][3]=4
numeros[1][0]=5 numeros[1][1]=6 numeros[1][2]=7 numeros[1][3]=8
numeros[2][0]=9 numeros[2] numeros[2][2]=11 numeros[2][3]=12
[1]=10
También se pueden inicializar cadenas de texto:
char dias[7][10]={"lunes","martes","miércoles","jueves","viernes","sábado","domingo"};
Para referirnos a cada palabra bastaría con el primer índice: printf("%s",dias[i]);
Estructuras y Uniones en C - Arrays de estructuras: Una estructura es una colección de
elementos finita y heterogénea. Se utilizan para resolver problemas que involucran tipos de datos
estructurados.
Una estructura es un conjunto de una o más variables, de distinto tipo, agrupadas bajo un mismo
nombre para que su manejo sea más sencillo. Su utilización más habitual es para la
programación de bases de datos, ya que están especialmente indicadas para el trabajo con
registros o fichas.
La sintaxis de la declaración de Estructuras es la siguiente:
tipo_estructura: es el nombre del nuevo tipo de dato que hemos
creado. Por último, tipo_variable y nombre_variable son las
variables que forman parte de la estructura.
Para definir variables del tipo que acabamos de crear lo podemos
hacer de dos maneras (las más utilizadas) son las siguientes:
En el primer caso declaramos la estructura, y en el momento
en que necesitamos las variables de estructura, las
declaramos.
En el segundo las declaramos al
mismo tiempo que la estructura, el
problema de este método es que no
podremos declarar más variables de este tipo a lo largo del programa, y
en cambio en la primera podremos seguir creando más variables de esa
estructura.
Para poder declarar una variable de tipo estructura, la estructura tiene que estar declarada
previamente. Se debe declarar antes de la función main.
El manejo de las estructuras es muy sencillo, así como el acceso a los campos (o variables) de
estas estructuras. La forma de acceder a estos campos es la siguiente: variable.campo;
Donde variable es el nombre de la variable de tipo estructura que hemos creado, y campo es el
nombre de la variable que forma parte de la estructura. Ej: temporal.edad=25;
Otra característica interesante de las estructuras es que permiten pasar el contenido de una
estructura a otra, siempre que sean del mismo tipo naturalmente: fijo=temporal. Aquí estoy
igualando dos variables de tipo estructura en el cual todo contenido dentro de estas se convierte
en el mismo (fijo = temporal con esto sus datos se igualan (fijo.edad = temporal.edad;
fijo.nombre= temporal.nombre; etc)).
Estructuras y funciones: Podemos enviar una
estructura a una función:
Por valor: su declaración sería:
void visualizar(struct trabajador);
Después declararíamos la variable fija y su
llamada sería: visualizar(fijo);
Por último, el desarrollo de la función sería:
void visualizar(struct trabajador
datos)
Arrays de estructuras:
Es posible agrupar un
conjunto de elementos
de tipo estructura en
un array. Esto se
conoce como array de
estructuras:
Así podremos
almacenar los datos de 20 trabajadores.
Ejemplos sobre como acceder a los campos y sus elementos: para ver el nombre del cuarto
trabajador, fijo[3].nombre;. Para ver la tercera letra del nombre del cuarto trabajador,
fijo[3].nombre[2];. Para inicializar la variable en el momento de declararla lo haremos de esta
manera:
struct trabajador fijo[20]={{"José","Herrero Martínez",29},{"Luis","García Sánchez",46}};
Typedef: Es posible agrupar un conjunto de elementos de tipo estructura en un array. Esto se
conoce como array de estructuras: El lenguaje 'C' dispone de una declaración llamada typedef
que permite la creación de nuevos tipos de datos. Ejemplos:
typedef int entero; /* crear un tipo de dato llamado entero */
entero a, b=3; /* declaramos dos variables de este tipo */
Con eso podemos remplazar la palabra reservada int por entero, otro ejemplo;
typedef printf imprimir;
imprimir(“Hola Mundo”);
Su empleo con estructuras está especialmente indicado. Se puede hacer de varias formas las dos
más usadas son:

Algoritmos de Búsqueda y Ordenamiento:


Los procesos de búsqueda involucran recorrer un array completo con el fin de encontrar algo. Lo
más común es buscar el menor o mayor elemento, o buscar el índice de un elemento
determinado.

El programa de Para buscar el menor o mayor elemento


ejemplo posee una de un array, podemos usar la
función que recibe estrategia, de suponer que el primero o
como parámetro un el último es el menor (mayor), para
array de 10 enteros, luego ir comparando con cada uno de
y luego solicita el los elementos, e ir actualizando el
número que desea menor (mayor). A esto se le llama
encontrar entre esos Búsqueda Lineal.
10, y retorna la
posición donde se Búsqueda Secuencial: Consiste en ir
encuentra el entero comparando el elemento que se busca
que se busca si es con cada elemento del array hasta
que se encuentra, encontrarlo. Buscamos el elemento ‘u’
de lo contrario
en la imagen.
devolverá –1.
Búsqueda Binaria:
La Búsqueda Binaria de array ordenados,
compara si el valor buscado está en la mitad
superior o inferior. En la que esté, subdivido
nuevamente, y así sucesivamente hasta
encontrar el valor. Por lo tanto, la velocidad de
ejecución depende logarítmicamente del
tamaño del arreglo.
Supuesto: Array con datos ordenados en forma
ascendente: i < k → a [ i ] < [ k ]
Estamos buscando la posición del valor 17
Ordenamiento de Burbuja: compara el elemento inferior con el superior y los ordena.

En el ejemplo se crea una


función para intercambiar las
posiciones de los números
utilizando
punteros, luego se crea el array y se inicia la búsqueda de si el primero es mayor al segundo se
llamara a la función intercambiar donde el primero pasa a ser segundo y se pasa a preguntar
nuevamente si el segundo es menor que el tercero y intercambiar, esto hasta que todo el array
este ordenado y sale de la función mostrando el array en orden.
Punteros: Un puntero es una variable que contiene la dirección de memoria de otra variable. Se
usan para pasar información entre una función y puntos de llamada. Los punteros permiten
código más compacto y eficiente; utilizándolos en forma ordenada dan gran flexibilidad a la
programación. La dirección de memoria de una variable se obtiene con el operador unario &.
Declaración de Punteros: Su sintaxis es la siguiente: tipo *nombre;
Donde nombre es, naturalmente, el nombre de la variable, y tipo es el tipo del elemento cuya
dirección almacena el puntero.
Operadores: Existen dos operadores especiales para trabajar con punteros: & y *
El primero devuelve la dirección de memoria de su operando. Por ejemplo, si queremos guardar
en el puntero x la dirección de memoria de la variable num, deberemos hacer lo siguiente:
x=#
El segundo devuelve el valor de la variable cuya dirección es contenida por el puntero. Este
ejemplo sitúa el contenido de la variable apuntada por x, es decir num, en la variable a:
A=*x;
Obtención de números aleatorios en C: A veces queremos que nuestro programa obtenga
números de forma aleatoria. En C de linux tenemos varias funciones que nos permiten obtener
estos valores aleatorios.
La función rand(): Esta función, cada vez que la llamamos, nos devuelve un número entero
aleatorio entre 0 y el RAND_MAX.
El primer problema que se nos presenta es que no solemos querer un número aleatorio en ese
rango. Podemos querer, por ejemplo, un número aleatorio entre 0 y 10. O de forma más general,
entre 0 y N. La forma de hacerlo es la siguiente:
numero = rand() % 11; numero = rand() % (N+1);
La operación módulo (%) nos da el resto de dividir rand() entre 11. Este resto puede ir de 0 a 10.
De la misma forma, el módulo de rand() entre N+1 va de 0 a N.
¿Y si queremos un rango que no empiece en 0?. Por ejemplo, queremos un rango
entre 20 y 30 (de forma más general, entre M y N con N mayor que M). Pues es fácil, obtenemos
un número entre 0 y 10 y le sumamos 20 (un número entre 0 y N-M y le sumamos M).  
numero = rand () % 11 + 20; // Este está entre 20 y 30
numero = rand () % (N-M+1) + M; // Este está entre M y N
La función srand(): Se nos presenta un nuevo problema. Si ejecutamos varias veces nuestro
programa, la secuencia de números aleatorios se repite. Imaginemos que tenemos un programa
que escribe 3 número aleatorios entre 0 y 10. Lo ejecutamos una vez y sale, por ejemplo 4, 7 y 9.
Lo ejecutamos por segunda vez y vuelve a salir 4, 7 y 9. La tercera vez sale lo mismo y cuando ya
nos hemos hartado de ejecutar, vuelve a salir lo mismo.
El problema es que rand() "calcula" los números aleatorios. Parte de un número inicial (llamado
semilla), echa unas cuentas y saca un número aleatorio. Para el segundo número, echa unas
cuentas con el resultado anterior y saca un segundo número y así sucesivamente.
Si volvemos a ejecutar el programa desde el principio, el número inicial (la semilla) que
usa rand() es el mismo, con lo que la secuencia de números aleatorios es la misma, ya que las
cuentas son las mismas. Para evitar este problema tenemos la función srand(), a la que se le
pasa de parámetro un número que se utilizará como número inicial para las cuentas. A esta
función sólo debemos llamarla una vez en nuestro programa.
¿Qué número le ponemos a este srand()?. No podemos ponerle un número fijo, porque entonces
no hemos hecho nada. No podemos ponerle un número obtenido con rand(), porque la primera
vez siempre nos dará el mismo y el resultado será igual que si le ponemos un número fijo.
Debemos buscar la forma de obtener un número que sea distinto en la ejecución de cada
programa.
Hay dos números que se utilizan habitualmente para ello:
La fecha/hora del sistema. Este valor cambia si ejecutamos el programa en distinto instante de
tiempo. Tendríamos que arrancar el programa dos veces en el mismo segundo para obtener la
misma secuencia de números aleatorios. En C de linux esta fecha/hora se obtiene con la
función time(): srand (time(NULL));
El número de proceso del programa. El primer programa que se arranca cuando se enciende el
ordenador con el sistema operativo linux, tiene el número de proceso 1, el segundo el 2, el tercero
el 3 y así sucesivamente. Cuando arrancamos nuestro programa, se le asignará el número que le
toque, por ejemplo, el 215. Cuando lo volvamos a arrancar, se le asignará el que le toque (puede
ser 216 si no hemos ejecutado nada entre medias o 345, si nos hemos entretenido con otras
cosas). Después de ejecutar nuestro programa varios miles de veces, el número de proceso
puede que se repita, pero ya no nos acordaremos de la secuencia que se sacó la primera vez. El
número de proceso se obtiene con getpid(): srand (getpid());
A esta función sólo hay que llamarla una vez al principio de nuestro programa. Cada vez que la
llamemos, estaremos reiniciando los cálculos de números aleatorios desde el principio, con lo que
se repetirá todo.
Las funciones drand48() y srand48(): ¿Y si queremos un número aleatorio con decimales? 
Tenemos la función drand48() que nos devuelve un número aleatorio con decimales
entre 0.0 (incluido, puede salir el 0,0) y 1.0 (excluido, nunca saldrá 1.0). A partir de ahí es fácil
transformarlo al rango que queramos. Si queremos un rango entre 10.0 y 20.0 (o
entre M y N siendo N mayor que M y ambos con decimales, aunque sean .0)
numero = drand48() * (20.0-10.0) + 10.0;
numero = drand48() * (N-M) + N;
De la misma forma que antes, la secuencia de números aleatorios se repetirá cada vez que
ejecutemos nuestro programa y de igual manera, tenemos manera de cambiar la "semilla" de esa
secuencia. Hay que llamar a la función srand48() pasándole un entero que sea distinto en cada
ejecución del programa. Nuevamente, tenemos las dos opciones anteriores:
srand48(time(NULL));
srand48(getpid());
SEGUIMIENTO DEL ALGORITMO Y “PRUEBA DE ESCRITORIO”
La prueba de escritorio es una herramienta que nos permite comprobar si el algoritmo realmente
funciona como esperamos.
Básicamente, consiste en definir un conjunto de datos arbitrarios que llamaremos “lote de datos” y
utilizarlos en un seguimiento, paso a paso, de cada una de las acciones del algoritmo controlando
los valores que irán tomando las variables, las expresiones lógicas y la salida que se va a emitir.
Analizaremos una prueba de escritorio, considerando el
siguiente lote de datos {5, 2, 3, 0}.
Comenzamos leyendo n que, según nuestro lote de datos,
tomará el valor 5.
Inicializamos suma en 0 y luego entramos a un ciclo de
repetición para iterar mientras que n sea distinto de “0” o,
dicho de otro modo, mientras que la expresión “n es distinto
de cero” sea verdadera.
Como n vale 5 se verifica la condición lógica e ingresamos al while. Dentro del while asignamos a
suma su valor actual (cero) más el valor de n (cinco) por lo que ahora suma vale 5.
Luego volvemos a leer n que tomará el valor 2 y volvemos a la cabecera del ciclo de repetición
para evaluar si corresponde iterar una vez más.
Como n (que vale 2) es distinto de cero volvemos a ingresar al while, asignamos a suma su valor
actual (cinco) más el valor de n (dos) por lo que suma ahora vale 7.
Luego leemos n que tomará el valor 3. La condición del ciclo se sigue verificando porque n (que
vale 3) es distinto de cero. Entonces asignamos a suma su valor actual (que es 7) más el valor de
n (que es 3). Ahora suma vale 10.
Volvemos a leer n que tomará el valor cero y evaluamos la condición del ciclo. Como la expresión
“n es distinto de cero” resulta falsa el ciclo no volverá a iterar, salimos del while y mostramos el
valor de la variable suma: 10.
Todo este análisis puede
resumirse en la siguiente
tabla que iremos llenando
paso a paso, siguiendo el
algoritmo y considerando
que ingresan uno a uno
los valores del lote de datos.
La tabla debe leerse de arriba hacia abajo y de izquierda a derecha.
El debugger, la herramienta de depuración: Es una herramienta que permite seguir paso a
paso la ejecución del código fuente del programa. También permite monitorear los valores que
toman las variables y evaluar las expresiones. Las IDE integran el debugger con el editor de
código fuente de forma tal que, dentro del mismo editor, el programador pueda seguir línea por
línea la ejecución del programa y así, depurarlo de errores de lógica.
Diagrama de flujo:
Un diagrama de flujo es un
diagrama que describe un
proceso, sistema o
algoritmo informático. Se
usan ampliamente en
numerosos campos para
comunicar procesos que
suelen ser complejos en
diagramas claros y fáciles
de comprender.
Los diagramas de flujo
emplean numerosas figuras
para representar diferentes
tipos de acciones o pasos
en un proceso, los básicos
son los siguientes y a
continuación el resto:

Símbolo del Un documento o informe impreso.


Documento Impreso

Símbolo de Representa multidocumento en el proceso.


Multidocumentos

Símbolo de Entrada Representa un paso en el que se pide al usuario


Manual que introduzca la información manualmente.

Símbolo de Representa un ajuste a otro paso en el proceso.


Preparación

Símbolo del Conector Indica que el flujo continúa donde se ha


colocado un símbolo idéntico (que contiene la
misma letra).
O Símbolo Indica que el flujo del proceso continúa en más
de dos ramas.

Símbolo de Unión de Indica un punto en el diagrama de flujo en el que


Invocación múltiples ramificaciones convergen de nuevo en
un solo proceso.

Símbolo de Fusión Indica un paso en el que dos o más sub-listas o


subprocesos se convierten en uno.

Símbolo de Intercalar Indica un paso que ordena información en un


formato estándar.

Símbolo de Ordenar Indica un paso que organiza una lista de


elementos en una secuencia o establece según
algunos criterios predeterminados.

Símbolo de Proceso Indica una secuencia de acciones que realizan


Predefinido una tarea específica incrustada dentro de un
proceso más grande. Esta secuencia de
acciones podría describirse con más detalle en
un diagrama de flujo separado.

Símbolo del Indica una secuencia de comandos que


Operación Manual continuarán repitiéndose hasta que se detenga
manualmente.

Símbolo de Límite de Indica el punto en el que debe detenerse un


Bucle bucle.

Símbolo de Retardo Indica un retraso en el proceso.


Almacenamiento de Almacenados
Datos o Símbolo de Indica un paso donde se almacenan los datos.
Datos

Símbolo de la Base Indica una lista de información con una


de Datos estructura estándar que permite buscar y
ordenar.

Símbolo de Indica que la información se almacenó en la


Almacenamiento memoria durante un programa, utilizado en
Interno diagramas de flujo de diseño de software.

Símbolo de Indica un paso que muestra información.


Visualización

Conector Fuera de Indica que el proceso continúa fuera de la


Página página.

También podría gustarte