C Array an Funktion

  • Ersteller Ersteller Taxotic
  • Erstellt am Erstellt am
T

Taxotic

Gast
Hallo,

ich arbeite an einem Programm, das Werte nacheinander einliest und diese in einem Array abspeichert. Nun möchte ich in einer extra Funktion den Mittelwert dieses Arrays berechnen und ihn anschließen an die main Funktion zurückgeben.

Problem: Wie übergebe ich den Array an die Mittelwertfunktion?
Ich habe herausgefunden, dass dies mithilfe von Zeigern geschieht. Nun habe ich versucht, das was ich im Internet gefunden habe, in meinem Programm umzusetzen. Es gibt auch keine Fehlermeldung bzgl. des Zeigers, aber das Programm arbeitet trotzdem nicht (Mittelwert ist immer 0,000) und meine Vermutung ist, dass der Fehler darin liegt, dass ich versuche den Array an die Mittelwertfunktion zu übergeben, da ich das in diesem Programm zum ersten Mal mache.

Danke und viele Grüße

Code:

Code:
#include <stdio.h>

#include <stdlib.h>   //für malloc

int mittelwert(int* speicher)
{   
	float mittelwert;
	int i;
	


	for (i=0;i<sizeof(speicher);i++)
		{
		speicher[i]=speicher[i]+speicher[i+1];
		}
	
	mittelwert=speicher[i]/sizeof(speicher);


return mittelwert;
}


int main (void)
{	
	int eingabe=0;
	int i=0;
	int *speicher;				
	int anzahl;


	printf("Wie viele Werte wollen Sie einlesen\n");
	scanf("%i",&anzahl);
	fflush(stdin);
	printf("Bitte geben Sie das Gewicht ein\n");
	speicher= (int *) malloc (anzahl* sizeof(int));						

		for (i=0;i<anzahl;i++)
			{ 
				printf("Gewicht %i",i+1);
				printf("\n");
				scanf("%i",&eingabe);
				speicher[i]=eingabe;			
			} 
	
		printf("%f",mittelwert(speicher));

return (0);
}
 
Dürfte folgender maßen gehen

#include <stdio.h>

#include <stdlib.h> //für malloc

int mittelwert(int *speicher)
{
float mittelwert;
int i;


for (i=0;i<sizeof(*speicher);i++)
{
* speicher=*speicher+*speicher[i+1];
}
mittelwert=*speicher/sizeof(*speicher);


return mittelwert;
}


int main (void)
{
int eingabe=0;
int i=0;
int speicher;
int anzahl;


printf("Wie viele Werte wollen Sie einlesen\n");
scanf("%i",&anzahl);
fflush(stdin);
printf("Bitte geben Sie das Gewicht ein\n");
speicher= (int *) malloc (anzahl* sizeof(int));

for (i=0;i<anzahl;i++)
{
printf("Gewicht %i",i+1);
printf("\n");
scanf("%i",&eingabe);
speicher=eingabe;
}
printf("%f",mittelwert(&speicher));

return (0);
}
 
Das Problem ist: sizeof(speicher) gibt Dir nicht die Größe des Arrays wieder sondern die dies Zeigers darauf. Du musst die Größe in C zusätzlich zum Array, also anzahl, mit an die Funktion übergeben und in mittelwert sizeof(speicher) durch anzahl ersetzen. Dann funktioniert es auch noch, wenn Du mal mehr Speicher alloziert hast als Werte im Array sind.
 
Du musst noch die Länge des Arrays mit übergeben, das kommt nicht von irgendwo. sizeof( Speicher ) gibt dir übrigens nicht die Anzahl Elemente, sondern die Anzahl belegter Bytes zurück. Ein char nimmt also weniger Platz weg als ein int, obwohl es evtl. den gleichen Wert hätte. Bei Zeigern bekommst du übrigens die Größe des Zeigers zurück und nicht die des Datentyps/der Variablen.
 
also...
1. du kannst natürlcih als parameter ein pointer auf ein int vorsehen. aber lesbarer und sinnvoller wäre besser so etwas:

int mittelwert(int speicher[])

2. sizeof sollte man nicht zum bestimmen der elemente in einem array benutzen. insbesondere da du sizeof auf ein "int *" anwendest erhälst du die anzahl an bytes die EIN int belegt.

bei c MUSST du im grunde die länge des (genutzten) array expliziet mit angeben, d.h. so:

int mittelwert(int speicher[], int n)
 
Und nicht vergessen den allokierten Speicher wieder freizugeben :) Man sollte grundsätzlich so wenig wie möglich dynamisch allokieren, ist immer eine Fehlerquelle.
 
In der Schleife auch unbedingt die Array-Grenzen beachten...
wenn du machst
array = array + array[i+1]
dann darfst dein i höchstens Länge-2 sein...
Allgemein steltl sich die Frage, wieso der Inhalt des Arrays geändert werden muss für die Berechnung...
Wieso wird nicht alles in einer Variablen float sum hochaddiert und die dann durch die Anzahl der Elemente geteilt? oO

Zudem ist i ja eins zu hoch am Ende der Schleife, in der Formel müsste es heißen "mittelwert=*speicher[i-1]/sizeof(*speicher);"
Aber das kommt daher, weil man sich lieber einen komplizierten Weg für die Berechnung überlegt hat, als einen einfachen...

Und bei der Division kommt übrigens immer eine Ganzzahl raus, wenn du ein int durch ein int teilst... da bringt es auch nichts, wenn man es einem float zuweist...

@GIN: Hauptsache der Speicher wird freigegeben, was am Ende des Programms eh gemacht würde, aber fehlerhafte Algorithmen (off-by-one-Fehler) sind egal..

@Empa:
du brauchst für a keinen Stern...
 
Zuletzt bearbeitet:
sizeof( Speicher ) gibt dir übrigens nicht die Anzahl Elemente, sondern die Anzahl belegter Bytes zurück

Also muss ich Anzahl der belegten Bytes durch die Größe des Datentyps teilen?

Bsp: sizeof(speicher)/sizeof(int) ...würde das gehen?
 
vergiss den sizeof-Operator im Zusammenhang mit dynamischen Arrays einfach, wenn es auch einfachere Möglichkeiten gibt... weil die mitunter dort auch schon mal unerwartetes zurückliefert, auch wenn es sich genau so verhalten sollte, wie bereits geschrieben.... (u.U. liefert sizeof lediglich die Größe des Zeigers...)
 
Zuletzt bearbeitet:
Okay, und wie bekomme ich den Wert für "anzahl" (in der main fkt. eingescannt) in die Mittelwertfunktion?

float sum kenne ich nicht, soll ich dafür eine eigene Funktion schreiben, die die Summe berechnet oder gibts da einen Befehl für in c?
 
# float mittelwert(int* speicher, int anzahl)
# {
# float mittelwert;
# int i;
# float summe = 0.0;
#
#
# for (i=0;i<anzahl;i++)
# {
# summe += speicher;
# /*
speicher=speicher+speicher[i+1];*/
# }
#
# mittelwert=summe/(float)anzahl;
#
#
# return mittelwert;
# }
Du gibst ja einen float zurück, der wird aber explicit in einen int verwandelt durch Abschneiden der Nachkommastellen. Deshalb sollte die Funktion auch float zurückgeben und Du solltest die Werte vor der Berechnung auf float casten. Außerdem würde ich das array nicht für die berechnung verändern sondern die Summe in einer eigenen Variable halten und bis speicher[i+1] darfst Du sowieso nicht gehen, da speicher[anzahl-1] der letzte gültige Wert des Array ist und alles darüber ein illegaler Speicherzugriff.

Der Aufruf geht dann so:
printf("%f",mittelwert(&speicher, anzahl));
 
Zuletzt bearbeitet:
Danke für Eure Hilfe! Ich habe mit das Prinzip der "call-by-reference" funktion nochmal angeschaut und ich denke, dass ich das Problem mit den Zeigern jetzt etwas besser verstanden habe.

Code:
#include <stdio.h>

#include <stdlib.h> //für malloc

float mittelwert(int *speicher, int anzahl)
{
	

	float mittelwert;
	int i;
	float summe=0.0;
	 
	for(i=0; i<anzahl; i++)
	{
		summe +=speicher[i];
	}
	mittelwert= summe/(float)anzahl;


return mittelwert;
}




int main (void)
{
int eingabe=0;
int i=0;
int *speicher;
int anzahl;


			printf("Wie viele Werte wollen Sie einlesen\n");
			scanf("%i",&anzahl);
			fflush(stdin);
			printf("Bitte geben Sie das Gewicht ein\n");
			speicher= (int *) malloc (anzahl* sizeof(int));

			for (i=0;i<anzahl;i++)
					{
					printf("Gewicht %i",i+1);
					printf("\n");
					scanf("%i",&eingabe);
					speicher[i]=eingabe;
					}
			printf("%f",mittelwert(speicher, anzahl)); 

return (0);
}
 
Zuletzt bearbeitet:
Der cast von anzahl auf float is hier übrigens unnötig, da summe selbst ein float ist... eine Prüfung ob anzahl 0 ist würde im Übrigen auch nicht schaden...
 
Zurück
Oben