Werte abfragen und in varargs-Parameter übergeben

Guten Morgen zusammen :slight_smile:

Heute hab’ ich folgende Aufgabe:

Implementieren Sie eine Funktion, die als ersten Parameter einen int-Wert n und daraufhin n float-Parameter übergeben bekommt, deren Summe geliefert werden soll (Beispiel: f(3, 1.1f, 2.2f, 3.3f) == 6.6f).

Die Werte möchte ich mit IO.read… abfragen. Aber wie übergebe ich n Werte dann in n float-Parameter?

Vielen Dank schonmal im Voraus :slight_smile:

du nennst selber das Stichwort im Titel, ist dir Varargs nun bekannt oder nicht?
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
Methode/ Aufgabe gar schon fertig?

damit kannst du beliebig viele Parameter übergeben,
das eignet sich freilich eher für direkte Quellcode-Aufrufe, für dynamisches Einlesen weniger

theoretisch denkbar ist noch,
drei float-Variablen f1, f2, f3 einzulesen und dann methode(3, f1, f2, f3) aufzurufen,
aber ganz schön begrenzt und die Anzahl ist dann auch nicht dynamisch

eher liest man doch in ein Array ein, Varargs hilft dabei nach meinem Vorstellungsvermögen nicht, richtig,
wobei man an so eine Varargs-Methode durchaus auch ein Array übergeben darf,
auch die bekannte Signatur der main-Methode darf man so umschreiben

dein Einlesen gehört anscheinend auch nicht zur Aufgabe, die ist also nicht Schuld

ist das die ganze Aufgabe ? interpretierbar :wink:

was ich mir vorstellen kann, wenn du varargs nehmen sollst ist eher dass die Methode ueberprueft, ob n gleich der groesse des varargs parameter ist (also des arrays).

Die ganze Aufgabe sieht so aus:

Implementieren Sie in Java folgende Prozeduren/Funktionen! Achten Sie auf Randfälle und nicht korrekte Parameterübergaben! Überprüfen Sie aber zunächst für jede Funktion, ob sie überhaupt mit den (bisher bekannten) Konzepten in Java implementiert werden kann und wenn nicht, begründen Sie, wieso nicht!

(1) eine Funktion, die testet, ob eine als Parameter übergebene natürliche Zahl eine Fibonacci-Zahl ist oder nicht (Beispiel: f(8) == true),
(2) eine Prozedur, die die Werte zweier als Parameter übergebener double-Variablen vertauscht (Beispiel: double a=2.0; double b=5.9; f(a, b); Ergebnis: a==5.9; b==2.0,
(3) eine Funktion, die einen übergebenen double-Wert rundet und als int-Wert zurückliefert (Beispiel: f(-2.6) == 3)
(4) eine Funktion, die die nächst kleinere Primzahl einer als Parameter übergebenen natürlichen Zahl (größer als 2) liefert (Beispiel: f(11) == 7),
(5) eine Funktion, die als Parameter einen int-Wert übergeben bekommt und die überprüft, ob die Ziffer 7 in dem int-Wert vorkommt (Beispiel: f(-2578) == true),
(6) eine Funktion, die als ersten Parameter eine Funktion g:char->int und als zweiten Parameter einen char-Wert zeichen übergeben bekommt und die als Ergebnis den Wert g(zeichen) liefert (Beispiel: public static int pos(char zeichen) {return zeichen - ‘a‘ ;} und f(pos, ‘b‘) == 2),
(7) eine Funktion, die als Parameter einen int-Wert n übergeben bekommt und die als Ergebnis die Summe der Zahlen zwischen 0 und n zurückliefert; ist
der Wert des übergebenen Parameters jedoch kleiner als 0, soll die Funktion den Wert false liefern (Beispiel: f(4) = 10, f(-2) == false)
(8) eine Funktion, die als ersten Parameter einen int-Wert n und daraufhin n float-Parameter übergeben bekommt, deren Summe geliefert werden soll (Beispiel: f(3, 1.1f, 2.2f, 3.3f) == 6.6f).
(9) eine Funktion, die als ersten Parameter einen float-Wert x (zwischen 0 und 1000) und als zweiten Parameter einen positiven int-Wert n (zwischen 1 und 5) übergeben bekommt. Die Funktion soll den Wert x auf n Nachkommastellen runden (Beispiel: f(2.2576F, 3) == 2.258F)
(10) eine Funktion, die die Summe zweier Uhrzeiten als Ergebnis liefert; Uhrzeiten werden dabei als float-Werte realisiert, wobei die Vorkommastellen die Stunden und die Nachkommastellen die Minuten darstellen (Beispiel: f(22.13f, 3.48f) == 2.01f)
(11) eine Funktion, die die Summe und die Differenz zweier als Parameter übergebener int-Werte zurückliefert (Beispiel: f(4, 3) = (7, 1))

Schreiben Sie ein Programm, das einem Benutzer eine Auswahl zur Ausführung der implementierbaren Funktionen anbietet, anschließend jeweils passende Werte für die aktuellen Parameter einliest, die ausgewählte Funktion aufruft und ein Ergebnis auf dem Bildschirm ausgibt. Achten Sie darauf, dass die Funktionen nur mit zulässigen Werten aufgerufen werden.

Problem is’ halt wirklich, dass die Zahlen eingelesen werden sollen und ich bisher mit Arrays nicht wirklich gearbeitet habe.

Ohne Abfrage sieht’s jetzt bei mir so aus:


	public static float berechnung(int n, float... zahlen) {
		float summe = 0;
		for (int m = 0; m < zahlen.length; m++) {
			summe = summe + zahlen[m];
		}
		return summe;
	}
	
	
	/* Hauptmethode */
	public static void main(String[] args) {
		int n = 3;
		float ergebnis = berechnung(n, 1.1f, 2.2f, 3.3f);
		System.out.println(ergebnis);
	}
}```

ja, der Zusatz zum Testen mit Einlesen ist ein gewisses Dilemma,
es bleibt denke ich bei:

  • festes Einlesen von z.B. 3 floats, wie ich schon genannt hatte
    oder
  • dynamisches Einlesen beliebiger Werte in ein Array, per Schleife,
    für sich eine Aufgabe, die du aber ruhig erstmal selber angehen magst, da will ich noch nicht so viel sagen,
  • dann Übergabe des Arrays + dessen Länge, sinnvoll zu addieren, aber nicht ganz das Einsatzgebiet von Varargs,
    wobei wie gesagt eine durchaus bekannte und erlaubte Variante, man kann an dieser Stelle auch ein Array übergeben, ausprobieren

der Zusatz ist für alle 11 Methoden, muss ja speziell bei dieser nicht ganz genau passen, schon ok,
wenn die die ‘3 floats’-Variante nimmst, dann mogelst du dich recht einfach raus,

kann durchaus ok, gar sinnvoller als Antwort statt der komplizierte Array-Variante sein,
sowas ist immer Interpretation der Wünsche des Aufgabenstellers, nicht formal eindeutig zu beantworten, keine Java-Frage

ob sie überhaupt mit den (bisher bekannten) Konzepten in Java implementiert werden kann und wenn nicht, begründen Sie, wieso nicht!

sind varargs bisher bekannt fuer euch ?

die einzige moeglichkeit eine solche Signatur zu haben ist dass das zweite argument ein Array bzw ein varargs argument ist. Wenn ihr das nicht hattet so scheint es das es nicht zu machen ist. Begruendung eben weil man bei der Definition einer methode nicht die anzahl der parameter flexibel halten kann

Wie ich das hasse: wozu das int? Warum nicht einfach
**
eine Funktion, die beliebig viele float-Parameter übergeben bekommt, deren Summe geliefert werden soll (Beispiel: f(1.1f, 2.2f, 3.3f) gibt 6.6f zurück).**

du brauchst die Anzahl gar nicht, die ergibt sich doch aus dem Array

(da brauchst du in dem Beispiel nur float statt int nehmen und anstatt das max einfach die Summe berechnen)

[QUOTE=black_droid;64233]
Ohne Abfrage sieht’s jetzt bei mir so aus:


	public static float berechnung(int n, float... zahlen) {
		float summe = 0;
		for (int m = 0; m < zahlen.length; m++) {
			summe = summe + zahlen[m];
		}
		return summe;
	}
```[/QUOTE]
dass der n-Parameter recht überflüssig ist, wurde ja schon genannt,
die Methode aber so zu programmieren, dass er gar nicht genutzt wird, dass man dort ohne Auswirkung auf -564665435 eingeben kann,
das ist kein empfehlenswertes Vorgehen ;) , 
allgemein schon nicht und als Code zur Bewertung an andere gegeben unnötige Scharte

wenigstens wie schon angesprochen mit Länge des Arrays vergleichen und vielleicht Fehlermeldung ausgeben

denkbar wäre auch, die Schleife nur bis n laufen zu lassen,
dann könnte man nur einen Teil der Parameter addieren, 
bei Übergabe eines Arrays, welches inital großzügig auf 100 erzeugt wurde, aber nur 3 Zahlen drin, durchaus interessante Möglichkeit,
muss man alles entscheiden

So sieht’s jetzt aus:


	/* Berechnung der Summe aus den angegebenen float-Parametern */
	public static float berechnung(float[] floatWerte) {
		float summe = 0;
		
		for (int zaehler = 0; zaehler < floatWerte.length; zaehler++) {
			summe += floatWerte[zaehler];
		}
		
		return summe;
	}
	
	
	/* Hauptmethode */
	public static void main(String[] args) {
		
		/* Abfrage der Anzahl der float-Parameter */
		int anzahlParameter = IO.readInt("Anzahl float-Parameter: ");
		
		/* Anlegen eines Arrays, in den genau "anzahlParameter" float-Werte passen */
		float[] floatWerte = new float[anzahlParameter];
		
		/* Abfrage der float-Werte */
		for (int zaehler = 0; zaehler < floatWerte.length; zaehler++) {
			floatWerte[zaehler] = IO.readFloat("float-Wert: ");
		}
		
		float ergebnis = berechnung(floatWerte);
		System.out.println(ergebnis);
	}
}```

Wozu noch das “int n” in der Summen-Methode?

Ups, übersehen, danke für den Hinweis :slight_smile:

stimmt aber nun nicht mehr mit der Aufgabe ueberein ?!

deine Methodensignatur ist ja anders als vorgegeben

[QUOTE=Bleiglanz]Wie ich das hasse: wozu das int? Warum nicht einfach
**
eine Funktion, die beliebig viele float-Parameter übergeben bekommt,[/QUOTE]Weils in der Anforderung steht.

Hier unterscheidet sich der professionelle Programierer vom guten: Er lässt unsinnige Anforderungen nicht einfach weg sondern diskutiert mit dem Kunden darüber.

Solange “alte Hasen” mit guten C-Kenntnissen die Aufgaben stellen müssen die Java-Lernenden wohl mit solchen Fehlleistungen leben…

bye
TT

Ha ha, das ist bestimmt der Grund :slight_smile:

Oder es ist wirklich Teil der Aufgabe, dass man „Überprüfen Sie aber zunächst für jede Funktion, ob sie überhaupt mit den (bisher bekannten) Konzepten in Java implementiert werden kann und wenn nicht, begründen Sie, wieso nicht!“ durchführt. Könnte ja sein, dass die Lösung aus dem Satz: „Geht mit den bisher bekannten Konzepten nicht“ besteht

[QUOTE=Bleiglanz]Oder es ist wirklich Teil der Aufgabe, dass man “Überprüfen Sie aber zunächst für jede Funktion, ob sie überhaupt mit den (bisher bekannten) Konzepten in Java implementiert werden kann und wenn nicht, begründen Sie, wieso nicht!” durchführt. Könnte ja sein, dass die Lösung aus dem Satz: “Geht mit den bisher bekannten Konzepten nicht” besteht[/QUOTE]Diese Funktion ist aber mit Java realisierbar.
Den Integer als ersten Parameter mitzugeben ist gute alte C-Tradition, weil ich da das array nicht (direkt) fragen kann wie viele Elemente es hat.

bye
TT

[QUOTE=Timothy_Truckle;64461]Diese Funktion ist aber mit Java realisierbar.
Den Integer als ersten Parameter mitzugeben ist gute alte C-Tradition, weil ich da das array nicht (direkt) fragen kann wie viele Elemente es hat.

bye
TT[/QUOTE]

es ist so: wenn varargs zu den bisher bekannten Konzepten gehört kann man die gewünschte Funktion realisieren (aber der Parameter n ist überflüssig), wenn nicht, dann geht das nicht

[QUOTE=Bleiglanz]es ist so: wenn varargs zu den bisher bekannten Konzepten gehört kann man die gewünschte Funktion realisieren (aber der Parameter n ist überflüssig), wenn nicht, dann geht das nicht[/QUOTE]ganz ohne VarArgs:```public static void main(String[] args){
float[] werte = new float[0];
Scanner scanner = new Scanner(System.in);
try {
werte = Arrays.copyOf(werte, werte.lenght+1);
System.out.print("Zahl (mit Dezimalpunkt) eingeben: ");
werte[werte.length-1] = scanner.nextFloat();
} catch(Exception e) {
// unschöner Missbrauch der Exception zur Ablaufsteuerung.
}
f(werte.length,werte);
}
private static void f(int n, float[] werte){
//ohne VarArray…
}


bye
TT

allerdings übergibst du hier ein float array, und nicht n floats
lässt sich drüber streiten

Als „gut“ würde ich diese Tradition nicht bezeichnen. Bei C ist es notwendig, bei Java redundant. Wenn jemand dann einen falschen Parameter mitgibt, führt das ggf. zu einer ArrayIndexOutOfBoudsException, es sei denn, man ignoriert den Parameter. Dann ist er wiederum sinnlos und sollte weggelassen werden.

Problem geklärt: In diesem Fall soll tatsächlich angegeben werden, dass es so nicht machbar ist. :o

Trotzdem vielen Dank für die Hilfe :slight_smile: