PDA

Ver la Versión Completa : ¿¿¿Por mi culpa Bush Premio Nobel de la Paz???


axelbb
04-10-2006, 17:05:04
O: "Cuando la culpa la tuvo Delphi" :p

¡Amigos del foro, me ha pasado algo terrible!

Resulta que The Nobel Foundation me encargó hacerles un programa para elegir al Premio Nobel de la Paz. Como siempre, hay tantos candidatos que decidieron al final tirar un dado y el que sale... sale.

La cosa era ponerlos en una lista (una matriz) y cuando tiraran los dados, se debía elegir en un combo desplegable el valor obtenido, y el sistema automáticamente debería enviar a todas las agencias noticiosas del mundo simultáneamente la buena nueva.

Para ello, hice un programa como el que sigue. Por favor, inicien un nuevo proyecto, y en el form arrojen un ComboBox y un Button. En los ítems del ComboBox, pongan los números del dado, del 1 al 6, en su propiedad Style: "csDropDownList", e ItemIndex: 0.

En el evento Button1Click, vá lo siguiente (copien y peguen :rolleyes: ):


//**********************************************
procedure TForm1.Button1Click(Sender: TObject);
var
NoInvitar: Array[1..3] of String;
Candidatos: array[0..2] of string;
begin

NoInvitar[1] := 'Tony Blair';
NoInvitar[2] := 'George Bush';
NoInvitar[3] := 'Condolezza Rice';

Candidatos[0] := 'Nelson Mandela';
Candidatos[1] := 'Madre Teresa de Calcuta';
Candidatos[2] := 'Dalai Lama';

Try
ShowMessage('Y el ganador del Premio Nobel de la Paz es: ¡'+
Candidatos[ComboBox1.ItemIndex]+'!'+
#13+#13+'¡¡Se ha enviado este mensaje a todas las agencias '+
'noticiosas del mundo!!');
Except
ShowMessage('Fuera de rango. Reintente...');
end;

end;
//**********************************************


Me explico: Hace falta una lista de personajes que NO SE DEBEN INVITAR a la ceremonia, para evitar protestas y espectáculos bochornosos. En base a esa lista los organizadores deben tener especial cuidado de no invitar a esos personajes. Los puse en una matriz, llamada "NoInvitar".

Y para los candidatos, hice otra, "Candidatos". La idea es que al poner el valor del dado, se elige de la matriz "Candidatos" al ganador de la lista. Por supuesto, hay más números posibles que candidatos, así que protegí el acceso de errores mediante un Try...Except. Si ponen un valor más alto que los posibles de la lista, pedirá que reintenten, que tiren de nuevo el dado.

¿Todo Ok? Parece que sí, se los entregué y me senté a contar los jugosos 14.000 euros que me pagaron por esta obra de arte.

Cuando en la CNN ví la noticia que Bush era el nuevo Nobel de la Paz... ¡No lo podía creer! :eek: :eek: :eek: :eek: +:mad:

En el dado, había salido un 5. ¿No me creen? Hagan la prueba!!! Y que demanden a Borland...:p

Saludos, y cuidado con el acceso a arrays :D ...

defcon1_es
04-10-2006, 17:48:10
Pues si, suele pasar si no compilas el ejecutable con la opción {$R+},
para que tenga en cuenta los rangos...

RONPABLO
04-10-2006, 19:43:00
ups... y en q parte se pone esa opción?
pa no caer en el error

axelbb
04-10-2006, 19:53:35
Aqui:



var
Form1: TForm1;
implementation
{$R *.dfm}

{$R+}:)

procedure TForm1.Button1Click(Sender: TObject);

ContraVeneno
10-10-2006, 23:48:39
changos!

ahora, ¿me lo podrían explicar como si no supiera Delphi?

¿es un error? ¿un descuido? ¿o porque pasa eso?

roman
11-10-2006, 00:00:33
De hecho no es Bush quien ganaria, sino Condolezza Rice. La razón tiene que ver con el hecho de que ambos arreglos, NoInvitar y Candidatos, están declarados contiguamente. Supongo, que el compilador los acomoda primero Candidatos y luego NoInvitados, es decir, que en memoria se ven así:


Candidatos[0]
Candidatos[1]
Candidatos[2]
NoInvitados[1]
NoInvitados[2]
NoInvitados[3]


Al tomar Cadidatos[5], el compilador simplemente "va" a la dirección de memoria que corresponde, que, como se ve, vendría siendo la de NoInvitados[3].

Si no se declara NoInvitados, entonces Candidatos[5], apuntará a cualquier cosa y posiblemente venga un Access Violation.

// Saludos

axelbb
11-10-2006, 14:35:46
No, Roman.

De hecho, si hacés la prueba exactamente como la describo, con 5 sale Bush (lo que pasa es que adrede lo hice así, donde una es [0..2] y la otra [1..3] para usar el Itemindex del ComboBox; bueno no sé si se entiende).

Y si en vez del ComboBox, ponés un Edit, y le vas dando cualquier valor, empiezan a salir caracteres extraños. Accede a cualquier cosa de la memoria, pero no produce error de ningún tipo.

¿Les cuento cómo lo encontré? Viene un cliente y me dice que en un listado (hecho con QReport, donde en beforeprint le adjudico valores a algunos rótulos desde código), le sale para un producto determinado una característica imposible, por ejemplo, en Talle='Blanco'. Busqué y busqué, no tenía ningún sentido... Hasta que me acordé del {$R+}, que nunca había entendido para qué estaba (supuestamente, no hacía falta controlar rangos!, al menos para los que venimos de lenguajes más amables). ¡Ahora sé! :D

axelbb
11-10-2006, 14:49:44
changos!

ahora, ¿me lo podrían explicar como si no supiera Delphi?

¿es un error? ¿un descuido? ¿o porque pasa eso?

Para mí, no es nada de eso. Un lenguaje potente tiene que tener posibilidades, y entre ellas las de acceder a cualquier parte de la memoria, imagino. Para controlarlo existe una directiva especial para el compilador, como bien explica más arriba defcon1_es.

Lo que sí me parece, es que más bien debería controlar rangos por defecto, y desactivar con un switch cuando uno expresamente desee esa posibilidad. Sino, pasan cosas como éstas. Bueno, en realidad la culpa fue mía, por conocer superficialmente el lenguaje (como dije antes, había visto de pasada esa directiva de compilador, pero no le encontré mayor sentido y la olvidé).

Cosas que pasan cuando quienes no somos profesionales de la informática (me dedico a la consultoría de gestión de PyMEs) nos metemos con herramientas hechas pá los que saben.

roman
11-10-2006, 17:49:33
No, Roman.


Es sólo que conté mal, la explicación es correcta. Yo puse directamente Candidatos[5] pero el 5 en tu ComboBoxen realidad corresponde al ItemIndex 4.

// Saludos

axelbb
12-10-2006, 15:25:24
Si, eso.

Usé el itemindex en lugar de un StrToInt(ComboBox.Text) para acceder al elemento.

Pero no me digan que no es una divertida curiosidad que le puede sacar canas a cualquiera, ¿no? :p