Question on argv and array of char string

L

Louis

Hi Guys:

I'm trying to understand argv in main, and i do understand it is an array of
character string. but when i try this its return error:

int main(int argc,char* argv[])
{
char* arofstr[] = {"foo", "bar", "baz"};


argv++; // i can do this
arofstr++; // i had compile error ISO C++ forbids cast to
non-reference type used as lvalue

cin.get();
return 0;
}

I thought arofstr is the same as argv since they are both a pointer to a
char array or array of char string.

Can anyone help me out Please!?

Thanks
Louis
 
T

Tim Love

Louis said:
I'm trying to understand argv in main
I suspect that you do understand it. Your problem's with arofstr[].
Even the simpler
char arofstr[] = {'f','o','o'};
arofstr++;
would fail, because arofstr can't be changed.
 
J

James Kanze

I'm trying to understand argv in main, and i do understand it
is an array of character string.

You understand wrong. It's a char**. A pointer to a pointer to
char. As usual, a pointer to something can be a pointer to the
first element of an array of those things---that's the case
here---but it is still a pointer.
but when i try this its
return error:
int main(int argc,char* argv[])

Don't be mislead by the way you've written it. The language
doesn't allow arrays as arguments, and treats this declaration
as if it were written:

int main( int argc, char** argv )
{
char* arofstr[] = {"foo", "bar", "baz"};

It does allow arrays as local variables, however, so here, you'd
declared and defined an array, not a pointer.
argv++; // i can do this

Yes, because argv is a pointer.
arofstr++; // i had compile error ISO C++ forbids cast to
non-reference type used as lvalue

Right, because arofstr is not a pointer or an arithmetic type.

In many contexts, it will convert to a pointer, but the result
of a conversion is not an lvalue, so cannot be incremented.
cin.get();
return 0;
}
I thought arofstr is the same as argv since they are both a
pointer to a char array or array of char string.

No. argv is a pointer to a pointer to char, arofstr is an array
of pointers to char. Two completely different things.
 
J

Juha Nieminen

James said:
No. argv is a pointer to a pointer to char, arofstr is an array
of pointers to char. Two completely different things.

There's a very simple way of demonstrating that argv and arofstr in
the given example are definitely *not* of the same type: Print the
values of sizeof(argv) and sizeof(arofstr).
 
J

James Kanze

There's a very simple way of demonstrating that argv and
arofstr in the given example are definitely *not* of the same
type: Print the values of sizeof(argv) and sizeof(arofstr).

Or typeid( argv ).name() and typeid( arofstr ).name(), if your
implementation has a usable implementation of typeid. (Most
compilers do---g++ seems to be the exception.) Good idea.
 
L

Louis

Hi James:

Thanks for your reply,i kind of getting the idea, and i try another test:

void test(char * ptr[])
{
cout << *ptr<< endl;
ptr++; // this work!
cout << *ptr << endl;
}



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

char* temp[] = { "foo", "woo", "wtf"}; //local

test(temp); //passing to funciton test

cin.get();

return 0;
}

If i pass the local array to the function, and do ptr++, it will work, is
that means,when i pass the array to the function test, which eq char * ptr[]
= temp, which result assgin a ptr to the 1st element of temp, and by
increment ptr, i'm actually increment the ptr, not the array temp itself and
that's why it is working?
which also imply if i do all this in local main, it also work because im
assign a ptr to a ptr of char to the temp array and it is the same as the
example above?

char ** ptr = temp;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;

Thanks!

Louis
There's a very simple way of demonstrating that argv and
arofstr in the given example are definitely *not* of the same
type: Print the values of sizeof(argv) and sizeof(arofstr).

Or typeid( argv ).name() and typeid( arofstr ).name(), if your
implementation has a usable implementation of typeid. (Most
compilers do---g++ seems to be the exception.) Good idea.
 
J

James Kanze

Thanks for your reply,i kind of getting the idea, and i try another test:
void test(char * ptr[])
{
cout << *ptr<< endl;
ptr++; // this work!
cout << *ptr << endl;
}
int main(int argc,char* argv[])
{
char* temp[] = { "foo", "woo", "wtf"}; //local
test(temp); //passing to funciton test
cin.get();
return 0;
}
If i pass the local array to the function,

You can't pass an array (local or otherwise) to a function. C++
doesn't allow it. There's no way to declare a function which
takes an array as an argument. You *can* pass a reference to an
array, a pointer to an array, or (what is the traditional way
from C), a pointer to the first element of an array. When you
write:
void test( char* ptr[] )
you are writing a lie. The type of the function is:
void test( char** ptr ) ;

This is a well known problem with C: arrays in C are broken.
The C++ standardization committee did consider the possibility
of "fixing" them, or at least making them less broken, but in
the end, decided that anything that they could do would only
break C compatibility, without really fixing them, and that
std::vector was an adequate replacement. Experience has shown
that this isn't 100% true; there are a few cases where the C
style array is still needed. Boost addressed most of these with
boost::array, which became tr1::array, and will be std::array in
the next standard.
and do ptr++, it will work, is
that means,when i pass the array to the function test,

It means that you're not passing an array to the function test.
Try
void test( char* (&array)[ 3 ] )
(Note that in this case, the size is part of the type.)

Better yet, get an implementation of tr1::array, and use it.
which eq char * ptr[] = temp, which result assgin a ptr to the
1st element of temp, and by increment ptr, i'm actually
increment the ptr, not the array temp itself and that's why it
is working?
Exactly.

which also imply if i do all this in local main, it also work
because im assign a ptr to a ptr of char to the temp array and
it is the same as the example above?
char ** ptr = temp;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;

Yes. Pointers are funny beasts in C++ as well (for historical
reasons). Practically speaking, unless you're writing really
low level code (like memory management), you should avoid
pointer arithmetic.
 

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

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top