Author |
Message |
Tom St Deni #1 / 17
|
 char **str vs. char *str[]
As I understand it they are equivalent? [yes/no/maybe/toaster]. Why wouldn't a person use the former since it is a bit more technically forthcoming. I read the former as "pointer to pointer to char" and the latter as "array of pointer to char". From a top-rough view I could use both in a sentence, but getting to the "guts" of what's going I would prefer the former... Is there any other reason why people use the latter? -- Tom St Denis --- http://www.*-*-*.com/
|
Wed, 10 Dec 2003 20:02:41 GMT |
|
 |
Tim Robinso #2 / 17
|
 char **str vs. char *str[]
| Why wouldn't a person use the former since it is a bit more technically | forthcoming. I read the former as "pointer to pointer to char" and the | latter as "array of pointer to char". From a top-rough view I could use | both in a sentence, but getting to the "guts" of what's going I would prefer | the former... I've seen both int main(int argc, char** argv); and int main(int argc, char* argv[]); and they work equivalently (at least in function argument lists). I think it's a matter of preference and aethetics -- I prefer the former, although conceptually the second form suggests that argv is an array of strings.
|
Wed, 10 Dec 2003 20:25:51 GMT |
|
 |
Robert Stankowi #3 / 17
|
 char **str vs. char *str[]
Quote: > As I understand it they are equivalent? [yes/no/maybe/toaster]. > Why wouldn't a person use the former since it is a bit more technically > forthcoming. I read the former as "pointer to pointer to char" and the > latter as "array of pointer to char". From a top-rough view I could use > both in a sentence, but getting to the "guts" of what's going I would prefer > the former... > Is there any other reason why people use the latter? > -- > Tom St Denis > ---
Not sure if that answers your question, anyway, that is how I use these forms: #include <stdlib.h> #include <stdio.h> void foo(char *array[]) { int i; for(i = 0; i < 5; i++) { printf("%s\n", array[i]); } Quote: }
void bar(char ** array_ptr) { *array_ptr = malloc(10 * sizeof **array_ptr); Quote: }
int main(void) { char *array1[5] = {"one", "two", "three", "four", "five"}; char *array_ptr; foo(array1); bar(&array_ptr); if(array_ptr != NULL) { /*use the allocated memory*/ free(array_ptr); return EXIT_SUCCESS; } fprintf(stderr, "Malloc failed, exiting\n"); return EXIT_FAILURE; Quote: }
|
Wed, 10 Dec 2003 20:42:13 GMT |
|
 |
Minh Van L #4 / 17
|
 char **str vs. char *str[]
Quote:
> As I understand it they are equivalent? [yes/no/maybe/toaster]. > Why wouldn't a person use the former since it is a bit more technically > forthcoming. I read the former as "pointer to pointer to char" and the > latter as "array of pointer to char". From a top-rough view I could use > both in a sentence, but getting to the "guts" of what's going I would > prefer the former... > Is there any other reason why people use the latter? -- Tom St Denis
there's no difference between the two. i use *str[] to emphasise that i'm passing a "pointer-to-a-pointer to an array of type char". **str as a "pointer-to-a-pointer of type char". i'm not sure if saying that's technically correct, but here're two examples: i would use *str[] if i previously declared an array (character array): /* prototype using *[] */ print_string(char *[]); int main(void) { char array[100]; /* character array */ char **p_ptr = &array; call_func(p_ptr); return 0; Quote: }
or **str if i declared a pointer to type char: /* prototype using **str */ print_string(char **); int main(void) { char *string; /* string constant */ char **p_ptr = &string; call_func(p_ptr); return 0; Quote: }
|
Wed, 10 Dec 2003 23:33:24 GMT |
|
 |
Morris Dove #5 / 17
|
 char **str vs. char *str[]
Quote:
> As I understand it they are equivalent? [yes/no/maybe/toaster]. > Why wouldn't a person use the former since it is a bit more technically > forthcoming. I read the former as "pointer to pointer to char" and the > latter as "array of pointer to char". From a top-rough view I could use > both in a sentence, but getting to the "guts" of what's going I would prefer > the former... > Is there any other reason why people use the latter?
It only makes a difference if you're /defining/ the variable. The former allocates space for a single pointer and the latter (with a dimension value) allocates space for <dimension> pointers. -- Morris Dovey West Des Moines, Iowa USA
|
Wed, 10 Dec 2003 23:33:19 GMT |
|
 |
Ben Pfaf #6 / 17
|
 char **str vs. char *str[]
Quote:
> As I understand it they are equivalent? [yes/no/maybe/toaster]. [...] > Is there any other reason why people use the latter? -- Tom St Denis
We are talking, in essence, about the difference between these two declarations: void foo (int *bar); void foo (int bar[]); These are equivalent from the compiler's point of view, of course. Personally, I use the former to declare a pointer to a single object, and the latter to declare a pointer to multiple objects. In other words, I use them like they appear. So, I prefer the usage of [] in the declaration of the `argv' parameter to main(). If there's a fixed number of objects being pointed to, then I'll even add the number of objects. For instance, suppose that there are always 3 objects at the business end of the pointer: void foo (int bar[3]); Again, this is equivalent from the compiler's point of view. (Perhaps this is all obvious `good style' but I thought I'd point it out anyway.) -- "The way I see it, an intelligent person who disagrees with me is probably the most important person I'll interact with on any given day." --Billy Chambless
|
Wed, 10 Dec 2003 23:43:01 GMT |
|
 |
Tom St Deni #7 / 17
|
 char **str vs. char *str[]
Quote:
> > As I understand it they are equivalent? [yes/no/maybe/toaster]. > > Why wouldn't a person use the former since it is a bit more technically > > forthcoming. I read the former as "pointer to pointer to char" and the > > latter as "array of pointer to char". From a top-rough view I could use > > both in a sentence, but getting to the "guts" of what's going I would > > prefer the former... > > Is there any other reason why people use the latter? -- Tom St Denis > there's no difference between the two. i use *str[] to emphasise that i'm > passing a "pointer-to-a-pointer to an array of type char". **str as a > "pointer-to-a-pointer of type char". i'm not sure if saying that's > technically correct, but here're two examples:
char *str[] means array of pointers to chars. char **str means pointer to pointer to chars. Quote: > i would use *str[] if i previously declared an array (character array): > /* prototype using *[] */ > print_string(char *[]); > int main(void) { > char array[100]; /* character array */ >char **p_ptr = &array;
This doesn't mean the same thing. array is not a pointer so p_ptr will not point to a pointer. I get [via GCC] test.c: In function `main': test.c:6: warning: assignment from incompatible pointer type Quote: > /* prototype using **str */ > print_string(char **); > int main(void) { > char *string; /* string constant */ > char **p_ptr = &string; > call_func(p_ptr);
This is valid, but doing anything with **p_ptr (or *p_ptr[anything_but_zero]) in "call_func" is undefined. Tom
|
Thu, 11 Dec 2003 03:37:23 GMT |
|
 |
Tom St Deni #8 / 17
|
 char **str vs. char *str[]
Quote:
> > As I understand it they are equivalent? [yes/no/maybe/toaster]. > [...] > > Is there any other reason why people use the latter? -- Tom St Denis > We are talking, in essence, about the difference between these > two declarations: > void foo (int *bar); > void foo (int bar[]); > These are equivalent from the compiler's point of view, of > course. > Personally, I use the former to declare a pointer to a single > object, and the latter to declare a pointer to multiple objects. > In other words, I use them like they appear. So, I prefer the > usage of [] in the declaration of the `argv' parameter to main(). > If there's a fixed number of objects being pointed to, then I'll > even add the number of objects. For instance, suppose that there > are always 3 objects at the business end of the pointer: > void foo (int bar[3]); > Again, this is equivalent from the compiler's point of view. > (Perhaps this is all obvious `good style' but I thought I'd point > it out anyway.)
Hmm, I would like to see the usage of the # give warnings like int myfunc(int a[3]) { return a[0]+a[1]+a[2]; Quote: }
int main(void) { int a[7]; return myfunc(a); Quote: }
Should give a warning in main saying the types are not of the same dimension. I see your points though. Thanks for the feedback. Tom
|
Thu, 11 Dec 2003 03:39:57 GMT |
|
 |
Sef Campstei #9 / 17
|
 char **str vs. char *str[]
Quote: > As I understand it they are equivalent? [yes/no/maybe/toaster].
They are sometimes equivalent. They are equivalent if they make up the second argument to function main. Quote: > Is there any other reason why people use the latter?
I use the latter if i want str to be an array of pointers to char. I use the former if i want str to be a pointer to a pointer to char. It's that simple.
|
Thu, 11 Dec 2003 14:27:58 GMT |
|
 |
Tor Rusta #10 / 17
|
 char **str vs. char *str[]
Quote: > As I understand it they are equivalent? [yes/no/maybe/toaster]. > Why wouldn't a person use the former since it is a bit more technically > forthcoming. I read the former as "pointer to pointer to char" and the > latter as "array of pointer to char". From a top-rough view I could use > both in a sentence, but getting to the "guts" of what's going I would prefer > the former... > Is there any other reason why people use the latter?
The FAQ has a good discussion on this topic. When I use the array-of-pointer-to-char insted of pointer-to-pointer-to-char, the array notation indicate that the space has been allocated for the array of pointers. A **str is just a pointer. Note that, as formal parameters in functions, *str[] decay into a **str and the two forms are equivalent. Related to this, is array-of-char vs pointer-to-char, i.e. *str vs. str[]. When I use "*str" as a formal function parameter, I typically expect a null-terminated string on input/output. However, in many cases we don't have null-terminated strings, but simply byte arrays, and then I find the notation str[] better. Examples (not compiled): void foo(char *string, char **string_ptr, unsigned char md5_hash[]) { size_t len; len = strlen(string); /* string is null terminated */ *string_ptr = strrchr(string, '#'); /* update the pointer*/ md5_sum(md5_hash, string, len); /*md5_hash is binary data and NOT null terminated */ Quote: }
char *bar(int no, char *week_day[]) { if (no<0 || no>6) return NULL; return week_day[no]; Quote: }
int main(void) { char *tail, *day; char *week[] = {"Mon","Tu","Wen","Th","Fri","Sat","Sun"}; foo("Test#Message", &tail); day = bar(1, week); return 0; Quote: }
-- Tor <torust AT online DOT no> http://www.eskimo.com/~scs/C-faq/top.html
|
Thu, 11 Dec 2003 17:46:14 GMT |
|
 |
Ben Pfaf #11 / 17
|
 char **str vs. char *str[]
[...*x[] vs **x as a parameter...] Quote: > > As I understand it they are equivalent? [yes/no/maybe/toaster]. > They are sometimes equivalent. They are equivalent if they make up the > second argument to function main.
No, they are *always* equivalent as parameters to *any* function.
|
Thu, 11 Dec 2003 22:07:46 GMT |
|
 |
Zoran Cutur #12 / 17
|
 char **str vs. char *str[]
... Quote: > Hmm, I would like to see the usage of the # give warnings like > int myfunc(int a[3]) > { > return a[0]+a[1]+a[2]; > } > int main(void) > { > int a[7]; > return myfunc(a); > } > Should give a warning in main saying the types are not of the > same dimension.
Tom, there are no such warnings since as you know an array decays to a pointer to an array when passed to a function. So the dimension gets lost. Anyhow I don't see a problem with passing a 7-int-array to a function expecting a 3-int-array. I'ld rather like to have a warning for passing a to short array to the function. --
"LISP is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days." -- Eric S. Raymond
|
Fri, 12 Dec 2003 17:44:18 GMT |
|
 |
Tom St Deni #13 / 17
|
 char **str vs. char *str[]
Quote:
> ... > > Hmm, I would like to see the usage of the # give warnings like > > int myfunc(int a[3]) > > { > > return a[0]+a[1]+a[2]; > > } > > int main(void) > > { > > int a[7]; > > return myfunc(a); > > } > > Should give a warning in main saying the types are not of the > > same dimension. > Tom, > there are no such warnings since as you know an array decays to > a pointer to an array when passed to a function. So the > dimension gets lost. Anyhow I don't see a problem with passing > a 7-int-array to a function expecting a 3-int-array. I'ld > rather like to have a warning for passing a to short array > to the function.
There is no reason why the compiler doesn't keep track of the sizes. And it is not against the C99 spec to give un-due warnings. It would be a good idea [IMHO] to catch alot of nippy bugs. Tom
|
Fri, 12 Dec 2003 18:30:07 GMT |
|
 |
Greg Come #14 / 17
|
 char **str vs. char *str[]
Quote:
>> > Hmm, I would like to see the usage of the # give warnings like >> > int myfunc(int a[3]) >> > { >> > return a[0]+a[1]+a[2]; >> > } >> > int main(void) >> > { >> > int a[7]; >> > return myfunc(a); >> > } >> > Should give a warning in main saying the types are not of the >> > same dimension. >> there are no such warnings since as you know an array decays to >> a pointer to an array when passed to a function. So the >> dimension gets lost. Anyhow I don't see a problem with passing >> a 7-int-array to a function expecting a 3-int-array. I'ld >> rather like to have a warning for passing a to short array >> to the function. >There is no reason why the compiler doesn't keep track of the sizes. >And it is not against the C99 spec to give un-due warnings. It would be >a good idea [IMHO] to catch alot of nippy bugs.
I have to agree with Tom. That is, from a quality of implementation issue, it might help. The thing is that even thought the decay is guaranteed, the [3] really is a misnomer. I've almost wished for a long time that it wasn't even allowed and IMO this could be considered as a fundamental flaw in the language. Anyway, a warning would certainly help beginners who in generally really would have no clue of the decay. -- Greg Comeau Countdown to "export": December 15, 2001 Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout NEW: Try out libcomo! NEW: Try out our C99 mode!
|
Sat, 13 Dec 2003 09:21:16 GMT |
|
 |
Tom St Deni #15 / 17
|
 char **str vs. char *str[]
Quote:
> >> > Hmm, I would like to see the usage of the # give warnings like > >> > int myfunc(int a[3]) > >> > { > >> > return a[0]+a[1]+a[2]; > >> > } > >> > int main(void) > >> > { > >> > int a[7]; > >> > return myfunc(a); > >> > } > >> > Should give a warning in main saying the types are not of the > >> > same dimension. > >> there are no such warnings since as you know an array decays to > >> a pointer to an array when passed to a function. So the > >> dimension gets lost. Anyhow I don't see a problem with passing > >> a 7-int-array to a function expecting a 3-int-array. I'ld > >> rather like to have a warning for passing a to short array > >> to the function. > >There is no reason why the compiler doesn't keep track of the sizes. > >And it is not against the C99 spec to give un-due warnings. It would be > >a good idea [IMHO] to catch alot of nippy bugs. > I have to agree with Tom. That is, from a quality of implementation > issue, it might help. The thing is that even thought the decay is > guaranteed, the [3] really is a misnomer. I've almost wished for > a long time that it wasn't even allowed and IMO this could be > considered as a fundamental flaw in the language. Anyway, a warning > would certainly help beginners who in generally really would have > no clue of the decay.
Personally I never use [] as a function argument because I was always confused on the "decay" issue. Tom
|
Sat, 13 Dec 2003 09:27:55 GMT |
|
|