[ Foro de Pascal ]

error duplicate identifier(cont)...

10-Jul-2011 15:38
oscar gomez
17 Respuestas

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.






 


10-Jul-2011 16:39
Antonio P.G.

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!


10-Jul-2011 18:54
oscar gomez

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.


10-Jul-2011 20:37
Antonio P.G.

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!


11-Jul-2011 12:48
oscar gomez

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!!!
 


11-Jul-2011 16:41
Antonio P.G.

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!


11-Jul-2011 17:07
oscar gomez

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


11-Jul-2011 17:46
oscar gomez

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


11-Jul-2011 17:59
Antonio P.G.

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!


11-Jul-2011 20:37
Antonio P.G.

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!


11-Jul-2011 20:38
oscar gomez

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


11-Jul-2011 21:03
oscar gomez

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?


11-Jul-2011 21:59
Antonio P.G.

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!


12-Jul-2011 12:02
oscar gomez

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.


12-Jul-2011 13:57
Antonio P.G.

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!


12-Jul-2011 16:58
oscar gomez

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


12-Jul-2011 20:01
Antonio P.G.

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!


13-Jul-2011 10:32
Nacho Cabanes (+84)

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.)