Yves Medhard Tibe-bi
Yves Medhard Tibe-bi

Reputation: 33

How to pass a bidimensional matrix by parameter to a function in C

I have a question about matrices. I have a program to calculate checkers moves; I solved it in Java, but it won't run fast enough and I decided to try it in C.

The problem is that in Java I can pass a bidimensional matrix as a parameter to a function, but I can't do it in C. The compiler says that I can't. I dig here and on the web, and saw something of dynamic allocation and things like this, but I don't really understand.

My problem is:

Here is the code:

#include <stdio.h>
#include <stdlib.h>

int checagem(int m[][100], int xo, int xd, int yd, int n) {
    int r = 0;
    if (0 <= xd && xd < n && 0 <= yd && yd < n) {
        if (yd == 0) {
            if (m[yd][xd] != 1) {
                r += 1;
            }
        } else if (m[yd][xd] == 0 || m[yd][xd] == 2) {
            r += checagem(m, xd, xd - 1, yd - 1, n);
            r += checagem(m, xd, xd + 1, yd - 1, n);
        } else if (m[yd][xd] == 1) {
            if (xo - xd > 0) {
                if (pulavel(xd - 1, yd - 1, m, n)==1) {
                    r += checagem(m, xd, xd - 1, yd - 1, n);
                }
            } else if (xo - xd < 0) {
                if (pulavel(xd + 1, yd - 1, m, n)==1) {
                    r += checagem(m, xd, xd + 1, yd - 1, n);
                }
            }
        }
    } else {
        r += 0;
    }
    return r;
}

int pulavel(int x, int y, int m[][100], int n) {
    int r = 1;
    if (x < 0 || x > n - 1 || m[y][x] == 1) {
       r=0 ;
    }
    return r;
}

int main(){
    //variaveis
    int n = 0, t = 1, x = -1, y = -1, teste = 1;
    int i,j;
    //logica
    scanf("%d %*c",&t);

    while (teste > 0) {
        scanf("%d %*c",&n);
        if (n > 1 || n <= 100) {
            int tabuleiro[n][n];
            for (i = 0; i < n; i++) {
                char l[n];
                scanf("%s %*c", &l);
                for (j = 0; j < n; j++){
                    switch(l[j]){
                    case ('.'): tabuleiro[i][j] = 0;break;
                    case ('b'): tabuleiro[i][j] = 1;break;
                    case ('w'): tabuleiro[i][j] = 2;
                                x = j;
                                y = i;break;
                    }
                }
            }
            int r = checagem(tabuleiro, x, x, y, n);
            printf("%d", r); 
        }
    }
}

The input is like the contest from: http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=3108

Upvotes: 1

Views: 1942

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753870

Your problem is that you declare int tabuleiro[n][n]; in your main() function, but your checagem() function does not expect to be passed a VLA. You need to pass the dimension before the array, so revise it to be:

int checagem(int n, int m[n][n], int xo, int xd, int yd)
{
    ...
}

Then make sure you don't overflow the bounds of the array (because C won't stop you, of course).

You will need to make a parallel change to pulavel(), and change the calls to both functions, of course.

This compiles OK; I've not tried running it. Don't take addresses of arrays; it will confuse you, even if it doesn't confuse the compiler (it just whinged about the type mismatch in scanf("%s %*c", &l);). Do upgrade your code to check that the scanf() calls succeed. I'm not sure what format you're reading with scanf("%s %*c", l), but I suspect it is doing damage to the data that you don't expect. I reordered the functions and made them static (and added void to int main(void)) to avoid compilation warnings from my standard GCC compilation options:

gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c ck.c

Code:

#include <stdio.h>
#include <stdlib.h>

static
int pulavel(int n, int x, int y, int m[n][n])
{
    int r = 1;
    if (x < 0 || x > n - 1 || m[y][x] == 1)
       r=0;
    return r;
}

static
int checagem(int n, int m[n][n], int xo, int xd, int yd)
{
    int r = 0;
    if (0 <= xd && xd < n && 0 <= yd && yd < n) {
        if (yd == 0) {
            if (m[yd][xd] != 1) {
                r += 1;
            }
        } else if (m[yd][xd] == 0 || m[yd][xd] == 2) {
            r += checagem(n, m, xd, xd - 1, yd - 1);
            r += checagem(n, m, xd, xd + 1, yd - 1);
        } else if (m[yd][xd] == 1) {
            if (xo - xd > 0) {
                if (pulavel(n, xd - 1, yd - 1, m)==1) {
                    r += checagem(n, m, xd, xd - 1, yd - 1);
                }
            } else if (xo - xd < 0) {
                if (pulavel(n, xd + 1, yd - 1, m)==1) {
                    r += checagem(n, m, xd, xd + 1, yd - 1);
                }
            }
        }
    } else {
        r += 0;
    }
    return r;
}

int main(void)
{
    //variaveis
    int n = 0, t = 1, x = -1, y = -1, teste = 1;
    int i,j;
    //logica
    scanf("%d %*c",&t);

    while (teste > 0) {
        scanf("%d %*c",&n);
        if (n > 1 || n <= 100) {
            int tabuleiro[n][n];
            for (i = 0; i < n; i++) {
                char l[n];
                scanf("%s %*c", l);
                for (j = 0; j < n; j++){
                    switch(l[j]){
                    case ('.'): tabuleiro[i][j] = 0;break;
                    case ('b'): tabuleiro[i][j] = 1;break;
                    case ('w'): tabuleiro[i][j] = 2;
                                x = j;
                                y = i;break;
                    }
                }
            }
            int r = checagem(n, tabuleiro, x, x, y);
            printf("%d", r); 
        }
    }
}

Upvotes: 1

Related Questions