views:

133

answers:

5

How to return a static multidimensional array of characters?

#include<stdio.h>
#include<conio.h>

#define SIZE 3

char ** MyFunction(void)
{
    static char arr[SIZE][SIZE]={
                                    {'A', 'B', 'C'},
                                    {'D', 'E', 'F'},
                                    {'G', 'H', 'I'}
                                };
    return arr;
}

void main(void)
{
    char ** arr1 = NULL;
    int i=0;
    int j=0;

    arr1 = MyFunction();

    for(i=0 ; i<SIZE ; i++)
    {
        for(j=0 ; j<SIZE ; j++)
        {
            printf("%c, ", arr1[i][j]);
        }

        printf("\n");
    }

    getch();
}
+4  A: 

First of all, arr can not be a char**. It is an address, but it's not the address of a pointer -- it's the address of a char[SIZE].

I've always found it easier to deal with these by spliting the dimensions up using typedefs.

#define SIZE 3 
typedef char ROW[SIZE];   // a ROW type is an array of chars

ROW* MyFunction(void) 
{ 
     static ROW arr[SIZE]={  // arr is an array of ROW objects 
                                    {'A', 'B', 'C'}, 
                                    {'D', 'E', 'F'}, 
                                    {'G', 'H', 'I'} 
                                }; 
    return arr; 
} 

void main(void) 
{ 
    ROW* arr1 = NULL;
    // etc...
James Curran
Sadly enough, this is not working either!#include<stdio.h>#include<conio.h>#define SIZE 3typedef char ROW[SIZE];ROW* MyFunction(void) { static ROW arr[SIZE]={ {'A', 'B', 'C'}, {'D', 'E', 'F'}, {'G', 'H', 'I'} }; return arr; } void main(void) { ROW * arr1 = NULL; int i=0; for(i=0 ; i<SIZE ; i++) { printf("%c ", arr1[i]); } getch();}
JMSA
Because `arr1[i]` is not a character, it's a ROW, which is a array of characters. IOW, everything else in your program, besides what I changed, should have remained the same.
James Curran
Can I do it without typedef? If yes how?
JMSA
Yes, it can be done. It's just that the syntax is real ugly: `char (*arr1)[SIZE] = NULL;`
James Curran
+1  A: 

Given the declaration

char arr[SIZE][SIZE];

then the type of the expression arr is char (*)[SIZE]; therefore, the function type should be

char (*myFunction(void))[SIZE] // myFunction returns a pointer to a SIZE-element
{                              // array of char
  static char arr[SIZE][SIZE] = ...;
  return arr;
}

Yes, the function type definition is ugly. James' typedef version reads more easily, but this is what's happening under the covers.

int main(void)
{
  char (*arr1)[SIZE];
  int i, j;

  arr1 = myFunction();
  ...
}
John Bode
A: 

change to static char ** arr[][]= ...

zahirhas
A: 

Who owns the array?

It is very important because some part of the code has to take full ownership (create, delete) of the array. Other parts of the code can read and write though.

With that philosophy, I would modify the code so that main function (in reality, it can be any function) takes ownership of arr1. main creates arr1, and passes it to other function (may be in other module) to "initialize" it. Here is a modified version of the program.

#include <stdio.h>

enum{ SIZE = 3 };

void initArray( char arr[ SIZE ][ SIZE ] ) {

    char x = 'A';

    for( int i = 0; i < SIZE; i++ ) {
        for( int j = 0; j < SIZE; j++ ) {
            arr[ i ][ j ] = x;
            x += 1;
        }
    }
}

int main()
{
    char arr1[ SIZE ][ SIZE ];
    initArray( arr1 );

    for( int i = 0; i < SIZE; i++ ) {
        for( int j = 0; j < SIZE; j++ ) {
            printf("%c, ", arr1[ i ][ j ]);
        }
        printf("\n");
    }
}

Upon spending few minutes in searching, I found a good discussion on multi-dimensional array in C.

Another comment on the side. please note that I have done couple of other changes in the code, some are design (e.g. using enum instead of #define, declaring variables (i, j in most local scope) while some are formatting. Programs are mainly for communicating with other human programmers, so readability of code is very important.

ArunSaha
Did you read my requirement?????????
JMSA
Yes. I think you are emphasizing on "returning" part. I wanted to provide a different perspective, albeit with a slight change of requirements, since I thought that is easier to understand and maintain.
ArunSaha
A: 

conio.h + getch() is not ANSI C. void main is not ANSI C. Take a new type, it make it easier.

#include<stdio.h>
#include<conio.h>

#define SIZE 3
typedef char CHAR3[SIZE];

CHAR3 *MyFunction(void)
{
    static CHAR3 arr[]={
                                    {'A', 'B', 'C'},
                                    {'D', 'E', 'F'},
                                    {'G', 'H', 'I'}
                                };
    return arr;
}

main(void)
{
    CHAR3 *arr1 = NULL;
    int i=0;
    int j=0;

    arr1 = MyFunction();

    for(i=0 ; i<SIZE ; i++)
    {
        for(j=0 ; j<SIZE ; j++)
        {
            printf("%c, ", arr1[i][j]);
        }

        printf("\n");
    }

   getch();
}