0

For below code how do I pass char[][] as char** parameter?

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


void fn(int argc,char** argv)
{
 int i=0;   
 printf("argc : %d\n",argc);
 for(i=0;i<argc;i++)
     printf("%s\n",argv[i]);
}

int main()
{
char var3[3][10]={"arg1","argument2","arg3"};
char var4[4][10]={"One","Two","Three","Four"};

fn(3,&var3);
fn(4,&var4);


return 0;
}

Getting below error:

$ gcc -Wall anyNumberOfParameters.c -o anyNumberOfParameters.exe
anyNumberOfParameters.c: In function ‘main’:
anyNumberOfParameters.c:18:1: warning: passing argument 2 of ‘fn’ from incompatible pointer type [enabled by default]
 fn(3,&var3);
 ^
anyNumberOfParameters.c:5:6: note: expected ‘char **’ but argument is of type ‘char (*)[3][10]’
 void fn(int argc,char** argv)
      ^
anyNumberOfParameters.c:19:1: warning: passing argument 2 of ‘fn’ from incompatible pointer type [enabled by default]
 fn(4,&var4);
 ^
anyNumberOfParameters.c:5:6: note: expected ‘char **’ but argument is of type ‘char (*)[4][10]’
 void fn(int argc,char** argv)
      ^

If I change my code in main() as:

char* var3[3]={"arg1","argument2","arg3"};
char* var4[4]={"One","Two","Three","Four"};

fn(3,var3);
fn(4,var4);

It works fine, but I want to know how do I pass char[][] as parameter.

char var[3][10]={"One","Two","Three"};
printf("%s",var[1]);

it does print : Two So if I pass var to char** ; won't it be equivalent to two dimentional array's address?

I mean for a function fn(char*) we do pass as:

char name[20]="Thomas";
fn(name);

char** is making me confused

3
  • 2
    The suggested duplicate is a C++ question; this is a C question Commented May 25, 2014 at 22:20
  • 2
    Hint: print the size of var3 and var4. Another hint: in-memory layout of char** and char[][] are different. Commented May 25, 2014 at 23:23
  • I do not know why negative vote? It is a valid question and I received good explanation.. It would be helpful for any beginner.. :( Commented May 26, 2014 at 3:17

2 Answers 2

9

If you dereference a char **, you should get a pointer to char. There are no pointers in a char[3][10]. They're just not interchangeable.

It works for a one-dimensional char * array because the array name implicitly converts to a pointer to the first element in this context, and if you dereference a char * you get a char, and that's exactly what your one-dimensional char array contains.

The line of thinking that "if it works for a one-dimensional array, shouldn't it work for a two-dimensional array?" is just invalid, here.

To make what you want to do work, you'd have to create char * arrays, like so:

#include <stdio.h>

void fn(int argc, char ** argv) {
    printf("argc : %d\n", argc);
    for (int i = 0; i < argc; ++i) {
        printf("%s\n", argv[i]);
    }
}

int main(void) {
    char * var3[3] = { "arg1", "argument2", "arg3" };
    char * var4[4] = { "One", "Two", "Three", "Four" };

    fn(3, var3);
    fn(4, var4);

    return 0;
}

which outputs:

paul@local:~/src/c/scratch$ ./carr
argc : 3
arg1
argument2
arg3
argc : 4
One
Two
Three
Four
paul@local:~/src/c/scratch$ 

An alternative is to declare your function as accepting an array of (effectively a pointer to) 10-element arrays of char, like so:

#include <stdio.h>

void fn(int argc, char argv[][10]) {
    printf("argc : %d\n", argc);
    for (int i = 0; i < argc; ++i) {
        printf("%s\n", argv[i]);
    }
}

int main(void) {
    char var3[3][10] = { "arg1", "argument2", "arg3" };
    char var4[4][10] = { "arg1", "argument2", "arg3", "arg4" };

    fn(3, var3);
    fn(4, var4);

    return 0;
}

but this obviously requires hard-coding the sizes of all dimensions except the leftmost, which is usually less desirable and flexible. char argv[][10] in the parameter list here is another way of writing char (*argv)[10], i.e. declaring argv as a pointer to array of char of size 10.

Sign up to request clarification or add additional context in comments.

Comments

1

A type** is by definition a pointer to a pointer, or an array of pointers.

When used in a function declaration, type[][] is inteligible with type** as in:

int main(int argc, char argv[][]) { ...

But it is not when declaring variables. When you do this:

char var[a][b] = { ... }

This is a matrix of char and there are no pointers envolved here. The compiler pretty much handles this as a straight forward array of char var[a*b] and when you access var[1][2] it internally does var[1*b+2]. It is not really an array of strings, and its utilization is only possible because the compiler knows the value of b when compiling this function, as the variable was declared there.

In order to pass as char**, var must be an array of pointers. A list containing pointers of char*.

When you do this:

char *var[a] { ... }

Now you are telling the compiler your intention. var is no longer a matrix of char, it is truly a list of pointers char*.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.