C Problem bei Übergabe mehrdimensionalem Array in Funktion (Hi-Tech C 3.09)

  • Habe ein Problem mit Hi-Tech C (3.09), aber vielleicht ist das gar nicht Hi-Tech spezifisch.


    Ich habe eine Funktion und ein Hauptprogramm in einer C-Quelldatei (ich lasse mal unwichtiges weg und zeige nur den "Rumpf"):


    01:#include "stdio.h"

    02:

    03:void funktion(char array[][][], int nummer) {

    04: printf("array[%d][0][0] = %d\n", nummer, array[nummer][0][0]);

    05:}

    06:

    07:int main() {

    08: char feld[2][2][2];

    09:

    10: feld[1][0][0]=32;

    11:

    12: funktion(feld,1);

    13:

    14: return 0;

    15:}



    Der Compiler mag Zeile 4 und Zeile 12 nicht.

    Wie definiere ich die Funktion ab Zeile 3, so dass ich in der Funktion selbst wieder auf das Array mit einem Index zugreifen kann ?

    Arrays sind erstmal bei Übergabe nur Adressen. Irgendwie schnallt der Hi-Tech C Compiler das aber nicht.

    Oder er kann keine mehrdimensionalen Felder übergeben.

    Stehe irgendwie auf dem Schlauch momentan.

    "Ich habe keine Zeit mich zu beeilen." (Igor Strawinsky)


    ... und schaut auch mal bei meinem Blog vorbei ...

    Edited once, last by Peter z80.eu ().

  • P.S. : Wenn ich das statt in Hi-Tech C in Turbo C mache, und das wie folgt abändere, geht es in Turbo C:


    01:#include "stdio.h"

    02:

    03:void funktion(char array[2][2][2], int nummer) {

    04: printf("array[%d][0][0] = %d\n", nummer, array[nummer][0][0]);

    05:}

    06:

    07:int main() {

    08: char feld[2][2][2];

    09:

    10: feld[1][0][0]=32;

    11:

    12: funktion(feld,1);

    13:

    14: return 0;

    15:}


    Das geht aber so leider nicht in Hi-Tech C.

    "Ich habe keine Zeit mich zu beeilen." (Igor Strawinsky)


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Das Array wird schon als Pointer übergeben, aber die Zeile 3 bei Hi-Tech C ist nach Ansi falsch. Es darf kein mehrdimensionales Array auf diese Weise ohne Grössenangaben übergeben werden. Die Angabe bei Turbo-C ist dagegen korrekt und sollte auf jeden Fall funktionieren, ausser der Compiler ist fehlerhaft.

    Was bekommst du den für eine Fehlermeldung? Die sollte bei solchen Fragen auf jeden Fall mit angegeben werden.

    Die Alternative wäre das als Pointer (int ***feld) zu übergeben, damit würde es funktionieren.

  • Wir reden von einem alten C-Compiler für CP/M...


    Die Adresse (auf den Anfang des Felds) wird korrekt übergeben, habe das mit einem anderen Testprogramm extra nachgeprüft.


    Mit typedef kommen noch mehr Fehlermeldungen.


    Mit ***feld verliere ich die Möglichkeit, das als Array mit Indices in der Funktion zu benutzen.


    Ich möchte nicht einen einzigen Feldinhalt in die Funktion übergeben, sondern das gesamte Array.




    Ich habe folgenden Workaround erarbeitet, aber ich möchte eigentlich nur feld[index1][index2][index3] in der Funktion benutzen:


    #include "stdio.h"


    void funktion(char *pointer,int m,int n,int o) {


    int index1,index2,index3;


    for (index1=0;index1<m;index1++) {

    for (index2=0;index2<n;index2++) {

       for (index3=0;index3<o;index3++) {

        printf("array[%d][%d][%d] = %d\n", index1, index2, index3,

    *(pointer+index1*n*o+index2*o+index3) );

    }

    }

    }

    }


    int main() {

    char feld[2][2][3]; /* 2*2*3= 12 array fields in total */


    feld[0][0][0]=1;

    feld[0][0][1]=2;

    feld[0][0][2]=3;

    feld[0][1][0]=4;

    feld[0][1][1]=5;

    feld[0][1][2]=6;

    feld[1][0][0]=7;

    feld[1][0][1]=8;

    feld[1][0][2]=9;

    feld[1][1][0]=10;

    feld[1][1][1]=11;

    feld[1][1][2]=12;

    funktion(feld,2,2,3);


    return 0;

    }


    Damit werden alle Werte korrekt ausgegeben. Sieht aber nicht gerade elegant aus.


    P.S.: Einrückungen gehen hier bei der Forensoftware immer flöten, sorry.

    "Ich habe keine Zeit mich zu beeilen." (Igor Strawinsky)


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Das Übergeben von array wird immer als Pointer gemacht (intern). Aber: die Funktion muß das array nochmal "definieren", aber es muß nicht vollständig sein. Es reicht daher auch, wenn man char feld[][2][2] im Funktionskopf übergibt. Es darf aber natürlich auch die dritte, vorderste leere Klammer noch gefüllt sein, sie muß aber nicht. Das ist bei einfachen arrays genauso, weil dort aber eben nur eine Dimension da ist, und die freibleiben darf, kann man auch char array[] schreiben.


    Um sowas aufzurufen, reicht es dann aber den Arraynamen ohne Klammern zu benutzen, also functionname(feld) oder functionname(array).


    Bei Zeile 4 würde ich sagen, daß es einfach daran liegt, daß da ein %d im printf steht, aber die Variable als char definiert ist - weshalb man da mal ein %c probieren könnte, als Platzhalter.

  • Die Funktion muss aber die Länge der einzelnen Dimensionen kennen. Sonst kann sie das Array nicht mehrdimensional indizieren.

  • Da ihr scheinbar selbst das Ganze nicht ausprobiert habt, sind da leider alle Antworten nur Mutmaßungen.

    Eine Übergabe mit array[][2][2] erzeugt natürlich auch einen Fehler.

    Ich glaube ich nutze meinen Workaround. Wird wohl am Compiler liegen, der ist einfach schon zu alt.


    Die Fehlermeldung bei Angabe der eckigen Klammern in der Funktionsparameterübergabe lautet:

    "Expression too complicated"

    "Ich habe keine Zeit mich zu beeilen." (Igor Strawinsky)


    ... und schaut auch mal bei meinem Blog vorbei ...

    Edited once, last by Peter z80.eu ().

  • Also hier geht das mit gcc in der Form einwandfrei



    Wenn man die "2" in den Funktionskopf mitreinschreibt, geht es natürlich auch.


    Was auch gehen sollte ist einen Zeiger definieren und mit &feld auf den Anfang zeigen lassen. Das kann man dann auch übergeben, aber damit fehlen dann wieder die Größen für die Arraylines.


    gcc 4.9.2


    %c geht erstaunlicherweise wieder mal nicht in printf . Das sind so diese C Fallen für Anfänger ... (shame).

    Da kommt dann nur ein ASCII Zeichen statt einer Zahl.

    • Official Post

    Hast du den mal in der Doku geschaut ob der Hi-Tech C ueberhaupt mehrdimensionale Felder unterstuetzt?

  • Über dieses Thema schweigt sich das User Manual aus. Wie gesagt, habe halt den Hi-Tech C bisher für CP/M genutzt. Kann auch mal einen anderen CP/M C-Compiler nutzen, aber die sind alle nicht ANSI-C kompatibel. Ich entwickle gerade ein Terminal-Testprogramm für CP/M, welches die Terminal ESC-Sequenzen aus einer Konfigurationsdatei (Text, editierbar) in ein mehrdimensionales Feld einliest. Um möglichst modular die Quelldatei zu entwerfen, war halt die Ausgabe der ESC-Sequenzen in einer Funktion angedacht.

    "Ich habe keine Zeit mich zu beeilen." (Igor Strawinsky)


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Laut http://www.cpcwiki.eu/index.php/Hi-Tech_C_compiler soll ANSI C (ANSI X3.159-1989 ?) unterstützt sein und damit auch multidimensionale Felder. Aber gut, k.A. von welcher Version hier die Rede ist. (war angegeben, sorry)


    Wenn man nach "Expression too complicated" sucht kommen einige Hinweise...zwar hier für Watcom C aber ggf. ein Anhaltspunkt...

    E1086 Expression too complicated, split it up and try again
    The expression contains too many levels of nested parentheses. Divide the expression up into two or more sub-expressions.

    gut ist für Delphi aber die Grundaussage bleibt die selbe. Der Ausdruck ist zu komplex...

    The compiler has encounter an expression in your source code that is too complicated for it to handle.

    Reduce the complexity of your expression by introducing some temporary variables.


    char feld[2][2][3]; /* 2*2*3= 12 array fields in total */

    Müssten dass net 3*3*4 sein, wenn der Index bei Null beginnt (0-2, 0-2, 0-3) ? :/

    ne, passt 2 in Summe, also 0-1 usw. :fp:

  • Habe das mal auf Unixware 1.0 PE in der VirtualBox mit LPI-C 1.3.0 probiert, einem ANSI-C89 Compiler.

    Das Beispiel aus Post #1 ging so nicht. Mit der statischen Definition von array[][2][2] aus Post #7 ging das auf Anhieb. Den Fehler "Expression too complicated" konnte ich leider nicht reproduzieren. Da fehlt die Umgebung mit Hi-Tech C 3.09.




  • Code
    void funktion(char array[][][], int nummer)

    geht natürlich nicht, weil der Compiler die Arraydimensionen kennen muß. Sonst könnte er für die Funktion keinen Code erzeugen, um auf Elemente zuzugreifen.


    Ich finde etwas wie

    am saubersten. Falls der Compiler das nicht mag, ist das natürlich ärgerlich.

  • Ich würde ja vorschlagen, daß man mal probier, ob nicht der Vorschlag von funkenzupfer schon des Rätsels Lösung ist. Das kann man auch einfach mal ohne function testen, ob da mehrdimensionale Arrays überhaupt bekannt sind.


    In der Doku taucht das Wort kaum auf (p16) und nur in einem Beispiel ganz hinten mal als eindimensionales array[100]. Außerdem steht am Anfag was davon, daß der ANSI Standard noch nicht beschlossen war, weshalb man sich zwar bemüht habe, das Ganze daran anzulehnen, aber ob das dazugehört, geht daraus nicht hervor.