C: Größe des zweidimensionalen Arrays

Lesezeit: 12 Minuten

Ich brauche Hilfe beim Zählen der Zeilen und Spalten eines zweidimensionalen Arrays. Anscheinend kann ich keine Spalten zählen?

#include <stdio.h>

int main() {

char result[10][7] = {

    {'1','X','2','X','2','1','1'},
    {'X','1','1','2','2','1','1'},
    {'X','1','1','2','2','1','1'},
    {'1','X','2','X','2','2','2'},
    {'1','X','1','X','1','X','2'},
    {'1','X','2','X','2','1','1'},
    {'1','X','2','2','1','X','1'},
    {'1','X','2','X','2','1','X'},
    {'1','1','1','X','2','2','1'},
    {'1','X','2','X','2','1','1'}

};

int row = sizeof(result) / sizeof(result[0]);
int column = sizeof(result[0])/row;

printf("Number of rows: %d\n", row);
printf("Number of columns: %d\n", column);

}

Ausgabe:

Reihenzahl: 10
Anzahl der Spalten: 0

  • int column = sizeof(result[0])/sizeof(result[0][0]);

    – BLUEPIXY

    7. Dezember 2015 um 12:57 Uhr

  • Da sie statisch sind, warum sollten Sie sie überhaupt zählen wollen? Definieren Sie einfach Konstanten für die Zeilen- und Spaltengröße, anstatt “magische Zahlen” zu verwenden.

    – Ludin

    7. Dezember 2015 um 13:36 Uhr

Das ist ein Problem der ganzzahligen Division!

int column = sizeof(result[0])/row;

sollte sein

int column = 7 / 10;

und in ganzzahliger Division, 7/10==0.

Was Sie tun möchten, ist die Länge einer Reihe zu teilen, z. sizeof(result[0]) durch die Größe eines Elements dieser Zeile, z. sizeof(result[0][0]):

int column = sizeof(result[0])/sizeof(result[0][0]);

  • Das ist falsch. Hier teilen Sie 7 (Anzahl der Elemente in der ersten Zeile) durch 1 (Anzahl der Zeichen in der ersten Zeile). result[0][0]).

    – Emi

    7. Dezember 2015 um 13:23 Uhr

  • Warum ist das falsch? sizeof (Ergebnis) = 70, sizeof (Ergebnis[0]) = 7, Größe von (Ergebnis[0][0]) = 1, also stimmt die Zeilenzahl = 70/7 = 10 und die Spaltenzahl = 7/1 = 7 ist auch richtig. Auch wenn Sie den Typ von char in int geändert haben (unter der Annahme von int = 32 Bits), sizeof (Ergebnis) = 280, sizeof (Ergebnis[0]) = 28, Größe von (Ergebnis[0][0]) = 4, also wie man wieder sieht, stimmt die Zeilenzahl = 280/28 = 10 und die Spaltenzahl = 28/4 = 7 stimmt auch.

    – ZeZNiQ

    14. Februar 2020 um 13:59 Uhr

Es ist viel bequemer (und weniger fehleranfällig), ein Array-Längenmakro zu verwenden:

#include <stdio.h>

#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))

int main(void)
{
    char result[10][7];

    printf("Number of rows: %d\n", LEN(result));
    printf("Number of columns: %d\n", LEN(result[0]));
    return 0;
}

  • Warum der Integer-Cast auf die LEN Makro? Sind Arrays nicht homogene Datenstrukturen, dh der Nenner ist immer ein Vielfaches des Nenners? Außerdem sollte die Sparte nicht zurückkommen unsigned integeroder size_twas bereits ein ganzzahliger Typ ist?

    – Rafa Viotti

    3. Mai 2017 um 0:37 Uhr

  • @Rafa Wir können auf die Besetzung verzichten, wenn wir den Formatbezeichner ändern %d zu %lu. Wann LEN wird in einem verwendet for Loop Guard müssen wir dann einen Cast verwenden oder die Indexvariablen mit Typ deklarieren Größe_t.

    – August Karlström

    3. Mai 2017 um 8:07 Uhr

  • Stimme dem „weniger fehleranfällig“ zu; die Idee ist nett, aber gefährlich; Es gibt viele Möglichkeiten, ein Array implizit in einen Zeigertyp zu konvertieren, und eine davon ist besonders gefährlich: Jemand versucht, Zeilen zu durchlaufen und so etwas zu tun LEN(result++) in einer Schleife.

    – Markus Müller

    20. Januar 2021 um 11:05 Uhr

  • @MarcusMüller Ja, Ausdrücke mit Nebenwirkungen zu haben ist hässlich und fehleranfällig, und Ihr Beispiel zeigt, warum es vermieden werden sollte. Auch wenn Sie die verwenden sizeof Operator direkt müssen Sie noch wissen, ob Sie einen Zeiger oder ein Array haben.

    – August Karlström

    20. Januar 2021 um 13:06 Uhr

Benutzer-Avatar
Emi

Das funktioniert für mich (Kommentare erklärt warum):

#include <stdio.h>

int main() {

   char result[10][7] = {

       {'1','X','2','X','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'1','X','2','X','2','2','2'},
       {'1','X','1','X','1','X','2'},
       {'1','X','2','X','2','1','1'},
       {'1','X','2','2','1','X','1'},
       {'1','X','2','X','2','1','X'},
       {'1','1','1','X','2','2','1'},
       {'1','X','2','X','2','1','1'}

   }; 

   // 'total' will be 70 = 10 * 7
   int total = sizeof(result);

   // 'column' will be 7 = size of first row
   int column = sizeof(result[0]);

   // 'row' will be 10 = 70 / 7
   int row = total / column;

   printf("Total fields: %d\n", total);
   printf("Number of rows: %d\n", row);
   printf("Number of columns: %d\n", column);

}

Und die Ausgabe davon ist:

Total of fields: 70
Number of rows: 10
Number of columns: 7

BEARBEITEN:

Wie von @AnorZaken gezeigt, übergeben Sie das Array als Parameter an eine Funktion und drucken Sie das Ergebnis von sizeof darauf wird eine andere ausgegeben total. Dies liegt daran, dass C, wenn Sie ein Array als Argument übergeben (keinen Zeiger darauf), es als Kopie weitergibt und dazwischen etwas C-Magie anwendet, sodass Sie nicht genau dasselbe übergeben, wie Sie denken. Um sicher zu sein, was Sie tun, und um zusätzliche CPU-Arbeit und Speicherverbrauch zu vermeiden, ist es besser, Arrays und Objekte als Referenz (mithilfe von Zeigern) zu übergeben. Sie können also so etwas verwenden, mit den gleichen Ergebnissen wie das Original:

#include <stdio.h>

void foo(char (*result)[10][7])
{
   // 'total' will be 70 = 10 * 7
   int total = sizeof(*result);

   // 'column' will be 7 = size of first row
   int column = sizeof((*result)[0]);

   // 'row' will be 10 = 70 / 7
   int row = total / column;

   printf("Total fields: %d\n", total);
   printf("Number of rows: %d\n", row);
   printf("Number of columns: %d\n", column);

}

int main(void) {

   char result[10][7] = {

       {'1','X','2','X','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'1','X','2','X','2','2','2'},
       {'1','X','1','X','1','X','2'},
       {'1','X','2','X','2','1','1'},
       {'1','X','2','2','1','X','1'},
       {'1','X','2','X','2','1','X'},
       {'1','1','1','X','2','2','1'},
       {'1','X','2','X','2','1','1'}

   };

   foo(&result);

   return 0;
}

  • Nur-Code-Antworten ohne Erklärung sind für zukünftige Besucher oft sehr wenig hilfreich. Erwägen Sie, Ihre Antwort zu bearbeiten, um weitere Informationen/Einblicke in Ihren Lösungsprozess zu erhalten.

    – Magisch

    7. Dezember 2015 um 13:08 Uhr

  • Code ist für mich selbsterklärend, aber verstehe dich. Bearbeiten Sie jetzt die Antwort.

    – Emi

    7. Dezember 2015 um 13:11 Uhr

  • Ich möchte nur darauf hinweisen, dass dies speziell bei Arrays, die als Funktionsargumente empfangen werden, nicht funktioniert total = sizeof result; funktioniert nicht: Es wird eine Warnung generiert und die Größe eines einzelnen Elements anstelle der Größe des gesamten Arrays ausgewertet. Also ist entweder VLA erforderlich (und Sie übergeben das Zeilen- und Spaltenargument) oder Sie müssen entweder die Zeilen- oder die Gesamtzahl als Argument übergeben (Spalte kann immer noch mit sizeof bestimmt werden).

    – AnorZaken

    25. Oktober 2017 um 18:30 Uhr

  • Hallo @AnorZaken. Wenn Sie die Variable als Zeiger darauf übergeben, wo sich die Daten befinden, a sizeof on gibt die Größe des Zeigers auf die Variable zurück, nicht die der Variablen selbst. In diesem Fall können Sie versuchen, a sizeof zu den Daten, auf die der Zeiger zeigt, mit etwas wie: total = sizeof(*result);

    – Emi

    26. Oktober 2017 um 19:03 Uhr

  • @AnorZaken Ich habe gerade die Antwort bearbeitet, um Ihre spezifische Frage zu beantworten.

    – Emi

    28. Oktober 2017 um 10:59 Uhr

    // gets you the total size of the 2d array 
    printf("Arrays Total size: %ld\n",sizeof(result));

    // gets you the cumulative size of row which is 5 columns * sizeof(int)
    printf("1 row cumulative size: %ld\n",sizeof(result[0]));

    // division of total array size with cumulative size of row gets you total number of rows
    printf("total number of rows: %ld\n",sizeof(result)/sizeof(result[0]));

    // and total number of columns you get by dividing cumulative row size with sizeof(char)
    printf("total number of columns: %ld\n",sizeof(result[0])/sizeof(char));

Benutzer-Avatar
kaali-keshav

Verwenden Sie die im folgenden Code gezeigten Makros, um eine beliebige Dimensionsgröße von 1D-, 2D- oder 3D-Arrays zu erhalten. Weitere Makros können auf ähnliche Weise geschrieben werden, um Dimensionen für 4D-Arrays und darüber hinaus zu erhalten. (Ich weiß, es ist zu spät für Wickerman, um einen Blick darauf zu werfen, aber dies ist für alle anderen, die diese Seite besuchen.)

// Output of the following program
// [
/*

Demo of the advertised macros :
----------------------------------------------
sizeof(int) = 4
sizeof(Array_1D) = 12
ELEMENTS_IN_1D_ARRAY(Array_1D) = 3
sizeof(Array_2D) = 24
ELEMENTS_IN_2D_ARRAY(Array_2D) = 6
ROWS_IN_2D_ARRAY(Array_2D) = 2
COLUMNS_IN_2D_ARRAY(Array_2D) = 3
sizeof(Array_3D) = 96
ELEMENTS_IN_3D_ARRAY(Array_3D) = 24
MATRICES_IN_3D_ARRAY(Array_3D) = 4
ROWS_IN_3D_ARRAY(Array_3D) = 2
COLUMNS_IN_3D_ARRAY(Array_3D) = 3

Array_3D[][][] Printed :
----------------------------------------------
 001 002 003
 011 012 013
---------------
 101 102 103
 111 112 113
---------------
 201 202 203
 211 212 213
---------------
 301 302 303
 311 312 313
---------------

Wickerman's problem solved :
----------------------------------------------
sizeof(result) = 70
ELEMENTS_IN_2D_ARRAY(result) = 70
ROWS_IN_2D_ARRAY(result) = 10
COLUMNS_IN_2D_ARRAY(result) = 7

*/
// ]

// ====================================================================================================
// Program follows
// ====================================================================================================

// Array Size Macros
// [
#define ELEMENTS_IN_1D_ARRAY(a1D)   ( sizeof( a1D       ) / sizeof( a1D[0]          )) // Total no. of elements in 1D array
#define ELEMENTS_IN_2D_ARRAY(a2D)   ( sizeof( a2D       ) / sizeof( a2D[0][0]       )) // Total no. of elements in 2D array
#define ROWS_IN_2D_ARRAY(a2D)       ( sizeof( a2D       ) / sizeof( a2D[0]          )) // No. of Rows in a 2D array
#define COLUMNS_IN_2D_ARRAY(a2D)    ( sizeof( a2D[0]    ) / sizeof( a2D[0][0]       )) // No. of Columns in a 2D array
#define ELEMENTS_IN_3D_ARRAY(a3D)   ( sizeof( a3D       ) / sizeof( a3D[0][0][0]    )) // Total no. of elements in 3D array
#define MATRICES_IN_3D_ARRAY(a3D)   ( sizeof( a3D       ) / sizeof( a3D[0]          )) // No. of "Matrices" (aka "Slices"https://stackoverflow.com/"Pages") in a 3D array
#define ROWS_IN_3D_ARRAY(a3D)       ( sizeof( a3D[0]    ) / sizeof( a3D[0][0]       )) // No. of Rows in each "Matrix" of a 3D array
#define COLUMNS_IN_3D_ARRAY(a3D)    ( sizeof( a3D[0][0] ) / sizeof( a3D[0][0][0]    )) // No. of Columns in each "Matrix" of a 3D array
// ]

#define PRINTF_d(s) (printf(#s " = %d\n", (int)(s)))    // Macro to print a decimal no. along with its corresponding decimal expression string,
                                                        // while avoiding to write the decimal expression twice.

// Demo of the Array Size Macros defined above
// [
main()
{
    // Sample array definitions
    // [
    int Array_1D[3] = {1, 2, 3};    // 1D array

    int Array_2D[2][3] =            // 2D array
    {
        {1,  2,  3},
        {11, 12, 13}
    };

    int Array_3D[4][2][3] =         // 3D Array
    {
        {
            {1,   2,   3},
            {11,  12,  13}
        },
        {
            {101, 102, 103},
            {111, 112, 113}
        },
        {
            {201, 202, 203},
            {211, 212, 213}
        },
        {
            {301, 302, 303},
            {311, 312, 313}
        }
    };
    // ]

    // Printing sizes and dimensions of arrays with the advertised Array Size Macros
    printf(
    "Demo of the advertised macros :\n"
    "----------------------------------------------\n");
    PRINTF_d(sizeof(int));
    PRINTF_d(sizeof(Array_1D));
    PRINTF_d(ELEMENTS_IN_1D_ARRAY(Array_1D));
    PRINTF_d(sizeof(Array_2D));
    PRINTF_d(ELEMENTS_IN_2D_ARRAY(Array_2D));
    PRINTF_d(ROWS_IN_2D_ARRAY(Array_2D));
    PRINTF_d(COLUMNS_IN_2D_ARRAY(Array_2D));
    PRINTF_d(sizeof(Array_3D));
    PRINTF_d(ELEMENTS_IN_3D_ARRAY(Array_3D));
    PRINTF_d(MATRICES_IN_3D_ARRAY(Array_3D));
    PRINTF_d(ROWS_IN_3D_ARRAY(Array_3D));
    PRINTF_d(COLUMNS_IN_3D_ARRAY(Array_3D));

    // Printing all elements in Array_3D using advertised macros
    // [
    int x, y, z;

    printf(
    "\nArray_3D[][][] Printed :\n"
    "----------------------------------------------\n");

    for(x = 0; x < MATRICES_IN_3D_ARRAY(Array_3D); x++)
    {
        for(y = 0; y < ROWS_IN_3D_ARRAY(Array_3D); y++)
        {
            for(z = 0; z < COLUMNS_IN_3D_ARRAY(Array_3D); z++)
                printf("%4.3i", Array_3D[x][y][z]);
            putchar('\n');
        }
        printf("---------------\n");
    }
    // ]

    // Applying those macros to solve the originally stated problem by Wickerman
    // [
    char result[10][7] = {
        {'1','X','2','X','2','1','1'},
        {'X','1','1','2','2','1','1'},
        {'X','1','1','2','2','1','1'},
        {'1','X','2','X','2','2','2'},
        {'1','X','1','X','1','X','2'},
        {'1','X','2','X','2','1','1'},
        {'1','X','2','2','1','X','1'},
        {'1','X','2','X','2','1','X'},
        {'1','1','1','X','2','2','1'},
        {'1','X','2','X','2','1','1'}
    };

    printf(
    "\nWickerman's problem solved :\n"
    "----------------------------------------------\n");
    PRINTF_d(sizeof(result)); // radha_SIZEOF_2D_ARRAY
    PRINTF_d(ELEMENTS_IN_2D_ARRAY(result)); // radha_SIZEOF_2D_ARRAY
    PRINTF_d(ROWS_IN_2D_ARRAY(result));
    PRINTF_d(COLUMNS_IN_2D_ARRAY(result));
    // ]
}
// ]

  • Hallo, bitte fügen Sie Ihrer Antwort eine Erklärung hinzu, um sie zuverlässiger zu machen

    – Mehrdad EP

    11. März 2019 um 10:20 Uhr

  • @MehrdadEP Dachte, der Code sei offensichtlich, fügte also keine Erklärung hinzu. Kommentare und Ausgabe jetzt hinzugefügt. Ich hoffe, das hilft.

    – kaali-keshav

    14. März 2019 um 8:36 Uhr


Benutzer-Avatar
LernenNoob123

Die anderen Antworten erklären das Konzept wirklich gut, sind aber nicht anfängerfreundlich; Also hier ist meine Version davon –

    #include <stdio.h>

    void main() {

      int arr [][3] = { {1,2,3 },
                       {4,5,6} };

      
        int size_row = sizeof(arr)/sizeof(arr[0]);
        int size_col = sizeof(arr[0])/sizeof(arr[0][0]);

        printf("Length of row : %d\n",size_row); *Output 24*
        printf("Length of column : %d",size_col); *Output 3*

        printf("\nTotal size of array : %d",sizeof(arr)); *Output 24*
        printf("\nSize of entire first row : %d",sizeof(arr[0])); *Output 12*
     printf("\nSize of first element of first row : %d",sizeof(arr[0][0])); *Output 3*

}

  • Hallo, bitte fügen Sie Ihrer Antwort eine Erklärung hinzu, um sie zuverlässiger zu machen

    – Mehrdad EP

    11. März 2019 um 10:20 Uhr

  • @MehrdadEP Dachte, der Code sei offensichtlich, fügte also keine Erklärung hinzu. Kommentare und Ausgabe jetzt hinzugefügt. Ich hoffe, das hilft.

    – kaali-keshav

    14. März 2019 um 8:36 Uhr


1367980cookie-checkC: Größe des zweidimensionalen Arrays

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy