[ Foro de Pascal ]
Hola profesor Nacho cabanes.
profesor estoy realizando un programa de arrays de registros que pide obtener los tres primeros ganadores de una maraton.los tiempos estan en minutos
el esquema es el siguiente:
nombre nacionalidad T1 T2 T3 T4
oscar españa 30 20 40 48
mario francia 20 50 58 35
pedro argentina 10 20 30 40
maria portugal 40 50 50 50
jose italia 30 30 25 40
bien queria como primera pregunta el por que me esta dando el error que te indico en el enunciado, y segundo como podria hacer el procedimiento de ordenacion?
program atletas;
uses crt;
const numpart=5;
numvueltas=4;
type
cadena=string[30];
atleta=record
nombre,pais:cadena;
t:array[1..numpart] of real;
end;
carrera=array[1..numpart] of atleta;
tiempos=array[1..numpart] of integer;
var
c:carrera;
i,j:integer;
tiempo:tiempos;
function calculartiempo(c:carrera;numvueltas:integer):integer;
var
i,cont:integer;
cont:=0; //////**** aui me registra el error ????????****
for i:=1 to numvueltas do
cont:=cont+c[i].t[i];
calculartiempo:=cont;
end;
procedure ordenar(c:carrera;tiempo:tiempos;numpart:integer) of carrera
...??????
????????
procedure medallas(c:carrera;numpart:integer) of integer;
var
tiempo:tiempos;
i:integer;
for i:=1 to numpart do
tiempo[i]:=calculartiempo(c[i],numvueltas);
ordenar(c,tiempo,numpart);
end;
begin
clrscr;
writeln;writeln;writeln;writeln;
for i:=1 to numpart do
begin
writeln('introduzca el nombre del atleta: ');
readln(c[i].nombre);
writeln('introduzca la nacionalidad del atleta: ');
readln(c[i].pais);
for j:=1 to numvueltas do
begin
writeln('introduca el tiempo ',j,':');
readln(c[i].t[j]);
end;
end;
medallas(c,numpart);
for i:=1 to numpart do
writeln('el tiempo para el atleta ',i, ' es: ',tiempo[i]);
readkey;
end.
mil gracias por tu ayuda profesor.
Hola Óscar,
Tu error se debe a que estás declarando dos veces la variable "cont". La asignación "cont:= 0" tienes que hacerla detrás del "begin".
Con respecto a la ordenación, hay varios métodos. A mí me gusta el de burbuja, pero puede ser un poco lioso ( http://es.wikipedia.org/wiki/Ordenamiento_de_burbuja ).
Hay otros muchos métodos de ordenamiento, cada uno con sus costes en tiempo y memoria.
Uno sencillo es el de "inserción directa" ( http://es.wikipedia.org/wiki/Ordenamiento_por_selección ).
¡Suerte!
Cordial saludo profesor Nacho y Antonio.
Antes que todo gracias antonio por tu respuesta ,ya la he solucionado gracias a tu concejo.
Bien queria preguntarles por lo siguiente:
Para este ejemplo
nombre nacionalidad T1 T2 T3 T4
oscar españa 30 20 40 48
mario francia 20 50 58 35
pedro argentina 10 20 30 40
maria portugal 40 50 50 50
el resultado que me esta devolviendo el writeln de la funcion: calculartiempo es incorrecto , es decir no se me esta sumando como quiero para cada atleta sus 4 tiempos, sino que me esta tomando el tiempo t1 para el primer atleta, luego le suma el tiempo t2 del segundo atleta, luego le suma el tiempo t3 del tercer atleta y a todo lo anterior le suma el cuarto tiempo del atleta cuatro dandome como resultado 160 y en el writeln del procedimiento tiempo[i], para cada atleta es 160 , cuando lo que yo quiero es reflejar que el tiempo para el atleta 1 es 138(tiempo[1]=138), para el atleta 2 es 163(tiempo[2]=163), para el atleta 3 es 100(tiempo[3]=100) y para el atleta 4 es 190(tiempo[4]=190) con los datos que di en el ejemplo.
el codigo es:
program atletas;
uses crt;
const numpart=4;
numvueltas=4;
type
cadena=string[30];
atleta=record
nombre,pais:cadena;
t:array[1..numpart] of integer;
end;
carrera=array[1..numpart] of atleta;
tiempos=array[1..numpart] of integer;
var
c:carrera;
i,j:integer;
{ tiempo:tiempos;}
function calculartiempo(var c:carrera;numvueltas:integer):integer;
var
i,cont:integer;
begin
cont:=0;
for i:=1 to numvueltas do
begin
cont:=cont+c[i].t[i];
writeln('aqui cont vale: ',cont);
end;
calculartiempo:=cont;
end;
procedure medallas(c:carrera;numpart:integer);
var
tiempo:tiempos;
i:integer;
begin
for i:=1 to numpart do
begin
tiempo[i]:=calculartiempo(c,numvueltas);{*******}
writeln('el tiempo para el atleta ',i, ' es: ',tiempo[i]);
end;
{ordenar(c,tiempo,numpart);}
end;
begin
clrscr;
writeln;writeln;writeln;writeln;
for i:=1 to numpart do
begin
writeln('introduzca el nombre del atleta: ');
readln(c[i].nombre);
writeln('introduzca la nacionalidad del atleta: ');
readln(c[i].pais);
for j:=1 to numvueltas do
begin
writeln('introduca el tiempo ',j,':');
readln(c[i].t[j]);
end;
end;
medallas(c,numpart);
readkey;
end.
no se si el error lo tenga en el procedimiento medallas cuando llamo a la funcion, es decir:
tiempo[i]:=calculartiempo(c,numvueltas);{*******}
por que he intentado hacerlo asi:
tiempo[i]:=calculartiempo(c[i],numvueltas);{*******} pero me da error type mismatch, podrian indicarme como debo hacerlo corectamente para lograr mi objetivo de calcular la suma de tiempos para cada atleta, es que no se si el paso de c sea correcto o como debo hacerlo, ademas queria saber si cada vez que se envia una variable de array de registro como es en mi caso c, deba ser por referencia( es decir con var dentro de la funcion) o si no es necesario???
mil gracias por sus ayudas profesor Nacho y Antonio.
Hola otra vez,
A ver, yo replantearía algunas cosas. Si quieres desarrollar una función para calcular el tiempo de un atleta 'i', haría lo siguiente:
----------------------------------
function TiempoTotalAtleta (num, n_tiempos : integer; vector_atletas : carrera) : integer;
{ "num" es el número del atleta, "n_tiempos" el número de tiempos que hay por atleta y "vector_atletas" el vector que contiene la información de la carrera. }
var
j : integer; { Es un contador. }
acum : integer; { Es un acumulador. }
begin
acum:= 0;
for j:= 1 to n_tiempos do
acum:= acum + vector_atletas[num].t[j];
TiempoTotalAtleta:= acum;
end;
-----------------------------------
Fíjate que la función que habías implementado pasaba a la vez al siguiente tiempo y al siguiente atleta, puesto que habías puesto el contador en ambos vectores.
Algunas notas después de ver (muy por encima) tu código:
- Elimina las variables globales. Éstas son las que van justo después de la declaración de tipos, al comienzo del código. Trasládalas al punto posterior a los subprogramas y anterior al cuerpo del programa principal. (Como lo tienes estructurado ahora, no te haría falta declarar las variables "i", "j", y "c" en ninguna parte de los subprogramas, pero queremos modularidad y con sentido :-) ).
- Puesto que estás manejando siempre números positivos o iguales a cero, trata de utilizar el tipo "word" en vez de "integer". A nivel de gasto de memoria, creo que es lo mismo, pero tiene más sentido y queda más elegante.
- Utiliza verbos o acciones para denominar los procedimientos. En plan "PintarCasa". En cambio, para las funciones utiliza sustantivos, "PinturaCasa".
- Trata de no introducir instrucciones de lectura "read" o escritura "write" en las funciones. No recuerdo el por qué, pero es aconsejable. Quizás Nacho pueda explicarlo.
- (Esta es personal) Prefiero "n_..." que "num..." para denominar variables que almacenan el número de algo.
Por último, con respecto a tu última pregunta:
- Por "referencia" o "variable", se hace cuando dicho parámetro va a ser modificado dentro del procedimiento o función y queremos que dicha modificación permanezca tras haber sido ejecutado ese procedimiento/función.
- Por valor, se utiliza cuando, independientemente de que ese parámetro vaya a ser modificado o no dentro del procedimiento o función, no queremos que permanezcan esos cambios tras la ejecución del subprograma.
Ejemplo. Imaginemos lo siguiente:
-----------------------------
program (input,output);
procedure Ejecutar (a, var b, c : integer);
begin
writeln ('Me gusta este valor: ',a);
b:= 2*b;
c:= c + 50;
end;
var
x, y, z : integer;
begin
x:= 3;
y:= 4;
z:= 7;
Ejecutar (x,y,z);
writeln ('X no ha sido modificado, porque sigue valiendo tres, ',x);
writeln ('Ahora Y vale el doble que antes, ',y);
writeln ('Z no ha sido modificado, porque sigue valiendo siete, ',z);
end.
-----------------------------
Si quieres ejecútalo y estúdialo. Seguro que lo entiendes :-).
¡Ciao!
Cordial saludo profesor Nacho y Antonio.
Gracias antonio tenias razon en cuanto a el calculo de los tiempos de cada atleta, lo corregi y me funciona ok, sin embargo queria pedirles su ayuda para poder realizar la ordenacion de forma descendente segun los tiempos totales de cada atleta es decir ordenarlos de mayor a menor segun tiempos totales obtenidos,yo entiendo el metodo de la burbuja pero para ordenamientos sencillos pero en realidad al tratarse de ordenar arrays de registros ,me esta costando pues lo que he buscado y leido, mas o menos me ha ayudado pero no me refleja los resultados correctamente, el codigo que hago para el procedimiento ordenacion_por burbuja es el siguiente:
procedure ordenar(var car:carrera;tiempo:tiempos;numpart:integer);
var
i,j:integer;
ordenado:boolean;
aux:atleta;
begin
i:=1;
repeat
ordenado:=true;
for j:=1 to numpart-1 do
if tiempo[j]>tiempo[j+1] then
begin
aux:=c[j];
c[j]:=c[j+1];
c[j+1]:=aux;
ordenado:=false;
end;
i:=i+1;
until ordenado or (i>numpart);
end;
el anterior procedimiento lo llamo desde:
procedure medallas(var c:carrera;numpart:integer);
var
tiempo:tiempos;
i:integer;
begin
for i:=1 to numpart do
begin
tiempo[i]:=calculartiempo(c,numvueltas,i);
writeln('el tiempo para el atleta ',i, ' es: ',tiempo[i]);
end;
ordenar(c,tiempo,numpart);
for i:=1 to numpart do
writeln(c[i].nombre);
end;
me esta dando resultados que no corresponden es decir:
nombre nacionalidad T1 T2 T3 T4 totaltiempo
oscar españa 30 20 40 48 138
mario francia 20 50 58 35 163
pedro argentina 10 20 30 40 100
maria portugal 40 50 50 50 190
la respuesta correcta deberia ser :
maria
mario
oscar
pedro
pero parece que no me esta haciendo ningun tipo de ordenamiento pues mis resultados siguen igual es decir me muestra:
oscar
mario
pedro
maria
queria pedirles su ayuda para poder alcanzar mi objetivo , indicandome posibles errores en mi funcion o llamado a la misma, o que me indiquen como se hacerlo y entender asi coo se ordenan arrays de registros que por lo visto al no darme el resultado esperado es por que no lo tengo claro del todo, mil gracias a los dos por su gran ayuda siempre!!!
Hola,
Te cuento según voy viendo cosas.Lo primero es una nota, con respecto al intercambio que realizas en caso de que un tiempo de un atleta con una posición menor sea mayor que el de un atleta que va después. Aquí utilizas la variable "aux". Te recomiendo que en vez de esto, utilices un procedimiento "Intercambiar" tal que:
---------------------------------
procedure Intercambiar (var a,b : atleta);
var
aux : atleta;
begin
aux:= a; a:= b; b:= aux;
end;
---------------------------------
Puesto que creo que queda más elegante. (Tu manera de intercambiar es correcta también, claro).
Con respecto al método que utilizas para ordenar, no sé cuál es muy bien... Si es el de la burbuja, necesitas dos bucles de recorrido completo (for), de forma que uno vaya en una dirección y el otro en la otra. Ésta sería más o menos la forma usando parte de tu código:
---------------------------------
procedure ordenar(var car:carrera;tiempo:tiempos;numpart:integer);
var
i,j:integer;
begin
for i:=numpart downto 2 do
for j:=1 to i-1 do
if tiempo[j]>tiempo[j+1] then
Intercambiar (car[j], car[j+1]);
end;
---------------------------------
(Si no me equivoco, y si no te funciona así dímelo). Si quieres entender el algoritmo bien, dibújate unos arrays y ejecútalo a mano, o tal vez puedes encontrar algo por la Red.
Por cierto, como puedes observar, la variable "ordenado" sobra.
¡Un saludo!
Hola antonio ante todo mil gracias por todo lo que haces por nosotros, y en particular por tu valiosa ayuda.
antonio estoy aqui provando cosas precisamente para intentar lograr el resultado y me cae muy bien tu respuesta, que aunque no he provado aun, viendolo por encima antes por favor dime por que usas el downto 2 ,y bueno paso a provar con el codigo que me adjuntaste y ya te conatre como fue.
gracias espero aqui tu explicacion.gracias antonio
Hola, Antonio.
mira acabo de probar tu codigo aunque no me bota ningun error de compilacion en ejecuacion los resultados no se intercambian ,es decir me muestra los datos tal y como los entramos sin ordenar nada, es decir me sale con los datos siguientes introducidos:
nombre nacionalidad T1 T2 T3 T4 total
oscar españa 30 20 40 48 138
mario francia 20 50 58 35 163
pedro argentina 10 20 30 40 100
maria portugal 40 50 50 50 190
y el resultado que se espera una vez ordenados debe ser:
nombre nacionalidad T1 T2 T3 T4 total
maria portuga 40 50 50 50 190
mario francia 20 50 58 35 163
oscar españa 30 20 40 48 138
pedro argentina 10 20 30 40 100
eso por una parte y otra cosita que te queria preguntar de paso en tu codigo como es que se puede hacer:
procedure ordenar(var car:carrera;tiempo:tiempos;numpart:integer);
...
...
Intercambiar (car[j], car[j+1]);
y en los argumentos de la funcion:
procedure Intercambiar (var a,b : atleta);
pones a, b de tipo atleta? es decir por que puedes hacer esto si lo que envias como parametros son dos variables de tipo carrera? me podrias explicar porque haces esto o por que se puede hacer? por tu ayuda mil mil gracias antonio
Te comento lo del "downto 2". Es "2" por dos motivos:
- No tendría sentido en el bucle secundario la declaración "j:= 1 to i-1", dado que si en vez de "2" pusiese "1", habría un momento en el que haría "de 1 hasta cero", y para este caso no se ejecuta el bucle.
- Para la última vuelta miraré en el array la casilla (atleta) número 1, y la compararé con la siguiente. Es decir, tengo que hacer numpart-1 vueltas.
Es un downto porque he querido. También podría haberlo expresado al revés. Depende de la condición del if..then, es decir, de si empiezo comparando el primero con su siguiente o del último con su anterior y también depende de como quiera expresar la cabecera del segundo bucle. Sin embargo, también lo podía haber expresado así:
----------------------------
procedure ordenar(var car:carrera;tiempo:tiempos;numpart:integer);
var
i,j:integer;
begin
for i:=1 to numpart-1 do
for j:=1 to numpart - i do
if tiempo[j]>tiempo[j+1] then
Intercambiar (car[j], car[j+1]);
end;
---------------------------
(Eso creo...)
Prueba ambos tipos, a ver si funcionan y me cuentas, ¿ok?
¡Suerte!
Hola,
Con respecto a tu última pregunta, es el vector de atletas el que es de tipo carrera, pero cada uno de los campo de ese vector de atletas es un atleta. Cuando yo intercambio, lo que hago es cambiar la información de cada atleta por la del otro. ¿Claro?
Por favor, ¿podrías colgar todo el código que llevas construido en un archivo (de texto, .pas,..., como veas) para probar yo el programa? Así podré buscar el error (mío o tuyo) mejor ;-).
¡Ciao!
Hola, Antonio.
mira acabo de probar las dos formas que me planteaste y aunque no me botan ningun error de compilacion en ejecuacion los resultados no se intercambian ,es decir me muestra los datos tal y como los entramos sin ordenar nada, es decir me sale en ejecucion lo siguiente:
nombre nacionalidad T1 T2 T3 T4 total
oscar españa 30 20 40 48 138
mario francia 20 50 58 35 163
pedro argentina 10 20 30 40 100
maria portugal 40 50 50 50 190
y el resultado que se espera una vez ordenados debe ser:
nombre nacionalidad T1 T2 T3 T4 total
maria portuga 40 50 50 50 190
mario francia 20 50 58 35 163
oscar españa 30 20 40 48 138
pedro argentina 10 20 30 40 100
eso por una parte y otra cosita que te queria preguntar de paso en tu codigo como es que se puede hacer:
procedure ordenar(var car:carrera;tiempo:tiempos;numpart:integer);
...
...
Intercambiar (car[j], car[j+1]);
y en los argumentos de la funcion:
procedure Intercambiar (var a,b : atleta);
pones a, b de tipo atleta? es decir por que puedes hacer esto si lo que envias como parametros son dos variables de tipo carrera? me podrias explicar porque haces esto o por que se puede hacer? por tu ayuda mil mil gracias antonio
perdona antonio,y por supuesto ante todo un MIL GRACIAS POR TU TIEMPO Y AYUDA,pero creo que estas equivocado o no te entendi bien, en lo siguiente:
dices: "es el vector de atletas el que es de tipo carrera, pero cada uno de los campo de ese vector de atletas es un atleta."
y vamos creo que no es asi o corrigeme por favor, pues mis definiciones de tipo que te indique en el codigo inicial de este programa son:
type
cadena=string[30];
atleta=record
nombre,pais:cadena;
t:array[1..numpart] of integer;
end;
carrera=array[1..numpart] of atleta;
tiempos=array[1..numpart] of integer;
var
c:carrera;
como vez el vector carrera es el que es de tipo atleta,osea cada elemento del vector carrera tiene un registro de tipo atleta, entonces ahi es donde no entiendo como es que puedes hacer:
procedure ordenar(var car:carrera;tiempo:tiempos;numpart:integer);
...
...
Intercambiar (car[j], car[j+1]);
/** aqui estas pasando un tipo carrera pues car:carrera;****
y en los argumentos de la funcion:
tienes como argumentos a, b de tipo atleta, no deberia ser del mismo tipo con los que envie los parametros en la llamada al procedimiento??
procedure Intercambiar (var a,b : atleta);
...
es decir por que puedes hacer esto si lo que envias como parametros son dos variables de tipo carrera?
Hola otra vez,
Cuando tienes un array "v", la declaración "v[n]", donde "n" es una variable de tipo ordinal (byte, word, integer, char,...), a lo que te refieres es a la variable de la casilla, es decir:
En tu caso tienes un array con esta forma (gráfica):
--------------------------------------
| atleta 1 | atleta 2 |...| atleta n |
--------------------------------------
El array en sí es un vector de variables de tipo atleta, y cada componente/casilla/cuadradito es una variable de tipo atleta, que almacena unos valores determinados.
Así pues, en tu programa, "c" es una variable de tipo carrera, es decir, de tipo array de atletas (o lo que es lo mismo, del tipo vector de atletas), mientras que "c[2]", por ejemplo, es una variable de tipo atleta. Recuerda que atleta es un tipo, y no un valor.
Por cierto, un consejo con respecto a los tipos: cuando declares un tipo, procura poner una "t" delante (ejemplo: tAtleta, tcarrera,...). Hará más claro tu código :-).
¿Te valió la explicación?
Por cierto, ¿funciona el programa ya?
¡Ciao!
Hola antonio , mil gracias por tu ayuda ,ya he solucionado el programa gracias a tus extraordinarias ayudas,sin ti seguro no lo hubiese logrado,gracias por tu paciencia y tu tiempo por supuesto.
antonio una unica cosa que no me queda aun clara y es respecto a lo siguiente:
en el programa en sus definiciones hago:
CONST
numpart=4;
numvueltas=4;
TYPE
cadena=string[30];
atleta=record
nombre,pais:cadena:
... etc
...
VAR
c:carrera;
i,j:integer;
LAS VARIABLES I,J EN ESTE PUNTO SON GLOBALES VERDAD?
mi pregunta es si son globales, no debo por que definirlas dentro de los procedimientos verdad? sin embargo, si tengo el procedimiento porejemplo medallas:
procedure medallas(....);
var
aux:atleta;
begin
for i:=1 to numpart do
...
como ves dentro de este procedimiento utilizo la variable i, que no defino internamente ,pues si la i, del inicio del programa es global, aqui no necesitaria definirla, pero el caso es que si no la defino dentro del procedimiento ,no me da el resultado correcto.
en cambio si hago:
procedure medallas(....);
var
i:integer;
aux:atleta;
begin
for i:=1 to numpart do
...
en este caso si que me funciona ok ,no entiendo entonces si es que la i del inicio no es global, y por que si no lo fuera en el procedimiento donde no defino la variable i , internamente no me envia un error en compilacion, tratandome de decirme que la variable i del for no esta definida????
solo eso , por lo demas antonio el programa ya funciona, mil gracias.
Hola,
Utilizar variables globales no es aconsejable, y más si las vas a usar en los procedimientos que las siguen. Esto es porque puede resultar difícil "controlarlas", es decir, conocer sus valores a lo largo del programa.
Con respecto a lo de que te da un mal resultado si las utilizas como globales, puede ser porque las variables no estén almacenando los valores correctos. Ten en cuenta, que si están como globales, vas modificando sus valores a lo largo de las distintas ejecuciones de los procedimientos, y se quedan los valores. Entonces, si un procedimiento necesitase empezar con "i" igual a 5, pero la anterior ejecución la dejó en 4, no funcionará.
De todas formas, justo en la parte que tú dices no tiene mucho sentido que te diese error... Si quieres, cuelga el programa entero y le echo un vistazo, para ser más preciso.
Hay, sin embargo, una ocasión en la que sí me gusta utilizar variables globales, y es cuando hay que pasar a todos los procedimientos/funciones (o a varios de ellos) algún dato que no se conoce de antemano, y que por tanto no ha sido definido como constante (puesto que si conoces un dato invariable a priori, directamente se usa una constante).
Un ejemplo de esto puede ser la memoria total del ordenador. Imagina que tienes que utilizar el valor de la capacidad del disco duro del ordenador en varios procedimientos. Esta capacidad, no variará, pero sí puede ser diferente en cada PC, por lo que no puede ser una constante. Entonces declaras una variable (global) que almacene ese valor al comienzo del programa. ¿Ok?
¡Ciao!
Hola Antonio , mil gracias de nuevo.
vale entendi lo que me respondiste, intente subir el archivo pero me da error al subirlo no se porque, pero bueno que sepas que gracias a ti ya me funciona ok.
para que em quede mas clara tu teoria , lo siguiente es totalmente correcto?????:
program atletas;
uses crt;
const numpart=4;
numvueltas=4;
type
cadena=string[30];
atleta=record
nombre,pais:cadena;
t:array[1..numpart] of integer;
end;
carrera=array[1..numpart] of atleta;
tiempos=array[1..numpart] of integer;
var
c:carrera;
i,j:integer;
....
....
procedure ordenar(var car:carrera;var tiempo:tiempos;numpart:integer);
var
i,j:integer;
begin
for i:=1 to numpart-1 do
for j:=1 to numpart-i do
if tiempo[j]>tiempo[j+1] then
intercambiar(car[j],car[j+1]);
end;
....
es decir el i y el j de la declaracion externa al procedimeito son variables que me funcionan para los for que hago fuera para la lectura de datos , y el i,j dque defino dentro del procedimiento son locales y a pesar de que sean tambien i, j, solo pertenecen al procedimiento y no tienen nada que ver con el i,y el j externos, esto que te digo es correcto antonio?
la vez pasada tampoco le pude subir a Nacho el codigo, tan solo pude el ejecutable por que me decia que error creo que por limite de tamaño,él en su momento se lo comente.
gracias, gracias
Hola,
Pues ahora me haces dudar ante tu nueva pregunta... Es decir, si una variable es global, y luego la vuelves a declarar dentro de un procedimiento... no sé que pasa. Supongo que se "encapsula" dentro de dicho procedimiento y no afecta a la de afuera... ¿Tiene sentido? No sé, la verdad. Esto para Nacho, ja ja. Por eso no recomiendo el uso de globales... je je.
Bueno, de todas maneras como te dije en un mensaje anterior, tendrías que estructurarlo así:
---------------
program;
{Unidades}
{Constantes}
{Tipos}
{Subprogramas (programas y funciones)}
{Variables}
var
c : carrera;
begin
end.
---------------
Sin poner variables justo después de la declaración de tipos.
¡Ciao!
Efectivamente, si tienes una variable "i" global y otra variable "i" local, desde dentro de ese procedimiento sólo será accesible la variable local: la otra, como se llama igual, que inaccesible hasta que salgas del procedimiento.
Las variables "i" y "j", que se usan típicamente para recorrer bucles, NUNCA deberían ser globales.
Afinando un poco más, ni siquiera deberían existir variables que se llamen así, porque pueden dar lugar a errores de lógica difíciles de encontrar. Hoy en día, que los equipos tienen menos escasez de memoria que hace 25 años, no se debería hacer algo como
for i:=1 to n1 do
for j:=1 to n2 do
sino algo como
for filaActual := 1 to filaMaxima do
for columnaActual := 1 to columnaMaxima do
Esos 20 segundos (o dos minutos) que tardas de más en teclear el programa compensan sobradamente en legibilidad cuando lo relees, pero sobre todo cuando hay que depurar algún fallo, que puede hacerte perder horas en volver a pensar todo, si la lógica no es evidente.
(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)