Reputation: 2975
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
Upvotes: 0
Views: 7692
Reputation: 27854
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*
.
Upvotes: 1
Reputation: 25908
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
.
Upvotes: 9