Guida Sintetica al C ed a Visual Basic
Transcript
Guida Sintetica al C ed a Visual Basic
DAL C++ A Visual Basic ( l’involzione della specie ) istruzione ; istruzione <crlf> o istruzione1 : istruzione2 In C le istruzioni finiscono sempre con punto e virgola, in VB con un ritorno a capo o con due punti. In C vi è differenza fra lettere maiuscole e minuscole, in VB no. Facciamo quindi attenzione in social modo ai nomi delle variabili, funzioni e subroutine che non possono avere come unica differenza una lettera maiuscola o minuscola. COMMENTI /* commento anche multilinea */ // commento fino a fine linea Rem commento fino a finelinea ‘ un apice singolo può sostituire Rem ISTRUZIONI CONDIZIONALI La condizione si può ottenere legando variabili e costanti con i seguenti operatori di confronto: <, >, <=, >=, = ( = = in C), <> ( != in C) e le condizioni con i seguenti operatori logici: Not (! in C), Or ( || in C), And ( && in C), Xor ( ^ in C) in VB si possono anche confrontare variabili stringa es. miastr = “ciao” in C si usa strcmp(puntatoreaMiastr, “ciao”) if ( cond ) { A } else { B } If cond Then A Else B EndIf Se cond è vera ( in C vero è anche un valore intero diverso da zero e falso se uguale a zero) si esegue il blocco di istruzioni A, altrimenti, se c’è la parte Else opzionale si esegue B. ( cond ) ? A : B ; IIf ( cond , A , B ) ( )? : e IIF Funzionano come l’IF visto prima If cond Then A Else B EndIf e ( if(cond) A else B in C ), sono poco usati. if ( cond1 ) { A } else if (cond2){ B … } else { N } If cond1 Then A ElseIf cond2 B … Else N EndIf In VB esiste una nuova parola riservata ElseIf in C si utilizzano degli if in sequenza ( non annidati ). switch ( exp ) { case 2: A break; case ‘b’: B break; case 0x65: C break; case 11: D break; … default: N } Select Case exp Case 2: A Case "bi", "c": B Case 3 To 10: C Case Is < 20: D … Case Else N End Select In C exp può solo essere un intero o un carattere, in VB un tipo qualunque (anche String), in base al valore di exp si esegue solo il Case che verifica la condizione; vi possono essere più condizioni in un case, si possono usare range 3 To 10 o la condizione Is > 15; se nessun caso è verificato ed esiste la clausola default o Case default si eseguono quelle istruzioni. pag. 1 di 7 Dal C++ a Visual Basic Prof. Ing. Ivano R. Castelnovo CICLI For cont = inizio To fine Step passo for ( init1, init2 ; cond ; istr1, istr2 ) { A A } Next cont es. for (int j=0; j < 10; j++) { arr[ j ] = 0 } Sono cicli a conteggio che mantengono solitamente un contatore (cont in VB) che ad ogni ciclo viene utilizzato come indice e incrementato di una certa quantità (passo o di default uno in VB, passi negativi devono sempre essere specificati), se ne esce quando cond è falsa in C o quando si raggiunge fine in VB. In C le inizializzazioni init vengono eseguite solo prima del ciclo; poi si verifica la condizione cond e se è vera si esegue il blocco di istruzioni A; poi si eseguono le istruzioni istr e si ricontrolla poi la condizione, ricominciando. while ( cond ) { Do While cond A A } Loop Il ciclo a condizione iniziale si ripete fino a quando la condizione cond rimane vera. do { Do A A } while ( cond ) Loop While cond Il ciclo a condizione finale, esegue sempre una volta il blocco A e poi continua a ripeterlo fino a che la condizione cond rimane vera. Do Until cond A Loop Do A Loop Until cond In VB esistono anche i due precedenti cicli, che vengono ripetuti fino a quando la condizione da falsa diventa vera ( quindi si rimane nel ciclo se cond e’ falsa ). foreach( Tipo id in exp ) { For Each var in insieme A A } Next var Solo in C#, in VB insieme è solitamente una Collection. Dim ins As New Collection potendo poi aggiungere (Add) togliere (Remove), accedere (Item) o contare (Count). COSTANTI #define nomeC valore const Tipo nomeC = valore; Const nomeC = valore Const nomeC As Tipo = valore #define max 16 const int mass = 20; Virgola fissa: 20.2 Virgola mobile: -13.2 e -3 Numeri esadecimali: 0xA3B2 o \x0A2 Numeri ottali: \632 float 356F o 356f, long 300L o 300l carattere ‘b’ o L’qd’ unicode stringhe “questa è una stringa” L”str unicode” Const max = 16 Const mass As Integer = 20 21.3 13.2 e -3 &HA3B2 &O632 o &632 esempi: non esiste, è una stringa unitaria “b” “anche in VB questa è una stringa” pag. 2 di 7 Dal C++ a Visual Basic Prof. Ing. Ivano R. Castelnovo VARIABILI Dichiarazioni: Tipo nomevar = valore; Tipo nome; Dim nomevar As Tipo nome$ Rem dichiarazione implicita di tipo String int w; float a; int b = 3; char k = ‘c’; char Pluto[20]; Dim pippo As String Dim w, x, z As Integer Dim pluto As String * 20 v1=Null: v2=3:v3%=4: v4!=5: v6&=7: v7# = 9: vv@= 11: vz$ = “abc” In C le variabili non inizializzate con un valore conterranno un valore a caso, in VB zero per i valori e stringa vuota per le Stringhe. In VB è possibile dichiarare una Stringa di lunghezza massima fissata con la sintassi: Dim nome As String * 20 ( in C char nome[20] ). Tipi di variabili: VC++ 6.0/ VC# bytes VB 6.0 / VB.NET bool sbyte unsigned char byte short 1 1 1 Boolean 2 Integer Short unsigned short ushort int unsigned int unsigned long uint long ulong float 2 double long double decimal 8 ( 10 ISO ) 16 (8 VB6 ) 16 (14 VB6 ) char char (wchar_t VC 6) string 1 2 2 * lun + 10 8 postfisso VB true / false True / False -128 / 127 0 / 255 Byte % -32 768 / 32 767 0 / 65 535 4 4 Integer ! -2 147 483 648 / 2 147 483 647 0 / 4 294 967 295 8 (4 VS6 ) 8 4 Long & -2 147 483 648 / 2 147 483 647 4 numeri 16 String 22 + len Uso delle variabili: a = 10.1; a = b; strcpy(Pluto, “nome di\nun cane”); Single Float Double # Currency Decimal @ String Date $ Object Variant +/- 1.401298E-45 +/- 3.402823E+38 +/- 1.79769313486231E308 +/- 4.94065645841247E-324 +/- 922 337 203 685 477.5808 +/-9 228 162 514 264 337 593 543 950 335 +/-7.922 816 251 426 433 759 354 395 033 5 -128 / 127 L”stringa unicode” ore da 0:00:00 a 23:59:59 date dal 1 Gennaio 100 al 31 Dicembre 9999 Referenza a qualunque oggetto default es: a=Null w=3:z=w pluto = “nome di” & vbCrLf & “un cane” ( ATTENZIONE a = b assegna il valore contenuto in b ad a. In VB a = b usato dove ci si aspetta una condizione confronta se i valori delle due variabili sono uguali. In C il confronto fra i valori si fa con un operatore speciale a = = b perché in automatico non vi è differenza fra condizioni ed istruzioni. Infatti se in C si scrive: if ( a = b ) istr1; else istr2; verrà sempre eseguita l’istruzione istr1 perché l’assegnazione = sarà sempre considerata vera ) In C vengono spesso utilizzati i termimi lvalue e rvalue per riferirsi alla zona di memoria che contiene il valore od al valore stesso (indirizzo della variabile e valore della variabile stessa) i termini derivano dalla posizione a sinistra o a destra del segno di uguale in una assegnazione. (es. a = 3; b = a; lvalue di b è l'indirizzo di b, mentre rvalue di a è 3 cioè il valore) pag. 3 di 7 Dal C++ a Visual Basic Prof. Ing. Ivano R. Castelnovo Scope delle variabili: Per SCOPE si intende la visibilità di una variabile. In C la cosa è relativamente semplice: le variabili sono Locali al blocco che comincia con aperta graffa e si chiude con chiusa graffa { ... } ovunque esso sia, corpo di una funzione, blocco di if .. else, while, for o blocco creato all'uopo dall'utente proprio per questo motivo. L'unica eccezione che è comunque sconsigliato utilizzare sono le variabili Globali cioè dichiarate all'esterno di tutte le funzioni che risultano quindi visibili da tutto il programma. In VB le variabili sono Locali alla Sub o Function dove sono dichiarate con Dim o Private, cioè visibili solo alla Sub o Function in cui sono dichiarate. Se vengono dichiarate nella parte Generale di Dichiarazioni del codice associato alla Form (fuori da ogni Sub e Function) possono essere viste da tutte le Sub o Function della Form. Se vengono dichiarate Public in questa parte Generale di Dichiarazioni o dentro un modulo .BAS allora possono essere viste anche da altre Form richiamando nomeForm.nomeVarPubblica o dopo aver creato una istanza della classe nomeClasse.BAS con Dim oggetto As nomeClasse richiamarla per l'uso con la sintassi oggetto.nomeVarPubblica ARRAY Dichiarazioni Array Statiche: Tipo nome[ numElementi ]; Tipo nome[ numElementi ] = { inizializzazione }; Tipo nome[ ] = { inizializzazione }; Tipo nome [ Nrighe ][ Ncolonne ]; Dim nomeA ( MaxIndice ) As Tipovariabile Dim nomeA ( minIndice To MaxIndice ) As Tipo Dim nomeA ( MaxRighe, MaxColonne ) As Tipo Erase ( nomeA ) LBound( nomeA ) o ( NomeA, numIndice ) UBound( nomeA ) o ( NomeA, numIndice ) Tutti i valori numElementi, MaxIndice, minIndice, Nrighe, Ncolonne, MaxRighe, MaxColonne devono essere costanti numeriche o dichiarate come Const in VB o #define in C; non è possibile l’uso di variabili al loro posto. In VB Erase azzera gli array numerici e mette a stringa vuota quelli String. Le funzioni LBound e UBound ritornano i valori minimo e massimo dell’indice uno o nel caso di array a più dimensioni quello di numIndice. In entrambi i linguaggi l’indice minimo inizia da zero 0 e in C può raggiungere al massimo in modo corretto (numElementi - 1) in VB anche MaxIndice è valido, se quindi numElementi = MaxIndice l’array dichiarato in VB potrà contenere un valore in più di quello C. In VB vengono effettuati tutti i controlli sugli indici di un array, in C nemmeno un controllo viene fatto e tutto è lasciato alla responsabilità del programmatore. Ciò era stato fatto per avere codici molto più veloci se corretti ma a scapito della robustezza. Array Dinamiche: Tipo *nomeArr; nomeArr = malloc( numEl * sizeof(Tipo) ); nomeArr = calloc( numEl, sizeof(Tipo) ); nomeArr = realloc( numEl, sizeof(Tipo) ); Tipo *nomeArr = new Tipo[ numEl ]; free ( nomeArr ); delete [] nomeArr ; Dim nomeA( ) As Tipo ReDim nomeA ( vMaxIndice ) As Tipo ReDim Preserve nomeA ( vMaxIndice ) ReDim nomeA ( vminIndice To vMaxIndice ) Erase nomeA Il numero degli elementi può essere determinato in maniera dinamica, cioè può essere il nome di una variabile che verrà valorizzata durante l’esecuzione del programma e non solo una costante il cui valore sia conosciuto al momento della compilazione dello stesso. numEl, vMaxIndice, vminIndice possono essere variabili intere. Preserve conserva i valori presenti prima della ReDim. malloc, calloc, realloc e free sono funzioni del C e non funzionano con le classi; in C++ sono stati introdotti al loro posto new e delete. In VB Erase libera la memoria dell’array ( come free e delete in C/C++) quindi non vi si può più accedere e non come per gli array costanti che azzera solo gli elementi. esempi di dichiarazioni: int ar1 [10]; int ar2 [ ] = {3, 6, 2}; char ar3[30] = “ciao pippo” char ar4[] = {‘c’,’i’,’a’,’o’}; int ar5[2][3] = { {5,3,7}, {4,9,10} }; int *dina; dina = new int[20] int k=2; int *dina; dina = new int[k] Dim ar1 (9) As Integer Dim ar2 (2) As Integer : ar2(0)=3:ar2(1)=6:ar2(2)=2 Dim ar3 As String : ar3 = “ciao pippo” Dim ar4 (3) As Single : ar4(0)=Asc(“c”) : ar4(1)=Asc(“i”) … Dim ar5 ( 1, 2 ) As Integer : ar5(0,0)=5: ar5(0,1)=3: ar5(0,2)=7 … Dim dina() As Integer : ReDim dina(1,9) Dim di() As Integer : Dim k,w As Integer : k=1:w=2: ReDim di(k,w) pag. 4 di 7 Dal C++ a Visual Basic Prof. Ing. Ivano R. Castelnovo STRINGHE In C/C++ le stringhe sono array di caratteri che utilizzano un terminatore ‘\0’ per delimitare la fine della stringa, nessun controllo viene fatto sullo sforamento della lunghezza massima o minima degli indici e non vengono ridimensionate automaticamente. In VB le stringhe si ridimensionano automaticamente se non ne è dichiarata la dimensione. Se hanno una dimensione massima e gli si assegna una stringa più lunga nessun errore viene generato ma la stringa viene troncata. Vi sono delle funzioni sia in C che VB per il trattamento delle stringhe: strcpy( str1, str2) = es. str2 = str1 assegna str2 a str1 strcmp( str1, str2) = = 0 = es. if str2 = str1 confronto uguali strcmp( str1, str2) ! = 0 <> es. if str2 <> str1 diverse strcmp( str1, str2) < = 0 <= es. if str2 = str1 minore uguale strcmp( str1, str2) > = 0 => es. if str2 = str1 maggiore uguale strcmp( str1, str2) < 0 < es. if str2 = str1 minore strcmp( str1, str2) > 0 > es. if str2 = str1 maggiore strcat( str1, str2 ) & o + unisce es. A$ = B$ + C$ : m$ = “ciao” & vbCRLF + “mamma” strlen( str1) Len$( str1 ) restituiscono la lunghezza della stringa Left$( str1, numChar ) ritorna la parte sinistra della str1 lunga numChar Right$( str1, numChar ) ritorna la parte destra della str1 lunga numChar Mid$( str1, inizio ) ritorna la parte centrale da inizio alla fine della str1 Mid$( str1, inizio, lung ) ritorna partendo da inizio, lung caratteri char strC[5] = “ciao”; //ricorda 1 char in più per ‘\0’ “ciao” char strC2[20]; char strC3[10]; strcpy(strC2, strC); //copia in strC2 if (strcmp(str1, “OK”) == 0) char s1[20]; char s2[]== "abcdefghijkl" strcpy(s1, s2); s1[3] = ‘\0’; for(int i=0;i<5; i++){s1[i]=s2[strlen(s2)-4+i]} for(int i=0;i< strlen(s2)-2; i++){s1[i]=s2[2+i]} for(int i=0;i< 2; i++){s1[i]=s2[3+i]}; s1[2]=’\n’; Dim strVB As String * 4 : strVB = “ciaoMammaComeStai” Rem tronca Dim strVB2, strVB3 As String strVB2 = strVB s2$ = "abcdefghijkl" s1$ = Left$(3) s1$ = Right$(4) s1$ = Mid$(s2, 3) s1$ = Mid$(s2, 4, 2) Rem “abc” Rem “ijkl” Rem “cdefghijkl” Rem “de” TIPI DEFINITI DALL'UTENTE struct nomeTipo { Tipo1 elemento1; Tipo2 elemento2[costante]; Tipo3* elem3; } var1, var2 ... varN; [Private | Public ] Type nomeTipo elemento1 As Tipo1 elemento2(costante) As Tipo2 elem3 As Variant End Type esempi di dichiarazioni struct SCHEDA { int eta; char nome[20]; }; Private Type SCHEDA eta As Integer nome As String End Type In VB le dichiarazioni possono essere fatte solo nell'area General di una Form (solo di tipo Private) o in file .BAS separato, all'interno della dichiarazione delle variabili elementi non cominciano con Dim. In C non ci sono limitazioni ed in più è possibile istanziare subito delle variabili di quel tipo ( var1, var2 ,...). Dichiarazioni di variabili di tipo struct o Type: struct nomeTipo nomevar; Dim nomevar As nomeTipo struct nomeTipo nomearr[costante]; Dim nomearr(costante) As nomeTipo nomeTipo nomevar; // solo in C++ e C# si può omettere la parola struct nomeTipo nomearr[costante]; // solo in C++ e C# pag. 5 di 7 Dal C++ a Visual Basic Uso di variabili di tipo struct o Type: nomevar.elemento = valore; nomevar.elemento[indice] = valore; nomearr[indice].elemento = valore; nomearr[indice].elemento[idx] = valore; strcpy( nomevar.elstringa, stringa ); Prof. Ing. Ivano R. Castelnovo nomevar.elemento = valore nomevar.elemento(indice) = valore nomearr(indice).elemento = valore; nomearr(indice).elemento(idx) = valore; nomevar.elstringa = stringa struct SCHEDA Anna; struct SCHEDA anagrafica[1000]; SCHEDA Anna; // solo in C++ e C# Dim Anna As SCHEDA Dim anagrafica (999) As SCHEDA strcpy(Anna.nome, "Anna"); Anna.eta = 23; printf( "Nome %s", Anna.nome ); printf( "Iniziale %c", anagrafica[1].nome[0] ); Anna.nome = "Anna" Anna.eta = 23 Debug.Print Anna.nome Debug.Print Left$( anagrafica(1).nome, 1 ) PROCEDURE E FUNZIONI void nomeRoutine( parametri ) { istruzioni } [Private | Public | Static] Sub nomeRoutine ( parametri ) istruzioni End Sub Tipo nomeFunzione( parametri ) { istruzioni return valore } [Private | Public | Static] Sub nomeFunzione ( parametri ) As Tipo istruzioni nomeFunzione = valore : istruzioni End Function parametri: (Tipo par1, Tipo* par2, Tipo par3[]) (ByRef par1 As Tipo, ByVal par2 As Tipo, par3( ) As Tipo) Parametri formali: possono essere dichiarati come se fossero delle variabili locali che verranno inizializzate con il valore passato loro dal punto del programma dove verranno richiamate. In C se non vi sono parametri si può usare void nomeRoutine (void) o void nomeRoutine( ) e in concomitanza Tipo nomeFunzione (void) o Tipo nomeFunzione (void). In VB solo le parentesi vuote Sub nomeRoutine( ) In C si possono passare valori, puntatori (per valore) o array per referenza (indirizzo). In VB si deve spacificare per ogni parametro se sarà passato per valore ( ByVal ) o per referenza ( ByRef ) default e che quindi cambia anche i valori delle variabili del chiamante. Ovviamente le Funzioni Ricorsive (che richiamano se stesse) possono avere solo passaggio di parametri per valore ( ByVal in VB ). Uso delle funzioni o subroutines: nomeRoutine ( ); Call nomeRoutine varx = nomeFunzione ( ); varx = nomeFunzione ( ) nomeRoutine ( val1, val2 ); Call nomeRoutine ( val1, val2 ) : nomeRoutine val1, val2 varx = nomeFunzione ( val1, val2 ); varx = nomeFunzione ( val1, val2 ) Parametri Attuali: val1 e val2 ... valN sono: valori, variabili o espressioni dello stesso tipo del parametro dichiarato nella medesima posizione e che vengono valutati prima di richiamare la funzione o subroutine. Si otterra par1 = val1, par2 = val2 ecc. GESTIONE DEGLI ERRORI O ECCEZIONI [ Sub | Function ] nome ( parametri ) On Error Go To label try { istruzioni che possono generare errori } catch( eccezione1 ) { //gestione eccezione1 } [ catch( ... ) { //gestione tutte le altre eccezioni }] istruzioni che possono generare errori Exit [Sub | Function] label: Rem gestione errore usando Err [ Resume | Resume Next ] End [Sub | Function ] pag. 6 di 7 Dal C++ a Visual Basic Prof. Ing. Ivano R. Castelnovo E' quasi obbligatorio usare la gestione degli errori quando si aprono, chiudono ed usano i file o quando si richiede dinamicamente una certa quantità di memoria che non è detto sia disponibile con una new, alloc, realloc, calloc in C o ReDim di un array in VB. In VB l'oggetto Err ha due proprietà importanti che sono Err.Description e Err.Number rispettivamente descrizione e numero. Con Resume si riprende dall'istruzione che ha generato l'errore, con Resume Next da quella successiva. La Descrizione può essere utilizzata per dare dei messaggi all'utente, il riconoscimento del Numero invece è più utile per una gestione automatica di aggiramento dell'errore (es. non c'è sufficiente memoria, creo un'array più piccola, ReDim). Solo in C++ e C# esiste la gestione delle eccezioni con try ... catch. In C invece le funzioni non si fermano, ma se si verifica un errore restituiscono un valore di ritorno che segnalala il tipo dell'errore, solitamente gli errori sono numeri negativi o NULL. FILE SEQUENZIALI Sono leggibili solo scorrendo dall'inizio tutto il file sino al punto che ci interessa, carattere per carattere o riga per riga, solitamente sono file di testo. Open percorsoEnomeFile [For modo] As #numeroFile [Len = dimBuffer] dove modo può essere: Append aggiunge in coda o crea per aggiungere elementi. Output crea per aggiungere elementi. Input apre un file esistente per leggerne i dati, se non esiste si genera un errore. Random vedi poi. Close o Close #numeroFile, #numeroFile ... Print #numeroFile, dato Write #numeroFile, dato1, dato2, ... , datoN Line Input #numeroFile, dato Input #numeroFile, dato1, dato2, ... , datoN EOF ( numeroFile ) Rem funzione Boolean vale True se si è raggiunta la fine del file, False altrimenti LOF ( numeroFile ) Rem restituisce un Long con la lunghezza in byte del file Dir ( percorsoEnomeFile ) Rem funzione che restituisce stringa nulla "" se il file non esiste. FreeFile Rem restituisce il primo numero di file disponibile, Open file As numeroFile Kill percorsoEnomeFile Rem cancella un file Name vecchioNome As nuovoNome Rem rinomina un file da vecchioNome a nuovoNome Close chiude tutti i file aperti, Close con uno o più numeri file chiude solo questi file. Nella Print e Line Input, dato può essere un tipo base od una stringa, solitamente è una riga di testo. dato1, ... , datoN in Write e Input sono delle informazioni che hanno qualche cosa in comune e per cui si richiede che vengano memorizzate su di una stessa riga. FILE AD ACCESSO CASUALE Si può cercare un determinato record posizionandosi con le funzioni messe a disposizione e sovrascrivere delle informazioni senza dover riscrivere tutto il file. Non è possibile cancellare un record, ma se si usa un campo Boolean cancellato e lo si mette a True se ne può simulare la cancellazione (cancellazione logica). Periodicamente poi si può provvedere a compattare il file copiando solo i record non cancellati in un nuovo file temporaneo, cancellando il vecchio file e rinominando il temporaneo con il vecchio nome. Open percorsoEnomeFile For Random As #numeroFile Len = dimensioneRecord Close o Close #numeroFile, #numeroFile ... Put #numeroFile, [posizione], record Get #numeroFile, [posizione], record Seek #numeroFile, posizione Seek ( numeroFile ) Rem posizione di lettura o scittura attuali ( Loc(N) + 1 ) se non ci sono state Seek Rem numero dell'ultimo record letto o scritto Loc ( numeroFile ) Len ( tipoRecord ) Rem valore in byte del tiporecord dichiarato con Type Open usa il modo Random ed è obbligatorio il parametro Len con la dimensione del recod. In VB i record sono dichiarati con Type e se ne può ricavare la dimenzione con la funzione Len( tipoRecord ) che restituisce il valore in byte. Put e Get scrivono o leggnono un intero record dalla posizione (se esiste) altrimenti danno errore. Put non da errore se posizione è il primo RecordLibero = LOF( file ) \ ( Len( tipoRecord ) + 1 ), cioè un numero in più dei record contenuti nel file, in questo caso aggiunge in coda al file. Get e Put senza posizione Get #1, , rec o Put #1, , rec leggono o scrivono il record successivo alla posizione dove ci si trova in quel momento ed avanzano di una posizione. Seek #1, 3 posiziona per avere la prossima lettura o scrittura sul terzo record memorizzato. pag. 7 di 7