difference(s) between char** argv and char* argv[]

D

David

what's the differences between:

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

and:

int main(int argc,char** argv){
...
}

it seems that in the first example, argv is an array of char* and in
the second example it's a pointer to char*? one of my C book tells me
that the difference is horriblly subtle but doesn't actually discribe
what the difference is. i can use them interchangeablly right?
 
A

Arthur J. O'Dwyer

what's the differences between:

int main(int argc,char* argv[])
int main(int argc,char** argv)
it seems that in the first example, argv is an array of char* and in
the second example it's a pointer to char*? one of my C book tells me
that the difference is horriblly subtle but doesn't actually discribe
what the difference is. i can use them interchangeably right?

Yes. They're EXACTLY THE SAME THING. You have already been told this,
several times, modulo Tisdale's muddyings. [Ignore him.]

bar_t foo ( baz_t quux[] );

is exactly equivalent to

bar_t foo ( baz_t *quux );

in all respects.

The difference between p[] and *p comes OUTSIDE function prototypes,
where, for example,

extern int arr[];

declares 'arr' to be of type 'array[unspecified size] of int',
otherwise known as an "incomplete array type." Since the type
of 'arr' is incomplete, you can't, for example, take the 'sizeof'
the array. Contrariwise,

extern int *ptr;

declares 'ptr' to be of type 'pointer to int', and is not incomplete.
That is, you can use 'ptr' in the same way you'd use any pointer,
including, of course, taking the 'sizeof' it.

Just don't worry about these things until you have done the exercises
in the first five chapters of K&R (or equivalent). Then you can
start worrying about becoming a language lawyer. :)

HTH,
-Arthur
 
E

E. Robert Tisdale

Arthur said:
David said:
what's the differences between:

int main(int argc,char* argv[])
int main(int argc,char** argv)

it seems that in the first example, argv is an array of char* and in
the second example it's a pointer to char*? one of my C book tells me
that the difference is horribly subtle but doesn't actually describe
what the difference is. I can use them interchangeably right?

Yes. They're EXACTLY THE SAME THING.

Please don't shout.
You have already been told this, several times,

When was David told this?
modulo Tisdale's muddying. [Ignore him.]

bar_t foo(baz_t quux[]);

is exactly equivalent to

bar_t foo(baz_t* quux);

in all respects.

The difference between p[] and *p comes OUTSIDE function prototypes,

You probably meant formal argument lists.
baz_t quux[] and baz_t* quux mean the same thing
in the *definition of function foo as well as in its declaration.
where, for example,

extern int arr[];

declares 'arr' to be of type 'array[unspecified size] of int',
otherwise known as an "incomplete array type." Since the type
of 'arr' is incomplete, you can't, for example, take the 'sizeof'
the array. Contrariwise,

extern int *ptr;

declares 'ptr' to be of type 'pointer to int', and is not incomplete.
That is, you can use 'ptr' in the same way you'd use any pointer,
including, of course, taking the 'sizeof' it.

Just don't worry about these things until you have done the exercises
in the first five chapters of K&R (or equivalent). Then you can
start worrying about becoming a language lawyer. :)

Please cite and quote the FAQ
that you believe is most relevant to David's question.
 
R

Richard Heathfield

David said:
what's the differences between:

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

and:

int main(int argc,char** argv){
...
}

No differences.
it seems that in the first example, argv is an array of char*

No, it's a pointer to the first element in an array of strings. Its type is
"pointer to pointer to char", despite appearances.
and in
the second example it's a pointer to char*?

Yes, in the second example, argv is a pointer to the first element in an
array of strings. Its type is "pointer to pointer to char".

Read K&R2 pp99-100.
one of my C book tells me
that the difference is horriblly subtle

The author of that book is either mistaken or lying - probably just
mistaken. Consider that to be one black mark against the book, since he
really should have known this. Which book is it?
but doesn't actually discribe
what the difference is.

There is none.
i can use them interchangeablly right?

Of course. They have the same type. These are just two different ways of
writing the same thing.
 
R

Richard Heathfield

E. Robert Tisdale said:
Arthur J. O'Dwyer wrote:
The difference between p[] and *p comes OUTSIDE function prototypes,

You probably meant formal argument lists.

It amounts to the same thing, in this case, so your objection is pointless.
baz_t quux[] and baz_t* quux mean the same thing
in the *definition of function foo as well as in its declaration.

In this code:

int main(int argc, char **argv)
{
return 0;
}

main() is declared, defined, and prototyped, all at once.

A prototype is merely a function declaration in which the types of all the
parameters are given. A definition is also a declaration.
 
D

David

Richard Heathfield said:
David said:
what's the differences between:

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

and:

int main(int argc,char** argv){
...
}

No differences.
it seems that in the first example, argv is an array of char*

No, it's a pointer to the first element in an array of strings. Its type is
"pointer to pointer to char", despite appearances.
and in
the second example it's a pointer to char*?

Yes, in the second example, argv is a pointer to the first element in an
array of strings. Its type is "pointer to pointer to char".

Read K&R2 pp99-100.
one of my C book tells me
that the difference is horriblly subtle

The author of that book is either mistaken or lying - probably just
mistaken. Consider that to be one black mark against the book, since he
really should have known this. Which book is it?
but doesn't actually discribe
what the difference is.

There is none.
i can use them interchangeablly right?

Of course. They have the same type. These are just two different ways of
writing the same thing.

if there is no differences between the 2 and i can use them
interchangeablly, why does C support the extra syntax? is this one of
those syntactic sugar thing?
just because a[2] looks better than *(a+2)?
 
D

David

Arthur J. O'Dwyer said:
what's the differences between:

int main(int argc,char* argv[])
int main(int argc,char** argv)
it seems that in the first example, argv is an array of char* and in
the second example it's a pointer to char*? one of my C book tells me
that the difference is horriblly subtle but doesn't actually discribe
what the difference is. i can use them interchangeably right?

Yes. They're EXACTLY THE SAME THING. You have already been told this,
several times, modulo Tisdale's muddyings. [Ignore him.]
[snip]


Just don't worry about these things until you have done the exercises
in the first five chapters of K&R (or equivalent). Then you can
start worrying about becoming a language lawyer. :)

no i am not trying to be a language lawyer. just trying to understand
the fundamental differences between the 2 so i don't use them in the
wrong way. now i wonder why C support 2 difference syntax when one is
enough...
 
A

Alan Balmer

Of course. They have the same type. These are just two different ways of
writing the same thing.

if there is no differences between the 2 and i can use them
interchangeablly, why does C support the extra syntax? is this one of
those syntactic sugar thing?
just because a[2] looks better than *(a+2)?

First, note that they are the same thing only in some contexts. Read
Arthur O'Dwyer's posting carefully.

That said, the [] notation is traditional for arrays, of course, and
it or equivalent notation is used in just about every language that
supports arrays. The pointer notation happens to be the way C
implements arrays, so it's equivalent. The choice of notation can
still be significant since it affects the "flavor " of the code, and
can make it clear what the intention and mind-set of the author is.
For example, If I have a table x of integer values, I find it natural
to think of an entry in that table as x. OTOH, in parsing an array
of characters, I find it more natural to assign a pointer to the
beginning and increment the pointer as I work through the array.
 
R

Richard Heathfield

David wrote:

<snip. See subject line. The discussion generalises to the exchangeability
of T *p vs T p[] in formal parameter lists.>
if there is no differences between the 2 and i can use them
interchangeablly,

....in formal parameter lists, yes. Not in the body of a function.

why does C support the extra syntax?

H[iy]st[oe]rical reasons.
is this one of
those syntactic sugar thing?

It's a h[iy]st[oe]rical accident. [] was originally used in C to mean
"pointer", but it was later munged into its current "array" usage. The
vestigial traces of its pointer heritage remain in function parameter
lists, possibly because to remove those traces would have broken too much
existing code.
just because a[2] looks better than *(a+2)?

Does it?
 
D

Dave Thompson

David wrote:

<snip. See subject line. The discussion generalises to the exchangeability
of T *p vs T p[] in formal parameter lists.>
if there is no differences between the 2 and i can use them
interchangeablly,

...in formal parameter lists, yes. Not in the body of a function.
Right. Or, more precisely, in the declaration of a (formal)
parameter, which contrary to a loose statement elsethread can either
be in a prototype *or* in old-style/K&R1 definition; in both cases the
syntax allows a list, although an actual case may be a singleton.
Not at local scope or file scope (outside any function).
why does C support the extra syntax?

H[iy]st[oe]rical reasons.
If you do that, you must also do r{ea,ai}s[oi]ns. Bleah.
is this one of
those syntactic sugar thing?

It's a h[iy]st[oe]rical accident. [] was originally used in C to mean
"pointer", but it was later munged into its current "array" usage. The
vestigial traces of its pointer heritage remain in function parameter
lists, possibly because to remove those traces would have broken too much
existing code.
Nit: in C's history or development, but not actually C. Per dmr's
2HOPL paper, the transition from actual pointers in BCPL and B to
array decay was one of two changes, the other being complex types
(using declaration-follows-use), that distinguished C from new B.

But yes existing code was the reason to retain the optional old syntax
-- which in hindsight may not have been worth all the angst it has
since caused, but it's way too late now.

- David.Thompson1 at worldnet.att.net
 
R

Richard Heathfield

Dave said:
It's a h[iy]st[oe]rical accident. [] was originally used in C to mean
"pointer", but it was later munged into its current "array" usage. The
vestigial traces of its pointer heritage remain in function parameter
lists, possibly because to remove those traces would have broken too much
existing code.
Nit: in C's history or development, but not actually C.

dmr's source code disagrees.
http://www.cs.bell-labs.com/who/dmr/last1120c/c00.c
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Communicating between processes 0
Questions about argv 14
char* argv[] 24
char **argv & char *argv[] 5
Command Line Arguments 0
Understanding char **argv 7
Argv question 2
The different ways to use argv 8

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top