-3

I have read a book about C, and I did try, so please be soft with me. I am trying to understand how memory really works.

I would like to have some words array like this ( in C) :

char builts[20][10]={"light","temp"}; //should it looks like this ?

Then, I would like to pass that array to a function (in another class)

   //some class
    char  *builtinFunctions;
    void Intepreter::setBuiltIns( char *builtins)
    {
      //  here - should I save a copy to builtinFunctions ?? how ?

    }

The other class need to have access to that array of words all the time. Why this is gives error : intepreter.setBuiltIns(&builts); ?

How would one declare builtinFunctions ? as a pointer or array ? should it be copied to?

How exactly the whole thing should look like ??

Curnelious
  • 1
  • 16
  • 76
  • 150
  • 5
    Some confusion here: `::` is not [tag:c] but [tag:c++]. And `class` too. – LPs Aug 02 '16 at 09:48
  • 1
    There is no class in `C`. – Shravan40 Aug 02 '16 at 09:49
  • As I said, forget about the C++ thing, I just need to understand how to pass arguments. I can remove the :: if its more convenient. Try to concentrate of the problem of passing an argument in C. – Curnelious Aug 02 '16 at 09:49
  • you'll need to pass the address of the array and catch it in a pointer. – Mridul Kashyap Aug 02 '16 at 09:49
  • @MridulKashyap thanks, can you show how the whole thing works ? I just can't get to understand this for an hour. ( I did try what you said, see inside the question) – Curnelious Aug 02 '16 at 09:50
  • 1
    Possible duplicate of [Correct way of passing 2 dimensional array into a function](http://stackoverflow.com/questions/9446707/correct-way-of-passing-2-dimensional-array-into-a-function) – flau Aug 02 '16 at 09:52
  • What a great people , again, you ask a question and its not good enough for them. wow. – Curnelious Aug 02 '16 at 10:10
  • You are hardly a newbie to SO. You should read the help section about what to/not to/how to ask, instead of complaining that you receive down-votes when the question is of low quality as specified there. – StoryTeller - Unslander Monica Aug 02 '16 at 12:43
  • Thanks for the overly broad generalization. Anyway, since C++ looks to be on the table, you may find it easier to pass around [`std::array`](http://en.cppreference.com/w/cpp/container/array) or a one dimensional array of [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string). – user4581301 Aug 02 '16 at 15:03

3 Answers3

4

There are multiple ways to pass a 2D array to a function:

The parameter is a 2D array

int array[10][10];
void passFunc(int a[][10])
{
    // ...
}
passFunc(array);

The parameter is an array containing pointers

int *array[10];
for(int i = 0; i < 10; i++)
    array[i] = (int*)malloc(40); //array[i] = new int[10];
void passFunc(int *a[10]) //Array containing pointers
{
    // ...
}
passFunc(array);

The parameter is a pointer to a pointer

int **array;
array = (int*)malloc(40);//array = new int *[10];
for(int i = 0; i <10; i++)
    array[i] = (int*)malloc(40); //array[i] = new int[10];
void passFunc(int **a)
{
    // ...
}
passFunc(array);
Shravan40
  • 8,922
  • 6
  • 28
  • 48
2

When passing a simple array to a function, you pass it as a pointer (array name is decayed as a pointer to the first element of the array), like this :

int foo[3] = { 3, 2, 1 };
bar(foo);

So your function takes a pointer to an int as parameter :

void bar(int *data) { }

Here you have an array which contains NULL terminated string of length 10 which are arrays too. So, builts is a pointer to his first element so a pointer to an array of 10 char :

char builts[20][10] = {"light", "temp"};
char (*foo)[10] = builts; // This is valid, foo is a pointer to an array of 10 char

So, your function must take an argument of type char (*)[10], because you pass a pointer to an array of 10 char :

void bar(char (*data)[10]) { }
Quentin
  • 724
  • 7
  • 16
  • great thanks, I can' get this (!) why in the first example, we send the address for the first cell , using * , and on the second, we also send the address for the first cell, using ** .. – Curnelious Aug 02 '16 at 10:00
  • @Curnelious : In the first example, we have go an array with only 1 dimension which contains `int`. In the second example, we have got an array which contains strings (in C, strings are NULL terminated arrays), so an array containing other arrays. Theses nested array are string, so `char *`. So, the first array contains `char *`, and the function takes a pointer to the first element of the array as parameter. So, pointer to `char *` which is `char **` – Quentin Aug 02 '16 at 10:03
  • Thanks, but still not working, if i create a function like this : void setBuiltIns( char **builtins); , then I call it with this : setBuiltIns(built); i get an error: cannot initialise parameter of char ** with array[20][10] – Curnelious Aug 02 '16 at 10:09
  • and your comment on that being valid char **foo = built; is also not valid, i get the same error for this. – Curnelious Aug 02 '16 at 10:11
  • @Curnelious My bad, I made an error in my explanations, the post has been edited correctly. You won't have a `char **` but a pointer to an array of `char [10]`, so a `char (*)[10]` – Quentin Aug 02 '16 at 10:19
0

You can pass the 2 day array by just using its name while calling a function, like:

test_2d(builts);

You can either pass the total number of words as a separate argument, or alternatively, you can make a special word to indicate end of your array. For instance, I have used a special word "\0" to indicate that this marks the end of array. Overall the code looks like.

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

int main(void)
{
    char builts[20][10]={"light","temp", "\0"};
    test_2d(builts);        /* without passing total number of args; depends on special word at the end */
    test_2d_num(builts, 2); /* also pass total num of elements as argument */
    return 0;
}

/* This needs a special word at the end to indicate the end */
void test_2d(char builts[][10])
{
    int i;
    char tmp[10];

    /* just print the words from word array */
    for (i=0; *builts[i] != '\0'; i++ )
            printf("%s\n", builts[i]);

    /* also try copy words to a tmp word and print */
    for (i=0; *builts[i] != '\0'; i++ ) { 
            strcpy(tmp, builts[i]);
            printf("%s\n", tmp);
    }

    /* Do something */
}

/* Also get total number of elements as a parameter */
void test_2d_num(char builts[][10], int tot_elem)
{
    int i;

    /* Process each word from the array */
    for (i = 0; i < tot_elem; i++) {
         printf("%s\n", builts[i]);
         /* Do something */
    }
}

Note that this function can only process arrays like, builts[][10], and not builts[][11], or builts[][9].

If you want want a generic function, then you need to store the addresses of individual words in an char *arr[] and pass this array to the function. Like

int main()
{
     /* store the addresses of individual words in an `char *arr[] */
     char *arr[] = {"hello", "this", "that", NULL};

     test_2d_gen(arr);
     return 0;
}

void test_2d_gen(char *arr[])
{
     int i;

     /* process each word */
     for (i = 0; arr[i] != NULL; i++) {
         printf("%s\n", arr[i]);

     /* Do something */
     }
}
sps
  • 2,720
  • 2
  • 19
  • 38
  • 1
    I have added `test_2d_num` which takes the total number of elements/words. The `test_2d` was a clumny one, where as `test_2d_num` is much cleaner. – sps Aug 02 '16 at 10:55
  • Thank you very much! this is exactly what I wanted when I asked the question. You saved me a few more hours . Thanks. – Curnelious Aug 02 '16 at 10:55
  • In the for loop, why do you use *builts[i] to test the condition and in the print line u use builts[i] (without the asterisk)? – George Bou Aug 02 '16 at 11:26