4 PR1
4.1 Cómo tratar elementos de un vector con un bucle
Imaginemos que nos piden un programa que realice dos acciones:
- Leer desde el canal estándar de entrada (teclado) 5 números e introducirlos en un vector de enteros.
- Mostrar por el canal estándar de salida (pantalla) los 5 números del vector de enteros del punto anterior.
El algoritmo podría ser el siguiente:
const
MAX_NUMS: integer = 5;
end const
algorithm vectorDeNumeros
var
i: integer;
numeros: vector[MAX_NUMS] of integer;
end var
{ Asignar valor a cada posición del vector desde teclado }
for i := 1 to MAX_NUMS do
writeString("Introduce número : ");
numeros[i] := readInteger();
end for
{ Mostrar por el canal estándar de salida qué valor hay
en cada posición del vector: se podría haber usado un bucle for,
pero lo implementamos con un while para que se vea que también
es posible hacerlo con este bucle. }
i := 1;
while i ≤ MAX_NUMS do
writeString("La posición ");
writeInteger(i);
writeString(" del vector contiene el número ");
writeInteger(numeros[i]);
{ En un bucle while es muy importante incrementar
la variable usada como índice antes de finalizar
el bloque de instrucciones que ejecuta, ya que
en caso contrario su valor sempre sería i == 1. }
i := i+1;
end while
end algorithm
Como se puede ver, con el fin de insertar/leer los elementos de un vector aprovechamos la iteración de un bucle para recorrerlos todos, uno a uno, con una variable que utilizamos de índice (en estos casos, la variable i
).
La traducción a C del algoritmo podría ser así:
/* Ejemplo ES0401 */
#include <stdio.h>
#define MAX_NUMS 5
int main(int argc, char **argv) {
int numeros[MAX_NUMS];
int i;
/* Asignar valor a cada posición del vector desde teclado */
for (i = 0; i < MAX_NUMS; i++) {
printf("Introduce número : ");
scanf("%d", &numeros[i]);
}
/* Mostrar por pantalla qué valor hay en cada posición
* del vector: se podría haber usado un bucle for,
* pero lo implementamos con un while para que se vea que
* también es posible hacerlo con este bucle.
*/
i = 0;
while (i < MAX_NUMS) {
printf("\nLa posición %d del vector contiene el número %d", i, numeros[i]);
/* En un bucle while es muy importante incrementar la variable usada
* como índice antes de finalizar el bloque de instrucciones que ejecuta,
* ya que en caso contrario su valor siempre sería i == 1.
*/
i = i+1;
}
return 0;
}
4.2 Entrada continua de valores con un bucle
Imaginemos que tenemos que hacer un programa que vaya pidiendo números indefinidamente y que finalice únicamente en el caso de que el número ingresado sea par.
Una posible forma de hacerlo usando un único while
sería la siguiente:
/* Ejemplo ES0402 */
#include <stdio.h>
int main(int argc, char **argv) {
int numero;
/* Pedimos una primera vez el número a validar
* justo antes de entrar en el bucle.
*/
printf("Teclea un número par : ");
scanf("%d", &numero);
while ((numero % 2) != 0) {
/* Entra en el bucle en el caso de que el
* resto de la división por 2 sea
* diferente de 0 (equivale a no ser par).
*/
printf("El número %d no es par \n", numero);
/* Volvemos a pedir un número, ahora ya
* dentro del bucle.
*/
printf("Teclea un número par : ");
scanf("%d", &numero);
}
printf("El número %d es par \n", numero);
return 0;
}
Antes de entrar en el bucle pedimos el valor de la variable numero
. Después se utiliza la condición de bucle para validar si se trata de un número par o impar:
- Si el número es par, no se entra en el bucle.
- Si el número es impar se cumple la condición del bucle y se entra; dentro del bucle se vuelve a pedir un valor para la variable
numero
y se vuelve a actuar igual que antes:- Si es impar, no se sale del bucle.
- En caso contrario, se sale del bucle.
Finalmente se muestra por pantalla el mensaje “El número X es par”.
4.3 Cómo tratar valores en múltiples vectores
Imaginemos que queremos introducir por teclado una serie de datos de los trabajadores de nuestra empresa: DNI, días de antigüedad y sueldo bruto anual. Estos datos los introduciremos en tres vectores diferentes: uno para los DNI, el otro para la antigüedad y el último para el sueldo bruto anual. El valor del sueldo neto mensual se calculará a partir del bruto y se guardará también en un vector.
El programa debe pedir por teclado los datos de 5 empleados, y al finalizar mostrará los valores por pantalla de la siguiente forma:
>> empleado: 39284019x
antigüedad (días): 784
bruto anual (€): 36874.78
neto mensual (€): 1659.36
>> empleado: 31214557m
antigüedad (días): 128
bruto anual (€): 20015.30
neto mensual (€): 1086.54
El sueldo neto mensual se calcula aplicando la siguiente retención y posteriormente dividiendo por 14 pagas:
sueldo bruto | retención |
---|---|
sueldo < 12450.0€ | 19.0% |
12450.0€ <= sueldo < 20200.0€ | 24.0% |
20200.0€ <= sueldo < 35200.0€ | 30.0% |
35200.0€ <= sueldo < 60000.0€ | 37.0% |
sueldo > 60000.0€ | 45.0% |
El algoritmo podría ser el siguiente:
const
MAX_ELEMS: integer = 5;
TRAMO1: float = 12450.0;
RETENCION1: float = 19.0;
TRAMO2: float = 20200.0;
RETENCION2: float = 24.0;
TRAMO3: float = 35200.0;
RETENCION3: float = 30.0;
TRAMO4: float = 60000.0;
RETENCION4: float = 37.0;
RETENCION5: float = 45.0;
NUM_PAGAS: integer = 14;
end const
algorithm datosSueldos
var
vDni: vector[MAX_ELEMS] of string;
vAntiguedad: vector[MAX_ELEMS] of integer;
vBrutoAnual: vector[MAX_ELEMS] of real;
vNetoMensual: vector[MAX_ELEMS] of real;
i: integer;
end var
{ Lectura de datos desde el canal de entrada. }
{ Se usa un único índice, 'i', para recorrer todos los vectores. }
for i := 1 to MAX_ELEMS do
writeString("datos empleado num. ");
writeInteger(i);
writeString(":");
writeString(">> dni : ");
vDni[i] := readString();
writeString(">> antigüedad : ");
vAntiguedad[i] := readInteger();
writeString(">> bruto anual : ");
vBrutoAnual[i] := readReal();
{ Cálculo del sueldo neto mensual. }
if (vBrutoAnual[i] < TRAMO1) then
vNetoMensual[i] := (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION1/100)) / NUM_PAGAS;
else
if (vBrutoAnual[i] < TRAMO2) then
vNetoMensual[i] := (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION2/100)) / NUM_PAGAS;
else
if (vBrutoAnual[i] < TRAMO3) then
vNetoMensual[i] := (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION3/100)) / NUM_PAGAS;
else
if (vBrutoAnual[i] < TRAMO4) then
vNetoMensual[i] := (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION4/100)) / NUM_PAGAS;
else
vNetoMensual[i] := (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION5/100)) / NUM_PAGAS;
end if
end if
end if
end if
end for
{ Se muestran los datos por el canal de salida. }
{ Se usa un único índice, 'i', para recorrer todos los vectores. }
for i := 1 to MAX_ELEMS do
writeString(">> empleado: ");
writeString(vDni[i]);
writeString(" antigüedad (días): ");
writeInteger(vAntiguedad[i]);
writeString(" bruto anual (€): ");
writeInteger(vBrutoAnual[i]);
writeString(" neto mensual (€): ");
writeInteger(vNetoMensual[i]);
end for
end algorithm
¿Cómo lo podemos implementar en C? Una posible solución sería la siguiente:
/* Ejemplo ES0403 */
#include <stdio.h>
#define MAX_ELEMS 5
#define TRAMO1 12450.0
#define RETENCION1 19.0
#define TRAMO2 20200.0
#define RETENCION2 24.0
#define TRAMO3 35200.0
#define RETENCION3 30.0
#define TRAMO4 60000.0
#define RETENCION4 37.0
#define RETENCION5 45.0
#define NUM_PAGAS 14
#define MAX_DNI 9+1
typedef char tDni[MAX_DNI];
int main(int argc, char **argv) {
tDni vDni[MAX_ELEMS];
int vAntiguedad[MAX_ELEMS];
float vBrutoAnual[MAX_ELEMS];
float vNetoMensual[MAX_ELEMS];
int i;
/* Lectura de datos desde el teclado.
Se usa un único índice, 'i', para recorrer todos los vectores. */
for (i = 0; i < MAX_ELEMS; i++) {
printf("datos empleado núm. %d : \n", i);
printf(">> dni : ");
scanf("%s", vDni[i]);
printf(">> antigüedad : ");
scanf("%d", &vAntiguedad[i]);
printf(">> brut anual : ");
scanf("%f", &vBrutoAnual[i]);
/* Cálculo del sueldo neto mensual. */
if (vBrutoAnual[i] < TRAMO1) {
vNetoMensual[i] = (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION1/100)) / NUM_PAGAS;
} else {
if (vBrutoAnual[i] < TRAMO2) {
vNetoMensual[i] = (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION2/100)) / NUM_PAGAS;
} else {
if (vBrutoAnual[i] < TRAMO3) {
vNetoMensual[i] = (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION3/100)) / NUM_PAGAS;
} else {
if (vBrutoAnual[i] < TRAMO4) {
vNetoMensual[i] = (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION4/100)) / NUM_PAGAS;
} else {
vNetoMensual[i] = (vBrutoAnual[i] -
(vBrutoAnual[i]*RETENCION5/100)) / NUM_PAGAS;
}
}
}
}
}
/* Se muestran los datos por pantalla.
Se usa un único índice, 'i', para recorrer todos los vectores. */
for (i = 0; i < MAX_ELEMS; i++) {
printf("\n>> empleado: %s \n", vDni[i]);
printf(" antigüedad (días): %d \n", vAntiguedad[i]);
printf(" bruto anual (€): %.2f \n", vBrutoAnual[i]);
printf(" neto mensual (€): %.2f \n", vNetoMensual[i]);
}
return 0;
}
Dentro del bucle utilizamos la variable i
como índice para ir recorriendo todos los vectores a la vez.
En ambos casos la inserción de los valores en los vectores la hacemos de la misma forma: utilizamos el índice i
para determinar la posición del vector donde ubicaremos los valores:
/* ... */
scanf("%s", vDni[i]);
/* ... */
scanf("%d", &vAntiguedad[i]);
/* ... */
scanf("%f", &vBrutoAnual[i]);
Al final del ejemplo mostramos todos los empleados introducidos mediante un segundo bucle, mostrando todos los datos introducidos anteriormente y los calculados.
4.4 Definición chars vs strings
En el lenguaje C, los caracteres se definen siempre con comilla simple '
, mientras que para los string se utiliza la comilla doble "
.
Ejemplo:
/* Ejemplo ES0404 */
#include <stdio.h>
#include <string.h>
#define MAX_PALABRA 8+1
int main(int argc, char **argv) {
char saludo[MAX_PALABRA];
char exclamacion;
/* Asignación de valor a un string con comilla doble. */
strcpy(saludo, "Hi World");
/* Asignación de valor a un char con comilla simple. */
exclamacion = '!';
printf("%s %c\n", saludo, exclamacion);
return 0;
}
4.5 Variable-sized object may not be initialized
El error variable-sized object may not be initialized
se produce cuando definimos el tamaño de un vector con const
y a la vez estamos inicializando el vector con valores:
const int NUM_JUGADORES = 5;
/* ... */
int vDorsalesEquipo[NUM_JUGADORES] = {1, 3, 23, 12, 99}; /* caso con error */
Pero en cambio, si realizamos la misma operación utilizando #define
, funciona correctamente:
#define NUM_JUGADORES 5
/* ... */
int vDorsalesEquipo[NUM_JUGADORES] = {1, 3, 23, 12, 99}; /* caso sin error */
El motivo es el comportamiento del array cuando recibe una constante o una variable (en este punto es reconamable revisar el punto Constantes: define vs const de las FAQ). Comentamos los dos casos más detalladamente:
Caso sin error
Cuando utilizamos #define NUM_JUGADORES 5
para definir una constante significa que en los pasos previos a la compilación del programa (fase de precompilación) se realiza una sustitución de todas las referencias de NUM_JUGADORES
por el valor 5
. De esta forma, en el momento de compilar el programa, ya se está trabajando con un valor constante, 5
, que puede ser evaluado y, por tanto, permite realizar la inicialización de los 5 valores que le pasamos:
int vDorsalesEquipo[5] = {1, 3, 23, 12, 99};
Caso con error
Cuando utilizamos const int NUM_JUGADORES = 5;
no estamos definiendo realmente una constante, sino que se define la variable NUM_JUGADORES
en memoria y se le asigna el valor 5
, con la particularidad de que la variable es read-only. Sin embargo, este tipo no es interpretado por el compilador como equivalente a una constante.
Por tanto, queremos hacer la siguiente operación utilizando la variable read-only NUM_JUGADORES
:
int vDorsalesEquipo[NUM_JUGADORES] = {1, 3, 23, 12, 99};
Cuando a un vector se le define el tamaño con una variable, es tratada en el momento de ejecución, una vez el programa se ha compilado. Por lo tanto, en el momento que el compilador está generando el ejecutable de nuestro programa en C, detecta una situación en la que, por un lado se quiere inicializar un array
con 5 valores (1, 3, 23, 12, 99), pero por otro lado se está concretando el tamaño del vector con una variable read-only de la que no se sabrá el valor hasta que se haya pasado la fase de compilación. Esta incongruencia temporal es la que no puede gestionar el compilador y acaba generando el error variable-sized object may not be initialized
.
Por este motivo, falla el caso que acabamos de comentar, pero en cambio el siguiente funciona correctamente aunque también se use const
:
const int NUM_JUGADORES = 5;
/* ... */
int vDorsalesEquipo[NUM_JUGADORES];
/* caso sin error */
vDorsalesEquipo[0] = 1;
vDorsalesEquipo[1] = 3;
vDorsalesEquipo[2] = 23;
vDorsalesEquipo[3] = 12;
vDorsalesEquipo[4] = 99;
4.6 Ejemplo: pesoPromedio
Imaginemos que queremos hacer un programa que nos ayude a calcular nuestro peso promedio semanal. Añadiremos por teclado las lecturas diarias de nuestro peso en el programa y, en caso de encontrar algún valor incoherente, lo obviará y lo volverá a pedir.
En lenguaje algorítmico lo podemos implementar de la siguiente forma:
const
NUM_DIAS: integer = 7;
PESO_MIN: real = 50.0;
PESO_MAX: real = 110.0;
end const
algorithm pesoPromedio
var
i: integer; { Contador que utilizará nuestro programa. }
peso: real; { Variable auxiliar para la lectura de pesos. }
pesos: vector[NUM_DIAS] of real; { Peso en Kg: 79.5, ... }
sumaPesos: real;
end var
i := 1;
sumaPesos := 0;
{ Se lee desde teclado los pesos diarios, uno a uno. }
while y ≤ NUM_DIAS do
{ Leemos un valor desde el canal estándar de entrada. }
writeString( "Introduce peso (Kg.):");
peso := readReal();
{ A continuación hay que revisar que este valor sea coherente. Tomamos
como valores "posibles" aquellos que estén entre PESO_MIN y PESO_MAX.
Fijaos que la lectura se guarda temporalmente en la variable 'peso':
cuando hayamos validado que contenga un valor válido, lo añadiremos
dentro del vector de pesos. }
if PESO_MIN ≤ peso and peso ≤ PESO_MAX then
{ En este punto, la variable 'peso' contiene un valor correcto,
con lo que ya lo podemos añadir al vector de pesos. }
pesos[i] := peso;
{ El siguiente punto es muy importante: como ya hemos añadido
el peso correcto, incrementaremos la variable 'i', la cual nos sirve
para acceder a una nueva posición del vector a la siguiente
iteración del bucle. }
i = i + 1;
else
{ En caso contrario, el peso es incorrecto con el que se muestra
el correspondiente mensaje de error. }
writeString("Peso incorrecto!");
{ Importante: aquí no incrementamos la variable 'i', ya que el valor
no es correcto; queremos que en la siguiente iteración del bucle,
se continúe intentando añadir el valor leído dentro
de la posición 'i' del vector. }
end if
{ En este punto tenemos el pesos que tiene 7 (=NUM_DIES) pesos válidos. }
{ Ahora utilizaremos un segundo bucle para recorrer todos los valores del
vector y hacer el cálculo pedido: la media de todos ellos. Si hubiéramos
querido, habríamos podido hacer todo en un único bucle, pero se ha preferido
separarlo para que quede más claro que se hace dentro de cada uno
de los dos bucles. }
for i := 1 to NUM_DIAS do
{ Dentro de la variable sumaPesos vamos sumando cada uno de los pesos
de las posiciones del vector. }
sumaPesos: = sumaPesos + pesos[i];
end for
{ Para calcular la media, únicamente nos falta dividir el valor
sumaPesos por el número total de pesos introducidos o, lo que es lo mismo,
NUM_DIAS. }
writeString( "El peso promedio semanal es:");
writeReal(sumaPesos / NUM_DIAS);
end algorithm
Una posible implementación en lenguaje C puede ser la siguiente:
/* Ejemplo ES0405 */
#include <stdio.h>
#define NUM_DIAS 7
#define PESO_MIN 50.0
#define PESO_MAX 110.0
int main(int argc, char **argv) {
float pesos[NUM_DIAS];
int i;
float peso;
float sumaPesos;
i = 0; /* ¡Importante! en lenguaje C los vectores empiezan por 0. */
sumaPesos = 0;
/* Primer bucle: introducción y validación de datos. */
while (i<NUM_DIAS) {
printf("Introduce peso (Kg.) : ");
scanf("%f", &peso);
if (PESO_MIN <= peso && peso <= PESO_MAX) {
pesos[i] = peso;
i = i+1;
} else {
printf("Peso incorrecto!\n");
}
}
/* Segundo bucle: cálculo intermedio para el promedio de pesos. */
for (i=0; i<NUM_DIAS; i++) {
sumaPesos = sumaPesos + pesos[i];
}
printf("El peso promedio semanal es : %.2f", sumaPesos/NUM_DIAS);
return 0;
}
4.7 Ejemplo: topFilms
A continuación se expone un ejemplo en el que se recorren vectores y calculan resultados en función de una serie de filtros.
Imaginemos que tenemos un listado con el top 10 de películas con mayor recaudación de la historia. De cada película sabemos su orden en el top 10 (actuará como identificador único de cada película), nombre, recaudación y año. Queremos que, dados un año y una cifra de recaudación entrados por teclado, se muestren por pantalla aquellas películas que sean del mismo año y acumulen una recaudación superior o igual a la cifra introducida.
Una posible implementación en lenguaje C sería la siguiente:
/* Ejemplo ES0406 */
#include <stdio.h>
#define TOP_FILMS 10
int main(int argc, char **argv) {
/* Declaración de variables */
/* Vectores */
int posiciones[TOP_FILMS]; /* Contiene el orden de películas con mayor recaudación */
char* titulos[TOP_FILMS]; /* Contiene los títulos de las películas */
int years[TOP_FILMS]; /* Contiene los años de las películas */
int recaudaciones[TOP_FILMS]; /* Contiene las recaudaciones (en millones US$) */
int recaudacion; /* Filtro para buscar películas con >= recaudación */
int year; /* Filtro para buscar películas con == year */
int posicionesEncontradas[TOP_FILMS]; /* Contiene el orden de las películas encontradas */
int numFilmsEncontrados; /* Contador de películas encontradas */
int i;
/* Inicialización de variables */
numFilmsEncontrados = 0;
/* Datos de recaudación extraídos de https://cutt.ly/iRs0N9v */
/* Para centrarnos en los recorridos de los vectores
* y buscar las películas que cumplen una serie de
* requisitos, se introducen directamente los valores en los
* correspondientes vectores, sin pasar por la lectura
* desde teclado.
*/
posiciones[0] = 1;
posiciones[1] = 2;
posiciones[2] = 3;
posiciones[3] = 4;
posiciones[4] = 5;
posiciones[5] = 6;
posiciones[6] = 7;
posiciones[7] = 8;
posiciones[8] = 9;
posiciones[9] = 10;
titulos[0] = "Avengers: Endgame";
titulos[1] = "Avatar";
titulos[2] = "Titanic";
titulos[3] = "Star Wars: El despertar de la Fuerza";
titulos[4] = "Avengers: Infinity War";
titulos[5] = "Jurassic World";
titulos[6] = "The Avengers";
titulos[7] = "Furious 7";
titulos[8] = "Avengers: Age of Ultron";
titulos[9] = "Black Panther";
years[0] = 2019;
years[1] = 2009;
years[2] = 1997;
years[3] = 2015;
years[4] = 2018;
years[5] = 2015;
years[6] = 2012;
years[7] = 2015;
years[8] = 2015;
years[9] = 2018;
recaudaciones[0] = 2797;
recaudaciones[1] = 2789;
recaudaciones[2] = 2187;
recaudaciones[3] = 2068;
recaudaciones[4] = 2048;
recaudaciones[5] = 1671;
recaudaciones[6] = 1518;
recaudaciones[7] = 1516;
recaudaciones[8] = 1405;
recaudaciones[9] = 1346;
/* Por teclado se piden dos filtros para recorrer todas las películas y
* encontrar las que cumplen las condiciones: el año de creación (debe ser
* igual) y la recaudación (debe ser igual o superior)
*/
printf("Año: ");
scanf("%d", &year);
printf("Recaudación mínima (en millones US$): ");
scanf("%d", &recaudacion);
/* En este caso hemos llenado las 10 posiciones máximas de los vectores,
* con lo que podemos utilizar TOP_FILMS como límite de elementos a
* recorrer en los vectores. Si no hubiera sido así, debería utilizarse
* un contador adicional que indicara el número de películas
* introducidas
*/
for (i=0; i<TOP_FILMS; i++) {
/* Se comprueba que la película tratada cumpla las
* condiciones entradas por teclado
*/
if (years[i] == year && recaudaciones[i] >= recaudacion) {
posicionesEncontradas[numFilmsEncontrados] = posiciones[i];
numFilmsEncontrados = numFilmsEncontrados + 1;
}
}
/* Salida de resultados por pantalla */
if (numFilmsEncontrados > 0) {
printf("Películas encontradas = %d: \n", numFilmsEncontrados);
for (i=0; i<numFilmsEncontrados; i++) {
printf("%d. %s (%d): %d M$\n", posicionesEncontradas[i],
titulos[posicionesEncontradas[i]-1], years[posicionesEncontradas[i]-1],
recaudaciones[posicionesEncontradas[i]-1]);
}
} else {
printf("Películas encontradas = %d: ninguna cumple las condiciones.\n",
numFilmsEncontrados);
}
return 0;
}
Un ejemplo de ejecución sería el siguiente:
Año: 2015
Recaudación mínima (en millones US$): 1500
Películas encontradas = 3:
4. Star Wars: El despertar de la fuerza (2015): 2068 M$
6. Jurassic World (2015): 1671 M$
8. Furious 7 (2015): 1516 M$
4.8 Errores más frecuentes
4.8.1 Estructura iterativa: for vs while
Este no es un error sintáctico o semántico, sino un error de diseño frecuente.
Código incorrecto:
#include <stdio.h>
#include <stdbool.h>
#define NUM 10
int main(int argc, char **argv) {
int i;
char password[NUM] = {'a', '1', 'h', '\0'};
for (i = 0; password[i] != '\0'; i++){
/* ... */
}
return 0;
}
En el código anterior, parece que queremos recorrer un vector de caracteres elemento a elemento, para ejecutar alguna acción. Para ello, decidimos utilizar un bucle y una condición final: las iteraciones se detendrán en el momento en que nos encontramos con el carácter especial '\0'
, indicador de fin de cadena de caracteres.
El problema es que el bucle for
no es la estructura más indicada para resolver este algoritmo, ya que está pensado para repetir un bloque de código un número de veces predeterminado, basado casi siempre en un índice (i
) que se ha de incrementar/decrementar desde un valor inicial a uno final. En este caso, la condición final no tiene nada que ver con el valor numérico del índice, por lo tanto es mucho mejor utilizar el bucle while
.
Código correcto:
#include <stdio.h>
#include <stdbool.h>
#define NUM 10
int main(int argc, char **argv) {
int i;
char password[NUM] = {'a', '1', 'h', '\0'};
i = 0;
while (password[i] != '\0'){
/* ... */
i++;
}
return 0;
}
Es importante recordar que en el caso de la estructura while
, el índice i
no se actualiza automáticamente: se debe hacer manualmente antes de cerrar el bloque.
4.8.2 Vectores: acceso a posiciones del vector
Pseudocódigo incorrecto:
const
MAX: integer = 3;
end const
var
vecNum: vector[MAX] of integer;
end var
vecNum[4] := 3;
En lenguaje algorítmico, un vector de dimensión N tiene las posiciones numeradas de 1 a N. Por contra, en lenguaje C las posiciones están numeradas de 0 a N-1.
El vector vecNum
tiene tres posiciones, pero estamos accediendo a la cuarta (inexistente). Es un error grave, especialmente en C, ya que los accesos a posiciones de vector no declaradas pueden conllevar errores de ejecución, aunque en el momento de compilar el código no se produzca ningún error.
Cuando usamos vectores, en caso de errores de ejecución inesperados y sin motivo aparente, siempre hay que revisar el código para comprobar que no se está accediendo a posiciones incorrectas. Es especialmente importante en el caso de los bucles iterativos, donde el acceso a los elementos del vector se hace mediante el uso de una variable.
Pseudocódigo correcto:
const
MAX: integer = 3;
end const
var
vecNum: vector[MAX] of integer;
end var
vecNum[3] := 3;