Autore Topic: [Risolto]Dichiarazioni di array globali  (Letto 3199 volte)

Offline Franco_da_vc

  • Grande Gambero
  • ***
  • Post: 215
  • Non è mai troppo tardi!
    • Mostra profilo
[Risolto]Dichiarazioni di array globali
« il: 30 Marzo 2012, 22:53:39 »
Riposto qui l'evidenziazione dell'ultimo mesaggio del topic "Le costanti queste sconosciute..........." perchè giustamente come mi aveva fattto notare Vuott non centrava col topic e siccome il nuovo argomento non mi pare essere esaurito è meglio che lo continui così.

============================================================


Se invece la dichiarazione la metto nella main procedure otterrò un'array globale che poi ridimensionerò nella procedura a mio piacere......
Funziona?


Fai la prova tu stesso !

"Provar non nuoce !" ...nuoce non provar !

Ho fatto una prova, ma i risultati che ho ottenuto mi stanno un po' inducendo in confusione e quindi preferisco realizzare una discussione con voi.

Alura..... ho dichiarato a livello globale due vettori: clienti1$ e clienti2$ con questa istruzione: PUBLIC clienti1$ AS String[], naturalmente anche per la seconda espressione, poi all'interno della PROCEDURE LETTURA_FILE_CLIENTI ho dimensionato i due array con questa istruzione: clienti1$ = NEW String[num] e la seconda matrice: clienti2$ = NEW String[num, 6].

Nel mio progetto infatti il vettore clienti1$ è monodimensionale mentre clienti2$ è bidimensionale, ora il problema stà proprio in questa diversità: il primo funziona a dovere, mentre il secondo, a quanto pare, no! E se lo interrogo mi restituisce per i primi 5 elementi (num nell'elelaborazione di prova è pari a 5) il messaggio "Bad number of dimension" per i restanti "Out of bounds", quasi come se fosse impossibile dimensionare array pluridimensionali (francamente lo troverei un po strano).

Voi che mi dite?

Grazie.
« Ultima modifica: 05 Aprile 2012, 23:19:53 da Franco_da_vc »
Bye by Afo

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #1 il: 31 Marzo 2012, 00:07:21 »
Andando con ordine:
Citazione
ho dichiarato a livello globale due vettori: clienti1$ e clienti2$ con questa istruzione: PUBLIC clienti1$ AS String[], naturalmente anche per la seconda espressione.
poi all'interno della PROCEDURE LETTURA_FILE_CLIENTI ho dimensionato i due array con questa istruzione: clienti1$ = NEW String[num] e la seconda matrice: clienti2$ = NEW String[num, 6]

Ma dove? In un modulo, fra le dichiarazioni di una Form, Dentro una classe dinamica?
 Potresti postare la codifica di quanto hai scritto ? Si capirebbe meglio.

Citazione
Relativamente agli array, secondo me, potevi scrivere:
Codice: [Seleziona]
a) Dim  clienti1$ = NEW String[] oppure
b) Dim  clienti1$ =  String[num], essendo num= Numero totale degli elementi dell'array.

Dim clienti2$ = String[num, 6]  Anche qui num rappresenta il numero complessivo delle righe dell'array, mentre 6 è il numero delle colonne di cui si compone ciascuna riga.
Quando però indirizzi un elemento per il caricamento dovresti:

per aggiungere un elemento in clienti1$:
Codice: [Seleziona]
a) client1$.add $Valore
b) for i = 0 to num-1      '0<i<num-1  perchè contando da 0 a num-1 il totale fa num.
        client1$[i]=$Valore
    next
per aggiunger un elemento in clienti2$:
Codice: [Seleziona]
for iRiga = 0 to num-1
 for iColonna = 0 to 5
     CaricaNuovoValore($Valore)
     clienti2$[iRiga, iColonna] = $Valore
 next
next
:ciao:
:ciao:

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #2 il: 31 Marzo 2012, 00:30:05 »
Citazione
....e la seconda matrice: clienti2$ = NEW String[num, 6]
Ricordo a me stesso che, avendo segnato 6, se il conteggio lo faccio partire da 0, si deve fermare a 5.


Relativamente agli array, secondo me, potevi scrivere:
Concordo con Picavbg: grossi problemi non ve ne sono.
Esempio simile al suo:
Codice: gambas [Seleziona]

Public clienti1$ As String[]
Public clienti2$ As String[]

Public Sub Form_Open()

 Dim num As Byte = 5
 Dim j As Byte
 Dim calculus As String

  clienti1$ = New String[num]

  clienti2$ = New String[num, 6]
 
' il totale delle unità di num non deve
' essere superiore a 5:
  For num = 0 To 4
' il totale delle unità di j non deve
' essere superiore a 6:
    For j = 0 To 5
      clienti2$[num, j] = Str(num & " " & j)
    Next
  Next

  For Each calculus In clienti2$
    Print calculus
  Next
 
End
« Ultima modifica: 31 Marzo 2012, 00:35:57 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Franco_da_vc

  • Grande Gambero
  • ***
  • Post: 215
  • Non è mai troppo tardi!
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #3 il: 31 Marzo 2012, 12:56:02 »
Grazie per le risposte,

dunque, le dichiarazioni iniziali sono, e si vede nella citazione, all'inizio della main.class, mentre il resto del codice è inserito in un una procedura a se stante e non in un form open, ma questo non penso che possa rappresentare un problema, una diversità che invece può essere sostanziale è la dichiarazione dei puntatori: io infatti li avevo dichiarati integer mentre vedo che sono dichiarati come byte... in totale il mio codice è così:

Codice: gambas [Seleziona]

PUBLIC clienti1$ AS String[] '##### 1° array dati clienti - Nome ditta
PUBLIC clienti2$ AS String[] '##### 2° array dati clienti - Dati ditta


PUBLIC tot_cli AS Integer '##### numero totali di clienti visualizzati

PUBLIC SUB _new()

  assegnazioni()

END

PUBLIC SUB assegnazioni()

  LETTURA_FILE_CLIENTI(tot_cli)

END

PUBLIC PROCEDURE LETTURA_FILE_CLIENTI(num AS Integer)

  DIM clienti1_tmp$ AS String '##### Variabile navetta - Nome ditta
  DIM clienti2_tmp$ AS NEW String[] '##### Array navetta - Dati ditta

  DIM i AS Integer '##### puntatore numero del record
  DIM j AS Integer '##### Puntatore numero del campo
  DIM y AS Integer '##### Puntatore alternativo numero del record
  DIM num_rec AS Integer '##### Numero totale dei record

    clienti1$ = NEW String[num]
    clienti2$ = NEW String[num, 6]
    clienti2_tmp$ = NEW String[6]

    FOR i = 0 TO num_rec - 1


        clienti1$[y] = clienti1_tmp$
        FOR j = 0 TO 5
          clienti2$[y, j] = clienti2_tmp$[j]
        NEXT
        y = y + 1

    NEXT

END


Questo è il codice interessato, non lo trovo tanto distante da quello che avete postato voi, il problema e che persiste il malfunzionamento che vi ho segnalato.

Ciao a tutti.



Bye by Afo

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #4 il: 31 Marzo 2012, 15:23:37 »
Vediamo un pò  :coder: . Cominciamo dalla cosa più facile:
Citazione
una diversità che invece può essere sostanziale è la dichiarazione dei puntatori: io infatti li avevo dichiarati integer mentre vedo che sono dichiarati come byte...
vuott ha dichiarato la variabile num come byte, probabilmente per risparmiare  lo spazio da occupare in memoria o  per sua abitudine. Il tipo variabile byte infatti occupa in memoria solamente 8 bit, ciioè un byte, mentre il tipo variabile integer occupa in memoria 16 bit, cioè 2 byte, ma non è obbligatorio utilizzare il tipo byte. Io, per mia abitudine, preferisco dichiarare gli indici degli array sempre come  integer ed includo, come prilma lettera del nome variabile la  "i", perchè così mi viene più facile e comodo riconoscerli.

Passiamo ora al codice:
 
Citazione
Codice: gambas [Seleziona]
clienti1$ = NEW String[num]  
   clienti2$ = NEW String[num, 6] 
   clienti2_tmp$ = NEW String[6] 
 
   FOR i = 0 TO num_rec - 1 
 
 
       clienti1$[y] = clienti1_tmp$ 
       FOR j = 0 TO 5 
         clienti2$[y, j] = clienti2_tmp$[j] 
       NEXT 
       y = y + 1 
 
   NEXT 


La riga 08 (clienti1$[y] = clienti1_tmp$ ) valorizza l'elemento y dell'array clienti1$ che è dimensionato ad 1 solo elemento, perchè num, nel codice che hai postato, non viene  mai incrementato o riempito. Quindi, secondo quello che si legge, dopo il primo ciclo di loop, l'array è già finito e non può essere ulteriormente valorizzato. Probabilmente dovresti sostituire num con num_rec, ma anche quest'ultimo non riceve mai un valore.

Citazione
Codice: [Seleziona]
PUBLIC SUB assegnazioni()  
 
 LETTURA_FILE_CLIENTI(tot_cli) 
 
END 
Secondo me, la SUB  LETTURA_FILE_CLIENTI non dovrebbe essere una SUB, ma una Function in modo da farti ritornare anche il totale dei record contenuti nel file clienti:
Codice: [Seleziona]
PUBLIC FUNCTION LETTURA_FILE_CLIENTI(TotRec as integer)
Dim iToReCli as integer
' ?????, a proposito il File Clienti che file è? Un file di testo, o cos'altro?
    ......bla......bla......bla......
    Return(iToReCli)
END

Vorrei dirti di più, ma ancora il tuo codice contiene applicati pochi concetti. Quindi partiamo da questo poco e piano piano costruiremo l'intero edificio.
Potresti, secondo me, prima di dedicarti alla gestione del file clienti, concentrarti sul codice scritto fino ad ora e fare funzionare quello. Allora potresti simulare che il file contenga, per esempio, 10 record e valorizzare quindi:
Codice: [Seleziona]
 DIM num_rec AS Integer = 10        '##### Numero totale dei record  
 DIM num AS Integer = 10

Aggiusta il programma tenendo conto di quello che ci siamo detti per ora. Dopo averlo fatto funzionare così, passiamo, se vuoi, al trattamento del file clienti.  ;)
 :ciao:  :ciao:
:ciao:

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #5 il: 31 Marzo 2012, 16:27:00 »
vuott ha dichiarato la variabile num come byte, probabilmente per risparmiare  lo spazio da occupare in memoria...

 :D  appunto, è così.  :ciao:
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Franco_da_vc

  • Grande Gambero
  • ***
  • Post: 215
  • Non è mai troppo tardi!
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #6 il: 31 Marzo 2012, 23:15:23 »
Effettivamente Picavbg ti devo delle spiegazioni supplimentari, perchè le tue obiezioni che hai mosso sono sensate, ma c'è perti della procedura che io non ho pubblicato che mutano del tutto la logica che tu presumi abbia il mio listato:

Tra la linea 27 e la linea 29 c'è una parte di codice molto significativa che va ad analizzare il file (li non si vedeva "CLIENTINEW.dat") ed alla fine la variabile num ha un valore ben determinato, nella prova che ho eseguito per esempio era 5; la variabile num_rec non deriva da un calcolo o da un conteggio, ma è scritto direttamente all'inizio del file e comunque è il totale dei record contenuti; num alla fine del codice che ti dicevo sopra contiene invece il totale dei record validi da visualizzare, e questa informazione è scritta nell'ultimo carattere di ogni record.

Dalla riga 33 in poi il codice legge nell variabile e negli array _tmp$ I record del file e poi li passa nella matrice definitiva solo se il record è valido e deve essere visualizzato, oltretutto non lo avevo postato ma nel codice esiste un secondo vettore serv$ che contiene sempre dati del file.

Per maggiore chiarezza ti posto quindi la routine completa:

Codice: gambas [Seleziona]

PUBLIC PROCEDURE LETTURA_FILE_CLIENTI(num AS Integer)
'########################################################################## PROCEDURA LETTURA FILE ELENCO CLIENTI #####
  DIM ch_file AS File '##### Identificatore del file
  DIM clienti1_tmp$ AS String '##### Variabile navetta - Nome ditta
  DIM clienti2_tmp$ AS NEW String[] '##### Array navetta - Dati ditta
  DIM serv_tmp$ AS NEW String[] '##### Array navetta - Dati di servizio per il programma
  DIM filler$ AS String '##### Lettura dati non usabili
  DIM buffer$ AS String '##### Lettura diretta di un record
  DIM visione$ AS String '##### Determinazione record da visualizzare
  DIM i AS Integer '##### puntatore numero del record
  DIM j AS Integer '##### Puntatore numero del campo
  DIM y AS Integer '##### Puntatore alternativo numero del record
  DIM num_rec AS Integer '##### Numero totale dei record

  ch_file = OPEN _base & "CLIENTINEW.dat" FOR READ
  INPUT #ch_file, filler$
  INPUT #ch_file, num_rec
  num = 0
  y = 0
  IF num_rec <> 0 THEN
    FOR i = 1 TO num_rec
      FOR j = 1 TO 13
        LINE INPUT #ch_file, filler$
      NEXT
      visione$ = ESTRAI(filler$)
      IF visione$ = "1" THEN
        num = num + 1
      END IF
    NEXT
    CLOSE #ch_file
    clienti1$ = NEW String[num]
    clienti2$ = NEW String[num, 6]
    serv$ = NEW String[num, 6]
    clienti2_tmp$ = NEW String[6]
    serv_tmp$ = NEW String[6]
    ch_file = OPEN _base &/ "CLIENTINEW.dat" FOR READ
    INPUT #ch_file, filler$
    INPUT #ch_file, filler$
    FOR i = 0 TO num_rec - 1
      LINE INPUT #ch_file, buffer$
      clienti1_tmp$ = ESTRAI(buffer$)
      FOR j = 0 TO 5
        LINE INPUT #ch_file, buffer$
        clienti2_tmp$[j] = ESTRAI(buffer$)
      NEXT
      FOR j = 0 TO 5
        LINE INPUT #ch_file, buffer$
        serv_tmp$[j] = ESTRAI(buffer$)
      NEXT
      IF serv_tmp$[5] = "1" THEN
        clienti1$[y] = clienti1_tmp$
        FOR j = 0 TO 5
          clienti2$[y, j] = clienti2_tmp$[j]
        NEXT
        FOR j = 0 TO 5
          serv$[y, j] = serv_tmp$[j]
        NEXT
        y = y + 1
      END IF
    NEXT
  END IF
  CLOSE #ch_file

END


Un'ultima cosa: riflettendo l'obiezione che mi muovi sul fatto di tramutare la procedure in function effettivamente è molto condivisibile, la variabile num all'esterno tot_cli in entrata non prevede valori ma solo essere dichiarata mentre restituisce poi il totali dei rekord visualizzati e quindi la function è senz'altro più che giustificata.

Ciao a tutti e saluti.
Bye by Afo

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #7 il: 01 Aprile 2012, 16:00:22 »
Io utilizzo raramente file sequenziali, per cui non ne conosco benissimo la metodologia più opportuna di gestione. Ho letto comunque la tua routine di lettura del file sequenziale ed ho notato che non contiene un controllo di sicurezza sull'esistenza del file, a meno che tu non lo faccia altrove.
Poi ho visto che apri più volte il file. Credo di capire che la prima volta lo fai, dopo avere valorizzato num-rec, solamente allo scopo di determinare il numero di record validi:
Codice: [Seleziona]
 FOR i = 1 TO num_rec   
     FOR j = 1 TO 13                  ==> 13 dovrebbero sono i campi interni a  ciascun record, vero ?
       LINE INPUT #ch_file, filler$ 
     NEXT 
     visione$ = ESTRAI(filler$) 
     IF visione$ = "1" THEN 
       num = num + 1                 ==> hai trovato un record valido
     END IF 
   NEXT 
   CLOSE #ch_file 
In realtà vi manca il controllo del fine-file (EOF), però se sei sicuro del contenuto di num-rec, va bene anche così.

Stabilito questo, perchè non mi pare sia il caso di approfondire, per ora la funzione di lettura file, ritornerei al problema di partenza:
Citazione
Codice: [Seleziona]
For num = 0 To 4  
' il totale delle unità di j non deve 
' essere superiore a 6: 
   For j = 0 To 5 
     clienti2$[num, j] = Str(num & " " & j) 
   Next 
 Next 
 
 For Each calculus In clienti2$ 
   Print calculus 
 Next 
poi aggiungi:
Citazione
il vettore clienti1$ è monodimensionale mentre clienti2$ è bidimensionale, ora il problema stà proprio in questa diversità: il primo funziona a dovere, mentre il secondo, a quanto pare, no! E se lo interrogo mi restituisce per i primi 5 elementi (num nell'elelaborazione di prova è pari a 5) il messaggio "Bad number of dimension" per i restanti "Out of bounds", quasi come se fosse impossibile dimensionare array pluridimensionali (francamente lo troverei un po strano).
nella documentazione ufficiale di Gambas l'errore  "Bad number of dimension" fa presente che
Si tenta di accedere a un array, indicando una serie di indici diverso dal numero di dimensioni della matrice.

Cosa intendi per "se lo interrogo"?
Citazione
For Each calculus In clienti2$  o altro?

Proviamo a farci dire dallo stesso Gambas quanti elementi sono dentro a  clienti2$[num, j] subito dopo la sua creazione:
Codice: [Seleziona]
PUBLIC PROCEDURE LETTURA_FILE_CLIENTI(num AS Integer)  
....bla....bla....bla....
clienti2$ = NEW String[num, 6] 
print num
print clienti2$.count
....bla....bla....bla....
END
Se è come ti aspetti, dovresti anche dirmi come ottieni calculus.
 :ciao:
:ciao:

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #8 il: 01 Aprile 2012, 16:58:56 »
Questo è il codice interessato, non lo trovo tanto distante da quello che avete postato voi, il problema e che persiste il malfunzionamento che vi ho segnalato.


...perché alla variabile tot_cli non passi alcun valore e quindi resta  = zero; la qual cosa comporta conseguentemente che anche la variabile num è zero, e clienti2$ si ritrova un elemento pari a zero !


Comunque, una domanda relativa all'intero listato di codice che hai allegato:
PUBLIC PROCEDURE LETTURA_FILE_CLIENTI(num AS Integer)

  DIM ch_file AS File
  DIM ...... etc etc
  etc etc

  ch_file = OPEN _base & "CLIENTINEW.dat" FOR READ
  INPUT #ch_file, filler$
  INPUT #ch_file, num_rec
  num = 0
  ..... etc etc

perché alla variabile num prima passi un valore  con LETTURA_FILE_CLIENTI(num AS Integer), e poi lo azzeri:  num = 0 ?  ???

...non ho... capito...
« Ultima modifica: 01 Aprile 2012, 17:15:44 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Franco_da_vc

  • Grande Gambero
  • ***
  • Post: 215
  • Non è mai troppo tardi!
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #9 il: 01 Aprile 2012, 18:01:26 »
Ho letto comunque la tua routine di lettura del file sequenziale ed ho notato che non contiene un controllo di sicurezza sull'esistenza del file, a meno che tu non lo faccia altrove.
E' vero, non lo controllo perchè questo file fa parte dei file di controllo del programma e senza di esso non avrei i dati per stampare l'indirizzo sulla bolla, infatti il programma mi serve per emettere bolle di accompagnamento

Citazione
Poi ho visto che apri più volte il file. Credo di capire che la prima volta lo fai, dopo avere valorizzato num-rec, solamente allo scopo di determinare il numero di record validi:
Codice: [Seleziona]
 FOR i = 1 TO num_rec   
     FOR j = 1 TO 13                  ==> 13 dovrebbero sono i campi interni a  ciascun record, vero ?
       LINE INPUT #ch_file, filler$ 
     NEXT 
     visione$ = ESTRAI(filler$) 
     IF visione$ = "1" THEN 
       num = num + 1                 ==> hai trovato un record valido
     END IF 
   NEXT 
   CLOSE #ch_file 
Vere entrambi le osservazioni num_rec contiene il numero totale dei rekord registrati nell'archivio mentre il conteggio num mi restituisce quanti rekord validi ci sono; inoltre come dici tu ogni rekord contiene 13 campi interni: uno viene memorizzato nella matrice clienti1$ (che è monodimensionale di x rekord), i secondi sei vengono inseriti nella matrice clienti2$ (bidimensionale, pari numero di record, 6 campi) e gli ultimi 6 campi vanno nella matrice serv$ (sempre bidimensionale, sempre pari numero di rekord e sempre 6 campi)

Citazione
In realtà vi manca il controllo del fine-file (EOF), però se sei sicuro del contenuto di num-rec, va bene anche così.
In effetti il file CLIENTINEW.dat viene mantenuto da un secondo programma a se stante che si tiene calcolo del numero di rekord che stà gestendo e lo va a scrivere all'inizio del file.


Citazione
nella documentazione ufficiale di Gambas l'errore  "Bad number of dimension" fa presente che
Si tenta di accedere a un array, indicando una serie di indici diverso dal numero di dimensioni della matrice.
E' proprio ciò di cui avevo sentore io!

Citazione
Cosa intendi per "se lo interrogo"?
Intendo dirti che facendo avvanzare il programma passo passo con il debugger ed evidenziando le variabil o gli arrays si ottiene come risposta il valore di ciò che si è evidenziato, evidenziando clienti1$ ottengo uno specchietto con i valori dei vari campi, mentre  evidenziando clienti2$ ottengo per i primi 5 campi "Bad number of dimension" e per i restanti campi Out of bounds

Citazione
Proviamo a farci dire dallo stesso Gambas quanti elementi sono dentro a  clienti2$[num, j] subito dopo la sua creazione:
Codice: [Seleziona]
PUBLIC PROCEDURE LETTURA_FILE_CLIENTI(num AS Integer)  
....bla....bla....bla....
clienti2$ = NEW String[num, 6] 
print num
print clienti2$.count
....bla....bla....bla....
END
Se è come ti aspetti, dovresti anche dirmi come ottieni calculus.
Interrogazione eseguita ed il responso non è difforme da ciò che mi attendevo per il primo array è 5 mentre per gli alti è 30 cioè 5 rekord da 6 campi ognuno.... piuttosto mi stai scrivendo di una entità  calculus, ma guarda che non esiste nel mio listato e non so cosa potrebbe essere.

In ogni caso ti ringrazio.
Ciao! :ciao:
Bye by Afo

Offline Franco_da_vc

  • Grande Gambero
  • ***
  • Post: 215
  • Non è mai troppo tardi!
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #10 il: 01 Aprile 2012, 18:11:55 »
Comunque, una domanda relativa all'intero listato di codice che hai allegato:
PUBLIC PROCEDURE LETTURA_FILE_CLIENTI(num AS Integer)

  DIM ch_file AS File
  DIM ...... etc etc
  etc etc

  ch_file = OPEN _base & "CLIENTINEW.dat" FOR READ
  INPUT #ch_file, filler$
  INPUT #ch_file, num_rec
  num = 0
  ..... etc etc

perché alla variabile num prima passi un valore  con LETTURA_FILE_CLIENTI(num AS Integer), e poi lo azzeri:  num = 0 ?  ???

...non ho... capito...
Uhm... la variabile num deriva da tot_cli che è una variabile globale che viene dichiarata ma non settata in pratica num non riceve valori validi dalla chiamata della procedura, ma ne restituisce, ecco perché concordo con l'osservazione di Picavbg che mi rimarcava che era meglio che questa procedure fosse trasformata in una function.

Grazie, ciao :ciao:
Bye by Afo

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #11 il: 01 Aprile 2012, 18:48:03 »
Uhm... la variabile num deriva da tot_cli che è una variabile globale che viene dichiarata ma non settata in pratica num non riceve valori validi dalla chiamata della procedura, ma ne restituisce, ecco perché concordo con l'osservazione di Picavbg che mi rimarcava che era meglio che questa procedure fosse trasformata in una function.
:ciao:
scusami, ma mi sfugge, forse, qualcosa del ragionamento... però vedendo il codice continuo a non capire.   :hard:
Allora... va be'... facciamo finta che ora hai trasformato la sub-routine da Procedure a Function... dunque sarebbe così:
Codice: gambas [Seleziona]

PUBLIC FUNCTION LETTURA_FILE_CLIENTI(num AS Integer) As Integer

oh... però non mi pare che la sostanza cambi.... il che continua a significare che, non appena la procedura del programma passa a questa routine-Funzione, la variabile num viene riempita dall'intero passato da tot_cli (qualunque intero le passi).
Procedendo, però, il programma s'imbatte nella riga:
Codice: gambas [Seleziona]

  num = 0

...qualunque cosa num contenesse, avendoglielo passato tot_cli, ora viene azzerato.

Domanda: ma se volevi semplicemente dichiarare il tipo di variabile nella Funzione, non era più corretto un:
Codice: gambas [Seleziona]

  Dim num As Integer


...forse mi sfugge qualcosa ?  :-\

 :ciao:
« Ultima modifica: 02 Aprile 2012, 06:28:27 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #12 il: 01 Aprile 2012, 19:37:52 »
@ Franco_da_vc:
Citazione
Intendo dirti che facendo avvanzare il programma passo passo con il debugger ed evidenziando le variabil o gli arrays si ottiene come risposta il valore di ciò che si è evidenziato, evidenziando clienti1$ ottengo uno specchietto con i valori dei vari campi, mentre  evidenziando clienti2$ ottengo per i primi 5 campi
"Bad number of dimension" e per i restanti campi Out of bounds
Aaaah!  Ma quello specchietto in G2, il più delle volte, non funziona.  :D  Non tenerne conto e verifica piuttosto  sempre con istruzioni print del tipo
Codice: [Seleziona]
FOR i = 0 TO num_rec - 1    
              print clienti1$[i]
             FOR j = 0 TO 5   
                print clienti2$[i, j]
             NEXT   
          NEXT
Se così funziona, non ti preoccupare, vai tranquillamente avanti, il programma non dovrebbe dare errori.  ;)
Se dovesse dare errori allora converrà inquadrare il problema, focalizzando per bene il passo di programma in cui emergerà l'errore.
 :ciao:
:ciao:

Offline Franco_da_vc

  • Grande Gambero
  • ***
  • Post: 215
  • Non è mai troppo tardi!
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #13 il: 01 Aprile 2012, 22:08:42 »
scusami, ma mi sfugge, forse, qualcosa del ragionamento... però vedendo il codice continuo a non capire.   :hard:
Allora... va be'... facciamo finta che ora hai trasformato la sub-routine da Procedure a Function... dunque sarebbe così:
Codice: gambas [Seleziona]

PUBLIC FUNCTION LETTURA_FILE_CLIENTI(num AS Integer)

oh... però non mi pare che la sostanza cambi.... il che continua a significare che, non appena la procedura del programma passa a questa routine-Funzione, la variabile num viene riempita dall'intero passato da tot_cli (qualunque intero le passi).
Procedendo, però, il programma s'imbatte nella riga:
Si, se però ti focalizzi sulla chiamata sarebbe plausibile questa sintassi:
Codice: gambas [Seleziona]
tot_cli=LETTURA_FILE_CLIENTI()

Ragion per cui la dichiarazione diverrebbe:
Codice: gambas [Seleziona]
PUBLIC FUNCTION LETTURA_FILE_CLIENTI()



Citazione
Codice: gambas [Seleziona]

  num = 0

...qualunque cosa num contenesse, avendoglielo passato tot_cli, ora viene azzerato.
Nel caso che ti ho illustrato io a questo punto avrebbe perfettamente senso sia la dichiarazione come variabile locale sia il settaggio a zero della stessa, considera anche che num non è un campo di comodo ma un contatore e chiaramente tranne casi particolari i contatori è buona norma settarli prima di porli in funzione, ma..........

Citazione
Domanda: ma se volevi semplicemente dichiarare il tipo di variabile nella Funzione, non era più corretto un:
Codice: gambas [Seleziona]

  Dim num As Integer
E proprio qui ho paura di aver dato per scontato qualcosa che non dovrei dare per scontato, nel basic da cui provengo le variabili di passaggio nelle proc e nelle function non dovevano essere dichiarate come variabili locali perché si sarebbe generato un errore sia a livello interprete che in fase di compilazione quindi una sintassi del genere non si poteva scrivere:
Codice: gambas [Seleziona]
PUBLIC FUNCTION LETTURA_FILE_CLIENTI(num AS Integer)
Dim num As Integer

Ma qui, in gambas, è valida questa sintassi? Ho gia visto che le variabili che devono essere fatte ritornare nelle function:
Codice: gambas [Seleziona]
Return nome_variabile

qui in gambas devono essere dichiarate come locali nel precedente basic invece no!

Grazie! Ciao. :ciao:
Bye by Afo

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Dichiarazioni di array globali
« Risposta #14 il: 01 Aprile 2012, 23:46:00 »
sarebbe plausibile questa sintassi:
Codice: gambas [Seleziona]
tot_cli=LETTURA_FILE_CLIENTI()

Ragion per cui la dichiarazione diverrebbe:
Codice: gambas [Seleziona]
PUBLIC FUNCTION LETTURA_FILE_CLIENTI()
  num = 0

Sì, così riesco a capire e mi è più chiaro.
Stando così, ossia senza dichiarazione della variabile num all'interno della routine-Function né nei parametri, mi lascia intendere che quella variabile è dichiarata come globale all'inizio, ovviamente.
Se è una Function, che appunto ritorna un valore, ovviamente va aggiunto dopo i parametri il tipo di valore che sarà restituito: As .....

E proprio qui ho paura di aver dato per scontato qualcosa...
Codice: gambas [Seleziona]
PUBLIC FUNCTION LETTURA_FILE_CLIENTI(num AS Integer)
Dim num As Integer

Ma qui, in gambas, è valida questa sintassi?
E' una dichiarazione replicata, ripetuta: se la variabile la dichiari all'interno dei parametri della routine-Funzione, non la puoi dichiarare anche all'interno della routine medesima... la dichiari due volte !
Infatti, se fai una prova uscirà l'errore: "'num' already declared".
Ma dichiarando la variabile all'interno dei parametri, ovviamente sta a significare che la funzione riceve un valore da quella variabile. Valore che poi la Funzione avrà il compito di manipolare.

Ad ogni modo, se tu vuoi che restituisca il valore di num:
Codice: gambas [Seleziona]

 ...
' questa istruzione non passa alcun valore alla Funzione chiamata:
 tot_cli=LETTURA_FILE_CLIENTI()
 ...
End


PUBLIC FUNCTION LETTURA_FILE_CLIENTI() As Integer    ' la Funzione non riceve alcun valore dalla funzione principale chiamante

  Dim num As Integer

' adottiamo il tuo giudizio: "è buona norma settarli prima di porli in funzione"
  num = 0

  ....etc
  ....etc
  ....etc

  Return num

End



qui in gambas devono essere dichiarate come locali nel precedente basic invece no!
...non in senso assoluto. Prova infatti questo:
Codice: gambas [Seleziona]

a As Integer = 10


Public Sub Button1_Click()
  
  Dim o As Integer
  
  o = alibaba()
  
  Print o
  
End


Public Function alibaba() As Integer
  
  a = a + 10
  
  Return a
  
End

...anche se, però, effettivamente - seppur non dia errore - mi sembra avere poco senso utilizzare una Funzione ed una variabile globale...  :rolleyes:
« Ultima modifica: 02 Aprile 2012, 16:31:11 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »