Reputation: 145
If I use char *s[]
, I can do the following:
char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};
What is the difference with **s
? How do I use the char **s
instead of char *s[]
in that case?
Example: int main (int argc, char **argv)
instead of *argv[]
Upvotes: 6
Views: 5062
Reputation: 69250
Arrays and pointers are different things. A pointer can be used to access an element in the array. To be able to initialize an array, you need to declare an array, not a pointer.
To show clearly the difference try this:
int[] ia = {1, 2, 3, 4, 5, 6, 7, 8};
int* ip = ia;
printf("sizeof(ia): %zu, sizeof(ip): %zu", sizeof(ia), sizeof(ip));
The first should print the size of the array, the second the size of an int pointer.
The odd thing with C is that when an array is passed as a parameter to a function it decays into a pointer. See more in section 2.3 of http://www.lysator.liu.se/c/c-faq/c-2.html. The reason main accepts argv**
instead of argv*[]
is that argv*[]
is decayed into argv**
when passed as a function parameter.
Upvotes: 1
Reputation: 901
It depends upon your requirement. If your program doesn't have to modify these strings later you can use
char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};
These are compiled as string literals in read only section.
Assembly output:
.file "test.c"
.section .rodata
.LC0:
.string "foo"
.LC1:
.string "bar"
.LC2:
.string "foobar"
.LC3:
.string "whatever"
.LC4:
.string "john"
.LC5:
.string "doe"
.text
If you try to modify these strings later in the program you would get a segmentation fault. In that case you have to use char **s
Upvotes: 0
Reputation: 9733
Not direct answer to your que but this might help you understand a bit more:
#include <stdio.h>
#include <string.h>
int main() {
char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};
printf(" s[0]: %s \n", s[0]);
printf(" *s: %s \n", *s);
printf(" *s+1: %s \n", *s+1);
printf("*(s+1): %s \n", *(s+1));
return 0;
}
Output:
$ gcc -o chararr chararr.c
$ ./chararr
s[0]: foo
*s: foo
*s+1: oo
*(s+1): bar
Upvotes: 1
Reputation: 132974
As function parameters, there is no difference whatsoever. They are equivalent.
void f(int** p);
void f(int* p[]);
void f(int* p[42]);
These three declarations are equivalent.
As objects, they have different types;
char *s[] = {"foo", "bar", "foobar", "whatever", "john, "doe"};
s
is an array of 6
pointers to char
sizeof(s) == 6*sizeof(void*)
char **s;
s
is a pointer to pointer to char
. sizeof(s) == sizeof(void*)
Upvotes: 4
Reputation: 1036
when you use char *s[] = {"foo", "bar", "foobar", "whatever", "john, "doe"};
the compiler already knows the length of array ie: in this case it knows the its a pointer to pointers of 6 character arrays.
char**
lacks the length information and thats specifically why main has 2 arguments {length, pointer to pointer to char} == {argc, arv}
Upvotes: 0
Reputation: 141819
They create the same data structure. The only difference s that char*s[] automatically mallocates enough memory for {"foo", "bar", "foobar", "whatever", "john, "doe"}
upon initialization. char **s would only allocate one byte for the pointer then you'd to manually mallocate memory yourself for the each string in the array.
Upvotes: 1
Reputation: 9963
If you define
char **s[] = {"foo", "bar", "foobar", "whatever", "john, "doe"};
I think that it's the same like defining tridiensional arrays (char s[10][10][10]), since char *s[] is defining a bidimensional array.
Upvotes: 0
Reputation: 59277
For function parameters, there is no difference.
Otherwise:
char *s[];
s is an array of pointer to char. And
char **s;
s is a pointer to pointer to char.
You use the former if you need an array of pointer to char, and you use the latter if you need a pointer to a pointer to a char.
Upvotes: 7
Reputation: 4049
From my knowledge, **s is the address of the address of s, where *s[] is the address of array s, I think you would store single values in s, yet in s[] you would store array, and array itself is a pointer. Hope this helps!
Upvotes: 0