Passing 2d char array by pointer to function

Hey guys,

so with the initBoard and printBoard functions, I'm trying to pass A 2D char array by pointer to these functions I got the solution from stackoverflow. but I don't understand the syntax why is the * in parenthesis? followed [20]?

normally passing a pointer you would do

1
2
3
4
5

 void foo(char* c){

}


when I remove the parenthesis the function doesn't accept the array

1
2
3
4
5
void initBoard(char *board[20]){

}
does not work





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

#include <iostream>

using namespace std;

void initBoard(char (*board)[20]){

    for(int i = 0; i < 20; i++){

        for(int j = 0; j < 20; j++){

           board[i][j] = '0';
        }
    }
}

void printBoard(char (*board)[20]){

  for(int i = 0; i < 20; i++){

    for(int j = 0; j < 20; j++){

        cout << board[i][j];
    }
    cout << endl;
  }
}

int main()
{

    char board[20][20];

    initBoard(board);
    printBoard(board);
}


could anyone try to explain this to me?

thanks
The reason the () are required is because of operator precedence.

Did you try something like void printBoard(char board[][20]){?

By the way you really should also be passing the array sizes into those functions as well.

I tried

1
2
void printBoard(char board[][20])


this function is ok to do that, as I want to only print the board but still that is a lot of copying, but the init board function , I cannot do this because I want to pass it by pointer/ value

Last edited on
C-style arrays (including multidimensional arrays) are passed by reference (EDIT: technically by pointer).

Don't worry, I made the same mistake of assuming otherwise once.

-Albatross
Last edited on
I'll talk about the syntax:

First of all, char *board2[0] is an array of 20 pointers to char. Writing char (*board)[20] instead yields a pointer to an array of 20 char.

C's declarations are supposed to model the usage of the variable being declared.

When subscripting an array, the brackets appear after the variable name (foo[2]). The declaration of an array requires the array bounds to appear in the same place. For example, int foo[24] is acceptable, but int[24] foo is not.

When dereferencing a pointer, the star appears on the left of the variable name (*x). The declaration of a pointer requires the star to appear in the same place. For example, int *foo is acceptable, but *int foo is not. Note this is why the declaration int *foo, bar makes any intuitive sense -- foo is a pointer, but bar is not.

When calling a function, arguments appear on the right of the function name, inside parentheses. The declaration of a function requires the parameters in the same place.

The same pattern for functions is clearer in K&R (pre-standard) C. K&R syntax looks like this:
1
2
3
int foo(x) 
  int x; // parameter x has type int
{ return x + 2; }


Since then, the language has changed to make the analogy worse, but it's still present to some extent in C and C++.

Hopefully it makes a little bit of sense that given char (*board)[20], *board yields a char[20]? Note that *x[y] is equivalent to *(x[y]).

If you think about it long-enough, even declarations like this will make some kind of sense:
void (*stuff(int, void (*)(int)))(int);
Exercise: stuff has the signature of an important function in both POSIX and the C++ standard library. What is its type?
Last edited on
If it is a fixed size array, consider using a type alias and passing the array object by reference.

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

constexpr std::size_t NROWS = 20 ;
constexpr std::size_t NCOLS = 20 ;
using board_type = char[NROWS][NCOLS] ; // type alias for 2d array

void fill( board_type& board, char fill_char ) {

    for( auto& row : board )
        for( char& c : row ) c = fill_char ;
}

void init( board_type& board ) { fill( board, '0' ) ; }

void print( const board_type& board, std::ostream& stm = std::cout ) {

    for( const auto& row : board ) {

        for( char c : row ) stm << c << ' ' ;
        stm << '\n' ;
    }
}

int main() {

    board_type board ;
    init(board) ;
    print(board) ;
}

http://coliru.stacked-crooked.com/a/db79a2913f73b559
adam2016 wrote:

I tried
 
void printBoard(char board[][20])


this function is ok to do that, as I want to only print the board but still that is a lot of copying, but the init board function , I cannot do this because I want to pass it by pointer/ value

There is no array copying taking place.

void printBoard(char board[][20]);
void printBoard(char board[20][20]);
void printBoard(char (*board)[20]);

It's all the same to the compiler.
There is a single pointer with a type of 'pointer to array'.

You can always do sizeof(board) in the function to verify that all you have is a pointer.

https://cdecl.org/
char (*board)[20] declare board as pointer to array 20 of char
char *board[20] declare board as array 20 of pointer to char
Any value within the square brackets of an array "passed by value" (although arrays are not copied) is simply ignored. There is a way to pass stack-based arrays of a known size "by reference" accepting a certain size:
void MyFunc(int (&theArray)[4]);

This only accepts a size 4 array. The syntax is non-obvious. I would recommend to not use a C-style array in this particular case and use std::array instead. They are statically allocated and know their sizes at compile time. They also have iterators and work well with standard library algorithms
Last edited on
Topic archived. No new replies allowed.