pointer to pointer

Discussion in 'C Programming' started by arnuld, Dec 22, 2010.

  1. arnuld

    arnuld Guest

    Its just a very simple and basic program to learn exactly what is
    described in comments here. Can you provide a better (and short)
    exercise ?


    /* A program to learn how to use a pointer to a pointer. Here we take an
    array of char pointers. A char* in the array, of course, points
    * to some char. Array has only one element. We change the value of char
    pointed by array's element using a function.
    *
    * VERSION 0.0
    */
    #include <stdio.h>

    void replace_char_value(char* [], char);

    int main(void)
    {
    char* arrc[2] = {0};
    char c = 'c';
    arrc[0] = &c;

    printf("*arrc: %p, **arrc: %c\n", (void*)*arrc, **arrc);
    replace_char_value(arrc, 'w');
    printf("*arrc: %p, **arrc: %c\n", (void*)*arrc, **arrc);

    return 0;
    }


    void replace_char_value(char* arr[], const char t)
    {
    **arr = t;
    }

    ==================== OUTPUT =======================
    [arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra pointer-to-
    pointer.c
    [arnuld@dune programs]$ ./a.out
    *arrc: 0xbfffe8ab, **arrc: c
    *arrc: 0xbfffe8ab, **arrc: w
    [arnuld@dune programs]$




    --
    http://www.lispmachine.wordpress.com
    arnuld, Dec 22, 2010
    #1
    1. Advertising

  2. arnuld

    Ian Collins Guest

    On 12/22/10 04:43 PM, arnuld wrote:
    > Its just a very simple and basic program to learn exactly what is
    > described in comments here. Can you provide a better (and short)
    > exercise ?


    Parse the arguments to a program. Don't forget argv is a pointer to
    pointer!

    Given ./a.out -a 10 -b 20

    print out the values of a and b.

    --
    Ian Collins
    Ian Collins, Dec 22, 2010
    #2
    1. Advertising

  3. arnuld

    Mark Wooding Guest

    arnuld <> writes:

    > Its just a very simple and basic program to learn exactly what is
    > described in comments here. Can you provide a better (and short)
    > exercise ?


    Several linked-list idioms involve a pointer-to-a-pointer. The most
    obvious ones are

    * Removing an item from a singly-linked list.

    * Inserting an item into a sorted singly-linked list.

    * Building up a list in order, one at a time.

    The last is especially simple, and will serve as an example of the
    general technique. Suppose that you have a node structure like this

    struct node {
    struct node *next;
    /* other members here */
    };

    You build a list in order by remembering where the trailing link is.
    Initially, the trailing link is actually the list head pointer.

    struct node *head, **tail = &head;
    struct node *n;

    To attach a new node n to the list, you do this:

    *tail = n;
    tail = &n->next;

    and finally you terminate the list like this:

    *tail = 0;

    I encourage you to draw diagrams to see why this works.

    Of course, you can abstract the core of the algorithm into a function.
    If you do this in the obvious way, you will find that you need to pass
    in the /address/ of the trailing-link pointer, which is a pointer to a
    pointer to a pointer:

    static link_to_end(struct node *n, struct node ***tail)
    {
    **tail = n;
    *tail = &n->node;
    }

    This is the simplest natural example I know of for a `three-star'
    pointer.

    -- [mdw]
    Mark Wooding, Dec 22, 2010
    #3
  4. arnuld

    arnuld Guest

    > On Wed, 22 Dec 2010 17:05:29 +1300, Ian Collins wrote:

    > Parse the arguments to a program. Don't forget argv is a pointer to
    > pointer!
    >
    > Given ./a.out -a 10 -b 20
    >
    > print out the values of a and b.



    How about this. Two questions:

    (1) How to write it better ?
    (2) How to avoid OUTPUT-2 ?



    /* A program given by Ian Collins on CLC. Parse input to C Program this
    way:
    * GIVEN: ./a.out a -10 b 2, print out values of a and b
    *
    * Assumptions: separator between 2 values is one space. User may enter
    two elements together without any value but then program will
    * take 2nd element as value of first element.
    * VERSION 0.0
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void printElementAndValue(char** t);

    int main(int argc, char* argv[])
    {
    /* char* pe; Pointer to element */
    /* char* pv; Pointer to value */
    char** t;

    if(1 == argc)
    {
    printf("USE: ./a.out [ELEMENT1] [VALUE1] [ELEMENT2] [VALUE2] ....
    \n");
    exit(EXIT_FAILURE);
    }
    else if(0 == (argc % 2))
    {
    printf("Please enter proper input: [ELEMENT] [VALUE] \n");
    exit(EXIT_FAILURE);
    }

    for(t = argv + 1; *t; ++t, ++t)
    {
    printElementAndValue(t);
    }

    return 0;
    }


    void printElementAndValue(char** t)
    {
    const char element_identifier = '-';
    if(strchr(*t, element_identifier))
    {
    printf("%s = ", *t++);
    printf("%s\n", *t);
    }
    else
    {
    printf("Improper input. Key identifier, '-', was not used ?\n");
    }

    }
    ==================== OUTPUT ==============================
    [arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra PtoP_argv-
    parse.c
    [arnuld@dune programs]$ ./a.out -a 10 -b 3
    -a = 10
    -b = 3
    [arnuld@dune programs]$



    ================= OUTPUT-2 ==========================
    [arnuld@dune programs]$ ./a.out -a 10 -b *
    -a = 10
    -b = a.out
    Improper input. Key identifier, '-', was not used ?
    Improper input. Key identifier, '-', was not used ?
    problem-scanf.c = PtoP_argv-parse.c
    PtoP_argv-parse.c~ = scanf-problems.c
    sequence-point.c = strcpy.c
    Improper input. Key identifier, '-', was not used ?
    [arnuld@dune programs]$




    --
    http://www.lispmachine.wordpress.com
    arnuld, Dec 23, 2010
    #4
  5. arnuld

    Chad Guest

    On Dec 21, 8:05 pm, Ian Collins <> wrote:
    > On 12/22/10 04:43 PM, arnuld wrote:
    >
    > > Its just a very simple and basic program to learn exactly what is
    > > described in comments here. Can you provide a better (and short)
    > > exercise ?

    >
    > Parse the arguments to a program.  Don't forget argv is a pointer to
    > pointer!
    >
    > Given ./a.out -a 10 -b 20
    >
    > print out the values of a and b.
    >


    I don't get the point of this exercise. Maybe I'm missing "it'.
    Anyways, here is what I came up with..

    #include <stdio.h>

    int main(int argc, char **argv)
    {
    int i;
    char dash, letter;

    for (i = 1; i < argc; i++) {
    dash = argv[0];
    letter = argv[1];

    if (dash == '-' && letter == 'a') {
    printf("a = %s\n", argv[++i]);
    }
    if (dash == '-' && letter == 'b') {
    printf("b = %s\n", argv[++i]);
    }
    }

    return 0;
    }

    [cdalten@localhost oakland]$ gcc -Wall -Wextra -ansi -pedantic
    parseab.c -o parseab
    [cdalten@localhost oakland]$ ./parseab -a 10 -b 20
    a = 10
    b = 20
    [cdalten@localhost oakland]$ ./parseab -a 10
    a = 10
    [cdalten@localhost oakland]$ ./parseab -b 40
    b = 40
    [cdalten@localhost oakland]$ ./parseab
    [cdalten@localhost oakland]$ ./parseab b 40
    [cdalten@localhost oakland]$ ./parseab a 40
    [cdalten@localhost oakland]$ ./parseab a 40 b 40
    [cdalten@localhost oakland]$ ./parseab -b 40 -a 100
    b = 40
    a = 100
    [cdalten@localhost oakland]$
    Chad, Dec 25, 2010
    #5
  6. arnuld

    Chad Guest

    On Dec 25, 12:23 pm, Chad <> wrote:
    > On Dec 21, 8:05 pm, Ian Collins <> wrote:
    >
    > > On 12/22/10 04:43 PM, arnuld wrote:

    >
    > > > Its just a very simple and basic program to learn exactly what is
    > > > described in comments here. Can you provide a better (and short)
    > > > exercise ?

    >
    > > Parse the arguments to a program.  Don't forget argv is a pointer to
    > > pointer!

    >
    > > Given ./a.out -a 10 -b 20

    >
    > > print out the values of a and b.

    >
    > I don't get the point of this exercise. Maybe I'm missing "it'.
    > Anyways, here is what I came up with..
    >


    And here is my attempt at the pointer solution. It's kind of ugly, but
    it appears to work correctly...

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    int main(int argc, char **argv)
    {
    char *letter ="";
    char *number ="";

    while (--argc > 0) {
    letter = *++argv;
    number = *++argv;

    if (letter != NULL && (strcmp(letter, "-a")) == 0 ) {
    if(number != NULL && (strcmp(number, "-b")) == 0 ) {
    number = *++argv;
    if (number != NULL) {
    printf("No number provided for a\n");
    printf("b = %s\n", number);
    exit(EXIT_SUCCESS);
    } else {
    printf("No number provided for a and b\n");
    exit(EXIT_FAILURE);
    }
    }
    printf("a = %s\n", number ? number : "No number provided for a
    \n");
    }
    if (letter != NULL && (strcmp(letter, "-b")) == 0 ) {
    if(number != NULL && (strcmp(number, "-a")) == 0 ) {
    printf("No number provided for b and a\n");
    exit(EXIT_FAILURE);
    }
    printf("b = %s\n", number ? number : "No number provided for b
    \n");
    }
    }

    exit(EXIT_SUCCESS);
    }
    [cdalten@localhost oakland]$ gcc -g -Wall -Wextra -ansi -pedantic
    parseab2.c -o parseab2
    [cdalten@localhost oakland]$ ./parseab2
    [cdalten@localhost oakland]$ ./parseab2 -a
    a = No number provided for a

    [cdalten@localhost oakland]$ ./parseab2 -a -b
    No number provided for a and b
    [cdalten@localhost oakland]$ ./parseab2 -a -b 10
    No number provided for a
    b = 10
    [cdalten@localhost oakland]$ ./parseab2 -a 10 -b
    a = 10
    b = No number provided for b

    [cdalten@localhost oakland]$ ./parseab2 -a 10 -b 20
    a = 10
    b = 20
    [cdalten@localhost oakland]$ ./parseab2 -b 10 -a
    b = 10
    a = No number provided for a

    [cdalten@localhost oakland]$ ./parseab2 -b 10 -a 50 20
    b = 10
    a = 50
    [cdalten@localhost oakland]$
    Chad, Dec 25, 2010
    #6
  7. arnuld

    Ike Naar Guest

    On 2010-12-25, Chad <> wrote:
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    >
    > int main(int argc, char **argv)
    > {
    > char *letter ="";
    > char *number ="";
    >
    > while (--argc > 0) {
    > letter = *++argv;
    > number = *++argv;


    You iterate argc-1 times through this loop, and in each iteration
    argv is advanced at least two times. That means that for certain
    argument lists you're accessing non-existing elements of argv.

    Let's take, for example, the argument list ``the quick brown fox''.
    argc=5, argv[0]=progname, argv[1]="the", argv[2]="quick",
    argv[3]="brown", argv[4]="fox", argv[5]=NULL.

    In the first iteration, you handle argv[1] ("the") and argv[2] ("quick").
    In the second iteration, you handle argv[3] ("brown") and argv[4] ("fox").
    In the third iteration, you handle argv[5] (NULL) and argv[6] (and
    here the program goes off the rails).
    Ike Naar, Dec 26, 2010
    #7
  8. arnuld

    arnuld Guest

    > On Dec 26, 1:23 am, Chad <> wrote:


    > I don't get the point of this exercise. Maybe I'm missing "it'.
    > Anyways, here is what I came up with..
    >
    > #include <stdio.h>
    >
    > int main(int argc, char **argv)
    > {
    >   int i;
    >   char dash, letter;
    >
    >   for (i = 1; i < argc; i++) {
    >     dash = argv[0];
    >     letter = argv[1];
    >
    >     if (dash  == '-' && letter == 'a') {
    >       printf("a = %s\n", argv[++i]);
    >     }
    >     if (dash  == '-' && letter == 'b') {
    >       printf("b = %s\n", argv[++i]);
    >     }
    >   }
    >
    >   return 0;
    >
    > }


    > ...SNIP....



    I think "Ian Collins" meant uknown number of arguments (rather than
    two). Still even if he meant two arguments -a and -b, still your
    program confuses a bit because at first it iterates for --argc times
    but then at same time it it handles only two variables (which may or
    may not not equal to --argc). I think if you want to deal with only 2
    argiments then (i < 3) must be the conditional check.

    Nice cleaner code with array indexing though :)
    arnuld, Dec 27, 2010
    #8
    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. Replies:
    10
    Views:
    697
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    837
    Jordan Abel
    Mar 28, 2006
  3. Replies:
    4
    Views:
    1,249
    Fred Zwarts
    Jul 2, 2009
  4. A
    Replies:
    7
    Views:
    633
  5. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    451
    James Kuyper
    Sep 23, 2011
Loading...

Share This Page