Array aus Funktion dem main-Prgramm übergeben?

Hi,
ich wollte mich mal bisschen in C einarbeiten.
Doch da bin ich schnell an meine Grenzen gestoßen.
Und zwar habe ich mir zuerst eine Funktion (einlesen) geschrieben, die eine Datei öffnet und den inhalt einliest. Es sind Dezimalzahlen, di in einem Array gespeichert werden.

Nun möchte ich aber diesen Array dem Hauptprogramm zurückgeben (mit return), aber es geht nicht.
Warum kann ich nicht einfach „return array“ schreiben?
array ist doch in diesem Fall, weil ohne [], ein Zeiger auf das erste Element des Arrays. Diesen Zeiger zu Übergeben sollte mir eigentlich reichen. Was muss ich als Rückgabetyp für diese Funktion (einlesen) angeben. Ich hatte float…

Wenn array[] mein Array ist, dann möchte ich entweder das ganze Array oder eben einen Zeiger auf das erste Arrayelement (array) zurückgeben.

Warum funzt „return array“ nicht???

Als Fehlermeldung bekomme ich:
incomatible types in assigments

array ist doch in diesem Fall, weil ohne [], ein Zeiger
auf das erste Element des Arrays. Diesen Zeiger zu Übergeben
sollte mir eigentlich reichen. Was muss ich als Rückgabetyp
für diese Funktion (einlesen) angeben. Ich hatte float…

Wie du selber schreibst, array ist ein Zeiger auf das erste Element des Arrays. Du deklarierst den Rückgabetyp aber als float, was du aber zurückgeben willst ist ein Zeiger auf float, also musst du den Rückgabetyp auf float* deklarieren.

Grüße, Robert

Nun habe ich stat float, float* aber es ist immernoch der selbe Fehler…

Nun habe ich stat float, float* aber es ist immernoch der
selbe Fehler…

Poste vielleicht einmal deinen Code (bitte mit PRE-Tag).

Grüße, Robert

Aber bitte nicht lachen… ist mein erster Versuch…

Die Datei ist eine Textdatei, die untereinandergeschriebene Zahlen enthält…

Die Fehlermeldung lautet:
47: warning: assigment from incompatible pointer type

PS. ich habe „_“ wegen der Lesbarkeit eingefügt…

#include

char dateiname[20];
long *dateieinlesen(char dname[20]);
long *temp;

int main(void)
{
__printf („Geben Sie den Dateiname ein: „);
__scanf(“%s“, dateiname);
__temp=(dateieinlesen(dateiname);
__printf(„Inhalt der Datei: %d\n“,temp);
__return 0;
}

long *dateieinlesen(char dname[20])
{
__int puffer=0;
__int seq[20], count;
__FILE *datei;
__long *z_seq;

__if ((datei=fopen(dname,„r“)) != NULL)
__{
____count=0;
____while ((fscanf(datei,"%d\n",&puffer)) != EOF)
____{
______seq[count]=puffer;
______count++;
______puffer=0;
____}
____fclose(datei);
____}
__else
__{
____fprintf(stderr, „\nFehler beim Oeffnen der Datei %s“, dname);
__}
__z_seq=seq; /*Zeile 48*/
__return z_seq;
}

Hallo Ali,

Aber bitte nicht lachen… ist mein erster Versuch…

Jeder hat einmal angefangen und hoffentlich aus den Fehlern gelernt !!!

Ich habe zwei Grundsätzliche Fehler entdeckt.
Zuerst zu der Fehlermeldung des Compilers:

int seq[20];
long *z_seq;
z_seq = seq; /*Zeile 48*/ Hier hast du die Fehlermeldung

int und long sind nicht das Gleiche !
z_seq ist ein Zeiger auf LONG.
seq ist ein Zeiger auf INT.

Da ein Zeiger einfach nur auf eine Speicheraddresse zeigt gibt es dann ganz lustige Resultate wenn dort ein 16-Bit-Wert abgelegt ist (z.B. int) und dann aber ein 32-Bit-Wert gelesen wird (z.B. long).
Werte kann der Compiler selber anpassen. Also bei „long = int“ kann der Compiler den „int“ einfach auf „long“ erweitern, aber bei Zeigern geht das nicht !

Das zweite, grundsätzliche Problem liegt in der Konstruktion:

long *dateieinlesen(char dname[20])
{
long *z_seq;

return z_seq;
}

long *z_seq; ist eine Auto-Variable und wird mit return ZERSTÖRT.

Also hier eine kleine einführung wie die Variablen in C verwaltet werden:

Allen Variablen welche AUSSERHALB einer Funktion deklariert werden wird ein fester Platz (Adresse) im Datensegment zugewiesen. Sie sind deshalb während der ganzen Laufzeit des Programms existent.

Alle Variablen welche INNERHALB einer Funktion deklariert werden werden auf dem Stack abgelegt. Der Speicher für diese Auto-Variablen wird erst festgelegt wenn diese Funktion aufgerufen wird und mit verlassen der Funktion wird dieser Speicherplatz wieder freigegeben. Ein Zeiger auf eine Auto-Variable zeigt nach dem verlassen der Funktion auf einen Speicherplatz welcher whrscheinlich schon wieder für eine andere Auto-Variable vergeben wurde. Das kann dann zu sehr „lustigen“ Fehlern im Programm führen.

Mit dem Schlüsselwort „static“ kann man dem Compiler mitteilen, dass er die Variable anders behandeln soll. Dabei hat „static“ drei verschiedene Auswirkungen, je nachdem wo es eingesetzt wird.
z.B.:
static char dateiname[20];

Eine Kleinigkeit habe ich noch vergessen zu erwähnen:
Ein Programm kann aus mehreren Modulen bestehen, welche getrennt compiliert werden und dan vom Linker zusammengesetzt werden. Du kannst also jede Funktion in eine Datei schreiben und jede Datei einzeln übersetzten, die Laufzeit-Bibliothek ist eigentlicht nichts Anderes.

Also eine Variable welche ausserhalb einer Funktion deklariert wurde ist automatisch GLOBAL, d.h. ein anderes Modul kann auf diese Variable zugreifen.
Wird eine solche Variable „static“ deklariert, so kann nur noch aus demjenigen Modul darauf zugegriffen werden in welchem sie deklariert wurde. Eine Variable in einem anderen Modul, mit dem gleichen Namen ist dann eine zweite Variable und bekommt ihren eigen Platz im Speicher. z.B.:
static char dateiname[20];

Für Funktionen gilt das selbe wie für globale Variablen und auch sie können mit „static“ vor anderen Modulen versteckt werden z.B.:
static long *dateieinlesen(char dname[20])
{
}

Wird eine Variable innerhalb einer Funktion als „static“ deklariert, dann wird sie nicht mehr auf dem Stack abgelegt, sondern wie eine gloabale Variable abgespeichert. Allerdings ist sie nur innerhalb der Funktion „sichtbar“. Beispiel:
long *dateieinlesen(char dname[20])
{
static long seq[20];

return seq;
}

MfG Peter(TOO)

PS. ich habe „_“ wegen der Lesbarkeit eingefügt…

Nachdem dem vorherigen Posting eigentlich nichts hinzuzufügen ist, nur noch eine Kleinigkeit, wenn du Source postet, dann am besten innerhalb eines PRE-Tags, dann bleiben Einrückungen erhalten.

Wenn du einen Artikel schreibst, dann hast du eh den Link „Hilfe zur Anwendung der HTML-Tags“, da steht das beschrieben.

Grüße, Robert

Danke für die Antwort.
Heute hatte ich mein Quellcode bei einem Freund mit Visual C++ probiert. Da gab es keine Fehlermeldung.
Anscheinend wurde der Fehler mit dem int seq[20] und long z_seq, wie du schön erklärt hast, vom Compiler „automatisch“ gelöst… Warum konnte es der gcc nicht???
Naja, nun habe ich aber ein weiteres Problem. Das hat wahrscheinlich genau mit dem Problem, dass du mir versuchst zu erkären zu tun. Nachdem ich z_seq an das main-Programm (temp)übergebe und mit einer for-Schleife *temp++ ausführe, hätte ich erwartet, das hier das Array seq[20] durchlaufen wird… anscheinend muss ich noch ein wenig mehr (bzw. besser) mit dem Thema Zeiger und Variablen beschäftigen…
Ich melde mich dann…
Danke noch mal…

Hallo,

Danke für die Antwort.
Heute hatte ich mein Quellcode bei einem Freund mit Visual C++
probiert. Da gab es keine Fehlermeldung.
Anscheinend wurde der Fehler mit dem int seq[20] und long
z_seq, wie du schön erklärt hast, vom Compiler „automatisch“
gelöst… Warum konnte es der gcc nicht???

NEIN: Hier ist der VC+±Compiler zu blöd, einen Zeiger kannst du eben NICHT von *int auf *long convertieren !!!

Naja, nun habe ich aber ein weiteres Problem. Das hat
wahrscheinlich genau mit dem Problem, dass du mir versuchst zu
erkären zu tun. Nachdem ich z_seq an das main-Programm
(temp)übergebe und mit einer for-Schleife *temp++ ausführe,
hätte ich erwartet, das hier das Array seq[20] durchlaufen
wird.

RICHTIG: Dein Programm hat 2 grundsätzliche Fehler.

… anscheinend muss ich noch ein wenig mehr (bzw. besser)
mit dem Thema Zeiger und Variablen beschäftigen…

Vor allem must du dir klar werden, wie der Speicher verwaltet wird.

MfG Peter(TOO)