C - передача 2d массива в качестве аргумента функции? - PullRequest
10 голосов
/ 28 июля 2011

Можно легко определить функцию, которая принимает аргумент 1d array, например:

int MyFunction( const float arr[] )
{    
    // do something here, then return...

    return 1

}

Хотя такое определение, как: int MyFunction( const float* arr ) также будет работать.

Как можноопределить функцию, которая принимает аргумент 2d array?

Я знаю, что это работает: int MyFunction( const float** arr ) - но возможно ли использовать первый вариант, который использует []?

Ответы [ 5 ]

30 голосов
/ 28 июля 2011

В C99 вы можете указать размеры массива перед его передачей:

 void array_function(int m, int n, float a[m][n])
 {
      for (int i = 0; i < m; i++)
          for (int j = 0; j < n; j++)
              a[i][j] = 0.0;
 }


 void another_function(void)
 {
     float a1[10][20];
     float a2[15][15];
     array_function(10, 20, a1);
     array_function(15, 15, a2);
 }
6 голосов
/ 28 июля 2011

Попробуйте что-то вроде этого:

int MyFunction(size_t ncols, const float arr[][ncols])
{    
    // ...
}
3 голосов
/ 14 марта 2016

когда мы передаем 2D-массив в качестве аргументов для функций, необязательно указывать большинство левых измерений. Ключевым моментом здесь является то, когда любые изменения, внесенные в функции, отражаются в вызывающих функциях, потому что, когда мы передаем 2-D массив в качестве аргументов означает, что на самом деле функции получают указатель на одномерный массив. И размер этого числа столбцов. Примеры

1 - int funct(int (*a) [4]);

здесь a указатель на массив целых чисел. мы можем просто так пройти и

2- void funct(int a[][4]);

как я говорил ранее, левая сторона всегда необязательна. В первом примере размер a будет 4, потому что обычно это просто указатель. в то время как размер * a будет 16, потому что у нас есть 4 столбца, и для каждого столбца у нас есть 4 байта, поэтому 4 * 4 = 16 байтов.

Но наиболее предпочтительным способом всегда является использование динамического выделения памяти.

Надеюсь, у тебя все ясно

0 голосов
/ 29 июля 2011

Хакерский путь - передать первый элемент и выполнить вычисления массива вручную.

В этом длинном примере используется макрос для полуавтоматического извлечения измерений массива для использования в вызове.

struct font { int disp, trig; };
struct font font3[3][3];
#define dim(x) (sizeof(x)/sizeof*(x))
#define font_and_dims(x) (struct font *)x, dim(x), dim(*x)
int print(char *s, struct font *font, int dimy, int dimx) { ... }

main(){ ...   print(*av, font_and_dims(font3));   ... }

Вызываемая функция обращается к массиву трудным путем.

print(){ ...   font[row*dimx+col]   ... }

Не бойтесь прокрутить вниз: хорошие вещи находятся внизу!Эта уродливая педантичная функция в верхней части обеспечивает максимальную переносимость кодировки;но это это бельмо на глазу, я признаю.

#include <stdio.h>
#include <string.h>

int ao(int c) {
    switch(c) {
    case '0':return 0;
    case '1':return 1;
    case '2':return 2;
    case '3':return 3;
    case '4':return 4;
    case '5':return 5;
    case '6':return 6;
    case '7':return 7;
    case '8':return 8;
    case '9':return 9;
    case 'A':case 'a':return 10;
    case 'B':case 'b':return 11;
    case 'C':case 'c':return 12;
    case 'D':case 'd':return 13;
    case 'E':case 'e':return 14;
    case 'F':case 'f':return 15;
    default:return -1;
    }
}

enum {
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6,
    H = 1 << 7 };

int seg[] = {
    /*0*/ A|B|C|D|E|F,
    /*1*/   B|C,
    /*2*/ A|B|  D|E|  G,
    /*3*/ A|B|C|D|    G,
    /*4*/   B|C|    F|G,
    /*5*/ A|  C|D|  F|G,
    /*6*/ A|  C|D|E|F|G,
    /*7*/ A|B|C,
    /*8*/ A|B|C|D|E|F|G,
    /*9*/ A|B|C|    F|G,
    /*A*/ A|B|C|D|E|  G, /*A|B|C|  E|F|G,*/
    /*b*/     C|D|E|F|G,
    /*C*/       D|E|  G, /*A|    D|E|F,*/
    /*d*/   B|C|D|E|  G,
    /*E*/ A|B|  D|E|F|G, /*A|    D|E|F|G,*/
    /*F*/ A|      E|F|G,
};

struct font {
    int disp, trig;
};
/* _
  |_|
  |_|
*/
struct font font3[3][3] = {
    { {  0,0}, {'_',A}, {  0,0} },
    { {'|',F}, {'_',G}, {'|',B} },
    { {'|',E}, {'_',D}, {'|',C} },
};
/* ___
  |   |
  |___|
  |   |
  |___|
*/
struct font font5[5][5] = {
    { {  0,0}, {'_',A}, {'_',A}, {'_',A}, {  0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {'|',B} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'|',B} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {'|',C} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'|',C} }
};
/* ____
  |    |
  |    |
  |    |
  |____|
  |    |
  |    |
  |    |
  |____|
*/
struct font font9[9][7] = {
    { {  0,0}, {'_',A}, {'_',A}, {'_',A}, {'_',A}, {  0,0}, {0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
    { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'_',G}, {'|',B}, {0,0} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
    { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'_',D}, {'|',C}, {0,0} },
};

#define dim(x) (sizeof(x)/sizeof*(x))
#define font_and_dims(x) (struct font *)x, dim(x), dim(*x)

int print(char *s, struct font *font, int dimy, int dimx) {
    int row, col;
    char *sp;
    for (row = 0; row < dimy; row++) {
    for (sp = s; *sp; sp++) {
        for (col = 0; col < dimx; col++) {
            putchar( seg[ao(*sp)] & font[row*dimx+col].trig ?
                font[row*dimx+col].disp : ' ');
        }
    }
    putchar('\n');
    }
}

int main(int ac, char **av) {
    enum { F1, F2, F3 } fz = F1;
    for (++av,--ac;ac;ac--,av++) {
    if (av[0][0] == '-') {
        switch (av[0][1]) {
            case '1': fz=F1; continue;
            case '2': fz=F2; continue;
            case '3': fz=F3; continue;
            default: fprintf(stderr, "Unrecognized Option!\n");
        }
    }
    if (strspn(*av, "0123456789abcdefABCDEF") != strlen(*av))
        fprintf(stderr, "Hex only!\n");
    else
        switch(fz) {
            case F1: print(*av, font_and_dims(font3)); break;
            case F2: print(*av, font_and_dims(font5)); break;
            case F3: print(*av, font_and_dims(font9)); break;
            default: fprintf(stderr, "Invalid Font!\n");
        }
    }

    return 0;
}
0 голосов
/ 28 июля 2011

В C89 вы можете использовать

typedef float OneRow[2];

void func(OneRow *arr)
{
  printf("%f",arr[1][0]);
}
...
  OneRow arr[] = {{1,2},{3,4},{5,6}};
  func(arr);
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...