C Array als Rückgabewert

Danny787

Ensign
Registriert
Jan. 2007
Beiträge
180
Ich habe eine Funktion erstellt, welcher man eine Dezimalzahl zuweist und die Funktion diese Zahl in eine Dualzahl umrechnnet. Die Dualzahl wird einem Array zugewiesen, welchen ich nun der Main Funktion übergeben und an der Konsole ausgeben lassen will.
hier erstmal der code der funktion:

#include <stdio.h>
#include <stdlib.h>


int dezimalzudual (int ndezimalzahl) {

int nergebnis=0;
int nmodulo = 0;
int nz;
int adualzahl[16];




if (ndezimalzahl < 0 || ndezimalzahl > 65535){
return (error);

}
else {for (nz = 0; nz < 16 ; nz++){
nergebnis = (ndezimalzahl/2);
nmodulo = ndezimalzahl - (nergebnis*2);
adualzahl[nz]= nmodulo;
ndezimalzahl = nergebnis;

}


for (nz=15; nz >=0; nz--){
adualzahl[nz];

}
return(*adualzahl);
}
}


ich weiß nun nicht wie ich den array der main zurückliefern kann. hab gelesen, dass dies nur mittels eines pointers auf das erste element des arrays funktionieren kann.
doch wie geb ich den kompletten array nun in der mainfunktion auf der konsole aus?
hab schon fast alles versucht, komm jedoch leider nicht weiter.
kann mir hier jemand vielleicht weiterhelfen?
danke schonmal im vorraus :)



also ich versuch mein vorhaben nochmal kurz zusammenzufassen. ich will nen pointer, welcher auf das erste element des arrays zeigt, der main funktion zurückgeben und den arrays dann mittels dem zurückgegebenen pointer in der main funktion dazu verwenden, um den kompletten array in der konsole ausgeben zu können.

ich bekomms einfach nicht hin, werd solangsam noch verrückt :(




@ BaLLeRTroeTe

vielen vielen dank :)
hat wunderbar geklappt, du bist echt meine rettung ich war echt kurz vorm durchdrehen.
 
Zuletzt bearbeitet:
ich bin kein C-Mensch, aber man könnte es auch anders versuchen: Array in der übergeordneten Methode (hier: Main) erzeugen und der Funktion via Call-By-Ref übergeben und auf diesem arbeiten. So muss man auch keins zurückgeben.
 
Hmm ich sehe noch ein anderes Problem: "int adualzahl[16];" wird in der Funktion aufgerufen und damit ein Array im Laufzeitstack der Methode erzeugt. Nach dem Rücksprung beim Return nach "Main" wird aber ungültig bzw. gelöscht und der Speicherbereit hinter diesem Pointer kann bei einem folgenden Methodenaufruf überschrieben werden.
 
Code:
#include <stdio.h>
#include <stdlib.h>

#define error -1

[COLOR="Red"]int* [/COLOR]dezimalzudual (int ndezimalzahl) {
	
	int nergebnis=0;
	int nmodulo = 0;
	int nz;
	[COLOR="Red"]int *adualzahl = (int*) malloc(16*sizeof(int));[/COLOR]
	
	
	
	
	if (ndezimalzahl < 0 || ndezimalzahl > 65535){
		[COLOR="Red"]return (int*) error;[/COLOR]
	} else {
		for (nz = 0; nz < 16 ; nz++){
		nergebnis = (ndezimalzahl/2);
		nmodulo = ndezimalzahl - (nergebnis*2);
		adualzahl[nz]= nmodulo;
		ndezimalzahl = nergebnis;
	}
	
	
	for (nz=15; nz >=0; nz--){
		adualzahl[nz];
	}

	[COLOR="Red"]return adualzahl;[/COLOR]
	}
}
Code ungetestet, sollte aber eigentlich funktionieren...

Zur Erklärung: Mit malloc() wird ein Speicherbereich auf dem Heap reserviert. Daher kannst du den Pointer darauf auch bedenkenlos an main zurückgeben. Allerdings solltest du nicht vergessen, den allokierten Speicherbereich später wieder mit free() frezugeben, da weitere maloc()-Aufrufe sonst irgendwann keinen Speicher mehr allokieren können :)

Was die Pointer-Arithmetik anbelangt, wird in dem in Post #3 verlinkten Buch gut erklärt ;)
 
Der Source von ballertroete birgt die Gefahr einer Zugriffsverletzung, wenn man ohne den Rückgabewert auf error zu überprüfen free mit der Rückgabe aufruft!

Zudem würde ich

#define error ((int*)-1)

schreiben, da ich dann auch gleich mit selbigem Makro wieder den Rückgabewert prüfen könnte und nicht dort nochmal um den Makroausdruck herumcasten müsste.

--------------

Es ist in C in der Tat die Regel, dass die Parameter einer Funktion nicht nur für die Eingabe, sondern auch für die Ausgabe verwendet werden. Der Spaß nennt sich - wie bereits erwähnt - call by reference.

Die Signatur meiner Funktion würde ich in diesem speziellen Fall so gestalten:

int dezimalzudual(int dezimal, int* dst)

Bei Funktionen solcher Art ist dann von Anfang an der aufrufende Part dafür zuständig, ein ausreichend großes Feld zur Verfügung zu stellen (und auch wieder freizugeben), egal ob nun auf Stack oder Heap - und den int-Rückgabewert könntest Du mit ==0 für OK oder !=0 für einen Fehler belegen. Bei einem Fehler sollte dann das Feld entsprechend unangetastet bleiben.


Warum nun aber schrieb ich 'in diesem speziellen Fall' ?

Üblicherweise wird noch die Länge des Pointers übertragen:

int dezimalzudual(int dezimal, int* dst, size_t size)

Somit beachtet die Funktion die Speichergrenzen und bearbeitet nur die tatsächliche Größe, um Zugriffsverletzungen innerhalb der Funktion zu vermeiden. Aber Achtung: ein solcher size-Parameter muss nicht immer die Anzahl der Feldelemente bedeuten, es kann durchaus auch die Anzahl der Bytes sein - für die Beantwortung dieser Fragen ist dann die Dokumentation zuständig.

Wenn die Feldgrößen einen konstanten Wert haben, kann man natürlich die Funktionen so gestalten, dass auf die Übergabe der Feldgröße verzichtet werden kann (siehe erste Funktions-Signatur).
 

Ähnliche Themen

Zurück
Oben