[Java e C++] Altro dubbio lettura di codice
Continuando con gli esercizi li ho risolti praticamente tutti, mi rimangono soltanto un paio di dubbi:
In questo esercizio l'output è IBM. Se ho capito bene, è così perché b1 utilizza il metodo equals che eredita implicitamente da Object e quindi è come facesse l'operazione == che ritorna sempre false a meno che i due oggetti passati non siano riferiti alla stessa locazione di memoria. Invece b2 sfrutta quello che abbiamo scritto noi e che sovrascrive quello di Object tramite Overriding, è corretto?
In questo l'output risulta 9 e dovrebbe essere perché dopo la new C(), chiamo la funzione a.f(3) che come parametro ha un intero e non un int, quindi la funziona int f(float w) della sottoclasse non può essere quella corretta da richiamare, il compilatore dovrebbe andare a prendere quella della superclasse B. Infatti se ci sono più funzioni con lo stesso nome il compilatore dovrebbe scegliere la funzione in base alla firma (overloading), giusto?
Questi due esercizi sono invece in C++ e non riesco a capire che valori sto passando alle funzioni tramite puntatori e array.
ES1.
OUTPUT: 03320 (di questo ho capito come escono le cifre centrali, ma perché 0 al primo e ultimo output?
ES2.
Output: 12220
Ma in questo caso non capisco che numeri io stia passando, non mi è chiaro cosa sia quel int n[7] come parametro della funzione (per inciso, non l'ho mai visto fare nemmeno al corso di prog1).
Grazie in anticipo per le risposte!
class B { int s=0; B(){}; B(int s){this.s=s;} } class A extends B{ A(int s){this.s=s*2;} public boolean equals(Object o){ return(s==((B)o).s); } } public class E1{ public static void main(String[] args) { B b1=new B(2); B b2=new A(1); B b3=new B(2); if (b1.equals(b2)) System.out.print("K"); else System.out.print("I"); if (b2.equals(b1)) System.out.print("B"); else System.out.print("D"); if (b1.equals(b3)) System.out.print("E"); else System.out.print("M"); } }
In questo esercizio l'output è IBM. Se ho capito bene, è così perché b1 utilizza il metodo equals che eredita implicitamente da Object e quindi è come facesse l'operazione == che ritorna sempre false a meno che i due oggetti passati non siano riferiti alla stessa locazione di memoria. Invece b2 sfrutta quello che abbiamo scritto noi e che sovrascrive quello di Object tramite Overriding, è corretto?
interface A{ int f(int x); } class B implements A{ public int f(int w){ return w*3; } } class C extends B{ int f(float w){ return (int)(w*2); } } public class Main { public static void main(String[] args) { A a=new C(); System.out.println(a.f(3)); } }
In questo l'output risulta 9 e dovrebbe essere perché dopo la new C(), chiamo la funzione a.f(3) che come parametro ha un intero e non un int, quindi la funziona int f(float w) della sottoclasse non può essere quella corretta da richiamare, il compilatore dovrebbe andare a prendere quella della superclasse B. Infatti se ci sono più funzioni con lo stesso nome il compilatore dovrebbe scegliere la funzione in base alla firma (overloading), giusto?
Questi due esercizi sono invece in C++ e non riesco a capire che valori sto passando alle funzioni tramite puntatori e array.
ES1.
#include <iostream.h> int x=4; int f(int *x){ x++; return (--(*x)); } void g(int &y){ y--; } int main(){ int y[]={3,2,1}; cout >> f(&y[1]); g(x); cout << x << *y << y[1] << *(y+2); }
OUTPUT: 03320 (di questo ho capito come escono le cifre centrali, ma perché 0 al primo e ultimo output?
ES2.
#include <iostream.h> void cambia(int m, int n[7]){ (*(n+m))--; m++, n--; } int main(){ int vet[]={1,2,3,2,1}; cambia(vet[3], vet); cambia(0,&vet[4]); int i=0; for (i=0; i<5;i++) cout << vet[i]; return 0; }
Output: 12220
Ma in questo caso non capisco che numeri io stia passando, non mi è chiaro cosa sia quel int n[7] come parametro della funzione (per inciso, non l'ho mai visto fare nemmeno al corso di prog1).
Grazie in anticipo per le risposte!
Risposte
Ciao,
vediamo...
per questo dubbio di cosa viene passato:
è equivalente ad:
al compilatore non interessa nulla cosa c'è dentro le parentesi quadre, è solo per ingannarti in questo esercizio, e in pratica si può usare come valore mnemonico della grandezza del vettore.
$n$ essendo un array puoi modificarne il contenuto
ti è più familiare questa scrittura?
ed $n$ essendo alla fine un puntatore (locale) nella funzione modificandone il contenuto con:
punterà a qualcos'altro.
per i passaggi di funzione:
cambia(vet[3], vet): banale
cambia(0,&vet[4]): &vet[4] sta a significare l'indirizzo di vect[4].
EDIT:
corretto no svarione...
vediamo...
"~Rose":
ES2.
#include <iostream.h> void cambia(int m, int n[7]){ (*(n+m))--; m++, n--; } int main(){ int vet[]={1,2,3,2,1}; cambia(vet[3], vet); cambia(0,&vet[4]); int i=0; for (i=0; i<5;i++) cout << vet[i]; return 0; }
Output: 12220
Ma in questo caso non capisco che numeri io stia passando, non mi è chiaro cosa sia quel int n[7] come parametro della funzione (per inciso, non l'ho mai visto fare nemmeno al corso di prog1).
Grazie in anticipo per le risposte!
per questo dubbio di cosa viene passato:
void cambia(int m, int n[7]){
è equivalente ad:
void cambia(int m, int n[]){
al compilatore non interessa nulla cosa c'è dentro le parentesi quadre, è solo per ingannarti in questo esercizio, e in pratica si può usare come valore mnemonico della grandezza del vettore.
$n$ essendo un array puoi modificarne il contenuto
(*(n+m))-- = n[m]--
ti è più familiare questa scrittura?
ed $n$ essendo alla fine un puntatore (locale) nella funzione modificandone il contenuto con:
n--
punterà a qualcos'altro.
per i passaggi di funzione:
cambia(vet[3], vet): banale
cambia(0,&vet[4]): &vet[4] sta a significare l'indirizzo di vect[4].
EDIT:
corretto no svarione...
Ho un po' di fretta per cui rispondo solo ai dubbi riguardo alla funzione
Quello che è importante comprendere in questo caso è che gli array vengono passati come se fossero dei puntatori al primo elemento dell'array. E' quindi normalmente meglio convertirla mentalmente nella seguente versione:
Immagino che ora quelle operazioni assumano più senso. Si tratta semplicemente di aritmetica con i puntatori. Per cui la prima operazione decrementa l'elemento che sta m "posizioni" dopo il puntatore, incrementa quindi inutilmente m e decrementa, sempre inutilmente, il puntatore n. Spero sia più o meno chiaro.
void cambia(int m, int n[7]) { (*(n+m))--; m++, n--; }
Quello che è importante comprendere in questo caso è che gli array vengono passati come se fossero dei puntatori al primo elemento dell'array. E' quindi normalmente meglio convertirla mentalmente nella seguente versione:
void cambia(int m, int *n) { (*(n+m))--; m++, n--; }
Immagino che ora quelle operazioni assumano più senso. Si tratta semplicemente di aritmetica con i puntatori. Per cui la prima operazione decrementa l'elemento che sta m "posizioni" dopo il puntatore, incrementa quindi inutilmente m e decrementa, sempre inutilmente, il puntatore n. Spero sia più o meno chiaro.
Direi che ora ha effettivamente più senso... Messa così è una normale operazione, quel n[7] mi aveva fatto pensare a qualche strana castroneria....
Rimango in attesa di conferme per i due in Java e il primo in c++, ma intanto ringrazio molto nuovamente entrambi!
Rimango in attesa di conferme per i due in Java e il primo in c++, ma intanto ringrazio molto nuovamente entrambi!
"~Rose":
interface A{ int f(int x); } class B implements A{ public int f(int w){ return w*3; } } class C extends B{ int f(float w){ return (int)(w*2); } } public class Main { public static void main(String[] args) { A a=new C(); System.out.println(a.f(3)); } }
In questo l'output risulta 9 e dovrebbe essere perché dopo la new C(), chiamo la funzione a.f(3) che come parametro ha un intero e non un int, quindi la funziona int f(float w) della sottoclasse non può essere quella corretta da richiamare, il compilatore dovrebbe andare a prendere quella della superclasse B. Infatti se ci sono più funzioni con lo stesso nome il compilatore dovrebbe scegliere la funzione in base alla firma (overloading), giusto?
ok.
in questo caso l'oggetto a ha in memoria solo la firma della funzione dichiarata int_f(int) ed implementata in B non ha una firma int_f(float), se te provi a chiamarla allo stato attuale non potresti.
Ricorda il principio di sostituzione di Liskov, e la visibilità delle funzioni.
ES1
In questo esercizio l'output è IBM. Se ho capito bene, è così perché b1 utilizza il metodo equals che eredita implicitamente da Object e quindi è come facesse l'operazione == che ritorna sempre false a meno che i due oggetti passati non siano riferiti alla stessa locazione di memoria. Invece b2 sfrutta quello che abbiamo scritto noi e che sovrascrive quello di Object tramite Overriding, è corretto?
non ho gurdato il codice, ma quello che dici è corretto, mi sembra però che si parli di overwriting se ricordo bene...
Attenzione al metodo equals() è pieno di insidie e sottilezze non da poco (un'altro esempio è il metodo clone()).
ES1.
cout >> f(&y[1]);
OUTPUT: 03320 (di questo ho capito come escono le cifre centrali, ma perché 0 al primo e ultimo output?
stesso giochetto dell'ES2 di C++ (v. risposta di apatriarca).
se hai dubbi chiedi pure

A posto così, grazie mille!
