Matrix in Array speichern



  • fredneumi schrieb:

    wie kann ich aber den maximal wert bestimmen. die matrix kann ja verschieden groß sein?

    Du musst wissen, wie welche Dimensionen die Matrix hat, sonst kannst du sie ja nicht anlegen. Zur Laufzeit eines C-Programmes gibt es keine Arrays mehr, weil die Elemente (wie oben gezeigt) nacheinander im Speicher abgelegt werden. Eine Information über die Dimension ist dann nicht mehr vorhanden.

    Dagegen werden zwei Techniken benutzt: 1.) man merkt sich die Dimension in irgendeiner Variable, oder 2.) man definiert einen Wert für das "Ende" der sinnvollen Daten, wie z.B. das Nullzeichen bei Zeichen-Arrays.



  • oder 3.) Man verwendet sizeof

    sizeof(A)/sizeof(**A));
    sizeof(A)/sizeof(A[0][0]));
    sizeof(A)/sizeof(double));
    


  • ergänzung schrieb:

    oder 3.) Man verwendet sizeof

    Hatte ich ganz vergessen. Dabei muss man als Anfänger aufpassen, dass man wirklich ein Array hat, und keinen Zeiger. Mich hat anfangs fein verwirrt, dass man Arrays nicht als Argumente übergeben kann.



  • fredneumi schrieb:

    hallo.
    ich muss aus einer Matrix : double A[2][3] = {{1,2,3},{4,5,6}};
    die Zahlen hintereinander in ein array speichern.

    Je nachdem welches Ordering (C verwendet row-major odering) erforderlich ist, reicht es einfach aus den Zeiger auf das erste Elemente zu übergeben.

    Zum Thema Ordering bitte folgenden Artikel durchlesen
    http://en.wikipedia.org/wiki/Row-major_order

    Da cBLAS column-major ordering nutzt, muß man auch zuweilen in C, das column-major ordering nutzen.



  • ~john schrieb:

    Da cBLAS...

    Bitte was?



  • mngbd schrieb:

    Bitte was?

    cBLAS ist ein Beispiel dafür, weshalb man manchmal column-major ordering in C braucht.



  • ~john schrieb:

    cBLAS ist ein Beispiel dafür, weshalb man manchmal column-major ordering in C braucht.

    Danke!
    🙂



  • asdf



  • fredneumi schrieb:

    super. geht gut. nun müsste ich aber noch die Anzahl der Spalten auslesen. Geht das irgendwie?

    Du mußt die notwendigen Informationen immer getrennt speichern, da sie C nicht vorhält.



  • sadf



  • fredneumi schrieb:

    kann man die spaltenanzahl überhaupt speichern?

    Mit sizeof ? Das geht z.B. so:

    #include <stdio.h>
    
    #define ZEILEN (2)
    #define SPALTEN (3)
    
    int main(void)
    {
        double A[ZEILEN][SPALTEN] = {{1,2,3},{4,5,6}};
    
        printf("zeilen: %d\n", sizeof(A) / sizeof(A[0]));
        printf("spalten: %d\n", sizeof(A[0]) / sizeof(A[0][0]));
    }
    

    Das darf dich aber nicht darüber hinwegtäuschen, dass diese Zahlen schon zur Compilezeit feststehen. In diesem Sinn ist der sizeof-Operator nur eine Schreibhilfe.

    Nachtrag: in C99 müssen diese Dimensionen nicht unbedingt zur Compilezeit bekannt sein, weil es Arrays mit variabler Länge gibt.



  • asdf



  • fredneumi schrieb:

    Wenn ich das mache hier: *azeiger[0] + *bzeiger[k];
    mäckert der compiler... hat jmd ne ahnung wieso?

    Keine Ahnung, ist das ein C++-Compiler? Anyway, versuch mal statt Zeile 6:

    double *zeiger = &A[0][0];
    


  • sadf



  • fredneumi schrieb:

    gcc compiler.
    mit dem gehts auch nicht 😞

    Ich blick gerade nicht völlig durch, bitte zeig ein kurzes lauffähiges Beispiel, in dem das Problem besteht.



  • asdf



  • Ok. Wie du die Warnungen in den Zeilen 10 und 11 loswirst, hab ich oben schon gesagt (der gcc übertreibt die Warnungen gelegentlich, man kann sie sicher auch über irgendeinen Schalter abstellen).

    Die Fehler kommen von einem logischen Problem: azeiger und bzeiger sind ein double * , für einen Ausdruck wie *azeiger[0] müssten sie aber ein double ** sein, weil da zwei Dereferenzierungen drinnen stecken: eine macht der * und die andere die [].

    Versuch mal:

    C[i][j] = azeiger[0] * bzeiger[k+1] + azeiger[1] * bzeiger[k+2] + azeiger[2] * bzeiger[k+3];
    

    Vielleicht ist es das, was du willst.
    🙂



    • Anstatt (azeiger[0]) willst du wohl nur azeiger[0] haben.
      a[b] ist äquivalent zu (
      (a + b)).
    C[i][j] = (*azeiger[0]) * (*bzeiger[k+1]) + (*azeiger[1]) * (*bzeiger[k+2]) + (*azeiger[2]) * (*bzeiger[k+3]);
    /* korrekt: */
    C[i][j] = *azeiger[0]*bzeiger[k+1] + azeiger[1]*bzeiger[k+2] + azeiger[2]*bzeiger[k+3];
    

    k = k + 3;
    /* schöner: /
    k += 3 /
    oder noch schöner, im for-Schleifenkopf

    *  ```cpp
    double A[4][3] = {{2,-1,3},{1,0,8},{-6,3,4},{9,8,7}};
    /* besser: */
    double A[][] = {{2,-1,3},{1,0,8},{-6,3,4},{9,8,7}};
    

    Die Zahlen kannst du in diesem Falle weglassen.

    double azeiger = A;
    /
    besser: */
    double *azeiger = A[0];

    *  ```cpp
    int laengea, laengeb;
    laengea = sizeof(A)/sizeof(A[0][0]);
    laengeb = sizeof(B)/sizeof(B[0][0]);
    /* besser: */
    const int laengea = sizeof(A)/sizeof(A[0][0]),
              laengeb = sizeof(B)/sizeof(B[0][0]);
    

    for (i = 1; i > 4; i++) {
    for (j = 1; j > 5; j++) {
    /* warum ist da nicht /
    for (i = 0; i < 4; i++) {
    for (j = 0; j < 5; j++) {
    /
    oder besser */
    for (i = 0; i < sizeof(C)/sizeof(*C); ++i) {
    for (j = 0; j < sizeof(*B)/sizeof(**B); ++j) {

    *  ```cpp
    return(0);
    /* schöner: */
    return 0;
    /* oder (eher unschöner): */
    return EXIT_SUCCESS; /* benötigt #include <stdlib.h> */
    

    Das ist (hoffentlich) alles 😉



  • asdf



  • fredneumi schrieb:

    Programm stürtz ab, und keine Ausgabe. Was ist da noch falsch?

    Welchen Wert hat k beim ersten Schleifendurchlauf?


Anmelden zum Antworten