Question on argv and array of char string

Discussion in 'C++' started by Louis, Mar 13, 2009.

  1. Louis

    Louis Guest

    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
     
    Louis, Mar 13, 2009
    #1
    1. Advertising

  2. Louis

    Tim Love Guest

    "Louis" <> writes:

    >Hi Guys:


    >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.
     
    Tim Love, Mar 13, 2009
    #2
    1. Advertising

  3. Louis

    James Kanze Guest

    On Mar 13, 7:39 am, "Louis" <> wrote:

    > 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Mar 13, 2009
    #3
  4. James Kanze wrote:
    >> 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.


    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).
     
    Juha Nieminen, Mar 14, 2009
    #4
  5. Louis

    James Kanze Guest

    On Mar 14, 4:29 pm, Juha Nieminen <> wrote:
    > James Kanze wrote:
    > >> 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.


    > 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Mar 15, 2009
    #5
  6. Louis

    Louis Guest

    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
    "James Kanze" <> wrote in message
    news:...
    On Mar 14, 4:29 pm, Juha Nieminen <> wrote:
    > James Kanze wrote:
    > >> 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.


    > 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    Louis, Mar 16, 2009
    #6
  7. Louis

    James Kanze Guest

    On Mar 16, 1:12 am, "Louis" <> wrote:

    > 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Mar 16, 2009
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bret

    char **argv vs. char* argv[]

    Bret, Aug 31, 2003, in forum: C Programming
    Replies:
    21
    Views:
    4,626
    Richard Heathfield
    Sep 3, 2003
  2. David
    Replies:
    10
    Views:
    5,996
    Richard Heathfield
    Sep 15, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,674
    Old Wolf
    Jan 20, 2004
  4. jab3

    char **argv & char *argv[]

    jab3, Dec 4, 2004, in forum: C Programming
    Replies:
    5
    Views:
    677
    Chris Torek
    Dec 8, 2004
  5. oogie
    Replies:
    9
    Views:
    661
    Default User
    Nov 18, 2007
Loading...

Share This Page