Newsgroup: it.comp.lang.c
Titolo: from QBASIC to C (di nuovo!)

 7080
for (j=c+1;j<=c+at && !(b(j) && a(h,j)!=a(k,j));j++);
if (j>c+at && b(j)) {
    if (a(k,c+at+1) < d) contr++;
    else corr++;
}
Il mio problema ora è capire come posso generalizzare i salti del GOTO
e convertirli in C (ne ho un casino). Riprendo il pezzo originario:
            FOR k = 1 TO pop
7015         IF a(k, c + at + 1) = 0 THEN GOTO 7080
7020            FOR j = 1 TO c
7030                IF b(j) = 0 THEN GOTO 7050
7040                IF a(h, j) > a(k, j) THEN GOTO 7080
7050            NEXT j
7051            FOR j = c + 1 TO c + at
7052                IF b(j) = 0 THEN GOTO 7056
7055                IF a(h, j) <> a(k, j) THEN GOTO 7080
7056            NEXT j
7061         IF a(k, c + at + 1) < d THEN contr = contr + 1
7062         IF a(k, c + at + 1) >= d THEN corr = corr + 1
7080     NEXT k
Mi è chiaro il passaggio di conversione dei due cicli ma le linee 7040
e 7080 mi spiazzano. Come faccio a gestire il salto senza GOTO?
Un grazie sincero! Perdonate la "rospaggine"

 Un grazie sincero! Perdonate la "rospaggine"
Beh non conosco il qbasic, ma il programma originale l'hai scritto tu?
Comunque a riga 7040 per convertirlo in teoria dovresti fare
if a(h,j) < a(k,j) // inversione
   linee 7050-7080
else
   linee 7080...
certo che a giudicare da quel for faresti meglio a riscrivere tutto
secondo me evitando di tradurre da un linguaggio all'altro, ma non so se
è fattibile...

 wrote:

Il problema è che non ho chiaro l'algoritmo ed ho trovato solo questo
codice qbasic (non scritto da me) che fa il lavoro che mi interessa ma
prima vorrei capirlo bene. Purtroppo anche per me qbasic è piuttosto
sconosciuto

 sconosciuto
Ok non ti invidio...  Quel goto esce dal ciclo interno e prosegue quello
esterno se ho capito bene.Ti conviene prima capire cosa sono quelle a b
c k e j (e se trovi il genio che ha scritto questo codice insultalo pure
;)).
Fare del refactoring "innocuo" come rinominare le variabili in modo
sensato man mano che capisci potrebbe essere utile, o anche cercare di
capire dal risultato che caspita dovrebbe fare quell'orrendume potrebbe
aiutare...

 7080     NEXT k
for(k=1;k<=pop;k++) {
   if (a(k,c+at+1)==0) continue;
   for (j=1;j<=c && (b(j)==0 || a(h,j)<=a(k,j));++j);
   if (j>c) {
     for (;j<=c+at && (b(j)==0 || a(h,j)==a(k,j));++j);
     if (j>c+at) {
       if (a(k,c+at+1) < d) contr++;
       if (a(k,c+at+1) >=d) corr++;
     }
   }
}
Comunque, per informazione, in C puoi usare il goto.
E.

 > Il mio problema ora è capire come posso generalizzare i salti del GOTO

Grazie, davvero.
Riguardo al GOTO è vero, posso usarlo ed in realtà un file generato da
bcx funzionante con una marea di GOTO l'ho ottenuto e, dopo tutto,
funziona. Il mio problema è che voglio capire con esattezza come il
codice lavora (circa 500 linee di qbasic). Il qbasic non lo conosco e
in C non è che sia un guru (tutt'altro!); con tutti i GOTO che mi
ritrovo esco matto (nonostante i numerosi tentativi fatti, compreso
quello di disegnare un flowchart come mi era stato consigliato in
passato).
Grazie ancora!

 Grazie ancora!
beh lì c'è poco da capire, ci sono dei for con dei goto, devi capire il
contorno piuttosto...
Ma fammi capire, quel codice è stato scritto da un umano?
Mi domando come caspita si faccia a mettere dei salti a numeri di linee,
non credo che non si possa mettere in labels in Qbasic se proprio vuoi
saltare.
Che fa quando aggiunge una linea modifica tutti gli indirizzi dei salti?

 wrote:

Guarda sto diventando matto! Non so se chi ha scritto è umano, a me è
stato passato  per poterci ricavare l'algoritmo perchè, non ho capito
come, il lavoro che deve fare lo fa (è algoritmo di analisi
multicriteri). Non sono un programmatore professionale ma nel mio
percorso di studio devo completare questo lavoro e comincio a non
dormirci la notte!

 dormirci la notte!
Insomma ricavare l'algoritmo da codice altrui non è mai il massimo, in
teoria hai
- un problema
- una soluzione
Cerca di scrivere tu il codice per risolverlo, vedrai che riuscirai poi
a capire pure quella schifezza...
(anche in python magari che è molto più semplice)

 (anche in python magari che è molto più semplice)
Quella del python potrebbe essere un'idea, il problema è che non
avendo conoscenze approfondite di programmazione vorrei concentrarmi
su una strada per evitare di perdermi.
Grazie comunque, lo scambio di idee su questo gruppo è sempre
estremamente utile, per non parlare degli aiuti!

 Che fa quando aggiunge una linea modifica tutti gli indirizzi dei salti?
Per ogni riga infatti si usavano dei multipli di 10:
7020            FOR j = 1 TO c
7030                IF b(j) = 0 THEN GOTO 7050
7040                IF a(h, j) > a(k, j) THEN GOTO 7080
7050            NEXT j
se fosse stato necessario inserire una riga o pi� la si numerava con un 
numero intermedio.
Si possono usare anche le label, ma le prime versioni di basic 
utilizzavano i salti in quella maniera li. Tieni conto che il basic � 
pi� vecchio del c.

 Che fa quando aggiunge una linea modifica tutti gli indirizzi dei salti?
Ecco, comincio a sentirmi vecchio... le persone non conoscono più il 
buon vecchio Basic (che, concordo, era una schifezza di linguaggio).
E.

 estremamente utile, per non parlare degli aiuti!
Scaricati questo
http://ipython.scipy.org/moin/
e vedrai che programmare sarà una pacchia.
Da quello che ho capito non ti serve molto, ti serve solo capire come
funziona la programmazione strutturata e qualche algoritmo, per farlo
devi fare parecchi esperimenti, e un interprete intelligente è il modo
migliore per farlo ;)

 migliore per farlo ;)
Scaricato!
Grazie ancora

Finchè avrete la pazienza di rispondermi ne approfitterò!
Continuo con il lavoro di conversione from QBASIC to C e ho due
domande:
a. la prima è se, secondo voi, la "traduzione" così come l'ho
impostato funzione
questo è il QBASIC
8000 FOR h = 1 TO pop
8010     IF lower(h) < csoglia THEN GOTO 12380
8020     FOR t = 1 TO rule
8030         FOR j = 1 TO c
8040             IF b(j) = 0 AND rulea(t, j) = 1000 THEN GOTO 8070
8050             IF b(j) = 0 THEN GOTO 8090
8055             IF rulea(t, j) = 1000 THEN GOTO 8070
8060             IF rulea(t, j) > a(h, j) THEN GOTO 8090
8070         NEXT j
8071         FOR j = c + 1 TO c + at
8072             IF b(j) = 0 AND rulea(t, j) = 1000 THEN GOTO 8076
8073             IF b(j) = 0 THEN GOTO 8090
8074             IF rulea(t, j) = 1000 THEN GOTO 8076
8075             IF rulea(t, j) <> a(h, j) THEN GOTO 8090
8076         NEXT j
8080         IF credrul(t) >= lower(h) THEN GOTO 12380
'label di fine ciclo cin NEXT h
8090     NEXT t
Questo è il codice C:
for(h=0;h<pop && !(lower[0]>csoglia);h++) {
    for(t=0;t<rule;t++)        {
        for(j=0;j<c && ((b[j]==0 && rulea[t][j]==1000)|| (b[j]!=0)||
(rulea[t][j]==1000) || (rulea[t][j] <=a[h][j]));++j);
        if(j>=c)    {
                    for(;j<c+at && ([b[j]==0 && rulea[t][j]==1000)||
(b[j]!=0)|| (rulea[t][j]==1000) || (rulea[t][j] <=a[h][j]));++j);
                    if(j>=(c+at)) {
                        if(credrul[t] >= lower[h])  {
                                /*GOTO fine ciclo  h var*/
                                                    }
                                    }
                        }
        }
b. la secondo è un consiglio: come faccio a inserire nel codice C  il
GOTO finale che in qbasic è alla linea 8080?
Grazie ancora
geo

 GOTO finale che in qbasic è alla linea 8080?
1. 
!(lower[0]>csoglia) -> (lower[0] <= csoglia)
1. se devi tradurre approfitta per scrivere in modo vagamente
   comprensibibile, io perlomeno non mi ci metto a leggere
   quest'obbrobrio (senza offesa).

 GOTO finale che in qbasic � alla linea 8080?
break;
E.

 E.
Scusa, è che non sono stato chiaro:
il break termina il ciclo, la linea a cui rimanda 8080 è questa:
12380 NEXT h
dunque ho un mega ciclo che fa così:
8000 FOR h = 1 TO pop
[....]
8020     FOR t = 1 TO rule
[....]
8080         IF credrul(t) >= lower(h) THEN GOTO 12380
[.....]
8090     NEXT t
[.....]
12380 NEXT h


scusa ?manu*, è come dici tu, come solito la tua indicazione era
corretta e pertinente!
grazie

 for(h=0;h<pop && !(lower[0]>csoglia);h++) {
tanto per rimanere fedeli al codice iniziale, avrei scritto:
for(h=1;h<=pop;h++)
{
    if(lower(h) < csoglia) break;
    //...
}
Ciao Jack

Devo riconoscere che alla fine, anche senza tutti i GOTO del codice
originario, non è che la leggibilità del codice sia cambiata
radicalmente (come qualcuno di voi mi aveva suggerito!) ma almeno sto
capendo l'algoritmo mettendo insieme i vari pezzi. Proprio riguardo a
questi "pezzi" avrei da chiedervi un'altro aiuto:
il codice di un ciclo qbasic (riportato sotto da 12230 a 12350) lo
convertito
12230    FOR l = 1 TO pop
12240        IF a(l, c + at + 1) = 0 THEN GOTO 12350
12250        FOR j = 1 TO c
12255            IF rulea(rule, j) = 1000 THEN GOTO 12280
12260            IF a(l, j) = 1000 AND a(l, c + at + 1) < d THEN nn =
nn + 1: GOTO 12350
                 IF a(l, j) = 1000 AND a(l, c + at + 1) >= d THEN np =
np + 1: GOTO 12350
12270            IF rulea(rule, j) > a(l, j) AND a(l, c + at + 1) < d
THEN nn = nn + 1: GOTO 12350
                 IF rulea(rule, j) > a(l, j) AND a(l, c + at + 1) >= d
THEN np = np + 1: GOTO 12350
12280        NEXT j
12290        FOR j = c + 1 TO c + at
12295            IF rulea(rule, j) = 1000 THEN GOTO 12320
12300            IF a(l, j) = 1000 AND a(l, c + at + 1) < d THEN nn =
nn + 1: GOTO 12350
                 IF a(l, j) = 1000 AND a(l, c + at + 1) >= d THEN np =
np + 1: GOTO 12350
12310            IF rulea(rule, j) <> a(l, j) AND a(l, c + at + 1) < d
THEN nn = nn + 1: GOTO 12350
                 IF rulea(rule, j) <> a(l, j) AND a(l, c + at + 1) >=
d THEN np = np + 1: GOTO 12350
12320        NEXT j
12340        IF a(l, c + at + 1) < d THEN pn = pn + 1
             IF a(l, c + at + 1) >= d THEN pp = pp + 1
12350    NEXT l


Segue dal precedente post:
Il codice in C che ho provato a scrivere è questo:
    for(l=0;l<pop && (a[l][c+at+1]!=0);l++)  { /*12230*/
            for(j=0;j<c && rulea[rule][j]==1000;j++j)  {
                if(a[l][j[==1000 && a[l][c+at+1]<d) {
                    nn++;
                    break;  }
                if(a[l][j]==1000 && a[l][c+at+1]>=d)    {
                    np++;
                    break; }
                if(rulea[rule][j] > a[l][j] && a[l][c+at+1]<d)  {
                    nn++;
                    break;  }
                if(rulea[rule][j] > a[l][j] && a[l][c+at+1]>=d)  {
                    np++;
                    break;  }
            }
            if(j>=c)    {
                for(;j<(c+at) && rulea[rule][j]==1000);++j) {
                if(a[l][j[==100 && a[l][c+at+1]<d) {
                    nn++;
                    break;  }
                if(a[l][j]==1000 && a[l][c+at+1]>=d)    {
                    np++;
                    break; }
                if(rulea[rule][j] > a[l][j] && a[l][c+at+1]<d)  {
                    nn++;
                    break;  }
                if(rulea[rule][j] > a[l][j] && a[l][c+at+1]>=d)  {
                    np++;
                    break;  }
            }
    }
if(a[l][c+at+1]<d)
    pn++;
if(a[l][c+at+1]>=d)
    pp++;
}            /*12350*/
So che c'è almeno un erorre logico dovuto al fatto che i break non
escono dal ciclo principale (per andare al punto 12350) ma solo dal
ciclo interno. Come posso intervenire per correggere l'errore?
Grazie ancora a chi vorrà aiutarmi
Geo

> convertito
Non è decisamente quello che intendevo ;)
Riscrivere significa rendere più modulare, prendere una schifezza lunga
una pagina e dividerla in 10 funzioni lunghe 1/5 di pagina che fanno UNA
sola cosa e la fanno bene.
Se traduci letteralmente è chiaro che non cambia nulla...

 Se traduci letteralmente è chiaro che non cambia nulla...
Mi dispiace non essere stato chiaro! E' esattamente come dici tu. Ero
stato avvertito che non dovevo tradurre ma riscrivere e per ora ho
solo tradotto (forse neanche troppo bene). Il fatto è che per studiare
un linguaggio, dopo avere fatto gli esercizi proposti su un libro di
testo ho bisogno di misurarmi su un progetto che ha una qualche
utilità pratica. In questo caso, oltre a cercare di comprendere
l'algoritmo sto approfondendo i cicli e le condizioni con gli
operatori logici. Il prossimo passo sarà quello di migliorare lo stile
e la leggibilità del codice. E un lavoro che penso debba essere fatto
a passi successivi (per approssimazioni successive).
Il tutto sarà possibile se potrà contare ancora sul vostro aiuto
geo

 geo
Non ho proprio mai sentito che per imparare a programmare si debba
tradurre codice schifoso da altri linguaggi :D
La traduzione è un lavoro palloso e inutile, piuttosto scrivi un
programma che la faccia ;)
Dovresti scrivere qualcosa di tuo piuttosto, ad esempio risolvendo
qualcuno di questi
http://projecteuler.net/

 wrote:

Grazie del suggerimento che seguirò senza dubbio. Io ho l'esigenza di
comprendere quell'algoritmo e farlo funzionare come codice C. Nel
frattempo colgo l'occasione per imparare a programmare, risolvendo in
C quello che è stato risolto in qbasic. Ma prima devo capire quello
che fa il qbasic. Se sembra una cosa da pazzi ti assicuro che non lo
è. Per me è importante ed utile

..... sono cosciente del fatto che ho tanto da imparare ma ho anche
tanta voglia di farlo e, finchè sarà possibile, continuerò a chiedere
a chi ne sa più di me.
grazie comunque.
geo

 ciclo interno. Come posso intervenire per correggere l'errore?
Ingloba il ciclo in una funzione e usa return invece di break;
E.

 buon vecchio Basic (che, concordo, era una schifezza di linguaggio).
Ma no... venti anni fa ci giocai tanto. Ma *oggi* non mi ricorderei una
favazza. ;)
Sono vent'anni, e quando una cosa va contro la mia logica... diciamo che
parte il garbage collector.
-- 
-riko

 E.
Grazie
Funziona!