Thread: incrementing character strings? pointers? HELP!

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    66

    incrementing character strings? pointers? HELP!

    consider the following code...

    Code:
    # include <stdio.h>
    
    struct foo {
        int     num;
        char    *word;
        struct  foo *ptr;
    };
    
    void func1(struct foo);
    void func2(struct foo*);
    void func3(struct foo);
    
    int main() {
        
        struct foo a;
        
            a.num = 5;
            a.word = "myword";
            func1(a);
            printf("1 %d %s\n", a.num, a.word);
        
            a.num = 100;
            a.word = "secondword";
            func2(&a);
            printf("2 %d %s\n", a.num, a.word);
            
            a.ptr = &a;
            a.num = 50;
            a.word = "mylastword";
            func3(a);
            printf("4 %d %s\n", a.num, a.word);   
        
        system("pause");
        
    return(0);
    }
    
    void func1(struct foo a) {
        
        while(*(a.word) != '\0') {
            putchar(*(a.word));
            a.word++;
        }
        putchar('\n');
        if(a.num % 10 != 0)
            a.num *= 2;
        a.word--;
        printf("num is %d\n", a.num);
    }
    
    void func2(struct foo *a) {
        
        while(*(a->word) != '\0') {
            putchar(*(a->word));
            a->word++;
        }
        putchar('\n');
        if(a->num %10 != 0)
            a->num *= 2;
        a->word--;
        printf("num is %d\n", (*a).num);
    }
    
    void func3(struct foo a) {
        
        if(a.num > a.ptr->num)
            a.num = 500;
        else
            a.num = a.ptr->num + 1;
            
        a.word = "myotherword";
        a.ptr->word = "yetanotherword";
        printf("3 %d %s\n", a.num, a.word);
    }
    if you copy that into your compiler, line 47, 55 and 60 baffle me. i run the program with and without them and i get the same outputs. WHAT THE HECK DO THEY DO?

    also, i am confused as to what the a.ptr does in the func3(). i realize its a pointer but why is it used? is it just a different way to do pass by ref without the *a in the function declaration?


    edit: i was wrong, removing the decrementing a.word from line 55 prints 's' forever. but i still dont understand its use. with it it only prints 1 's'. i'm more confused now than i was before.
    Last edited by ominub; 05-01-2009 at 02:30 PM.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    That code is very bad. It does a buffer underrun on line 55, and thus will give you undefined behavior. The fact that it doesn't crash is pure luck. The decrement on line 47 doesn't do anything. The decrement on 60 is a continuation of the buffer underrun. There is no purpose for the ptr member of a either.

    I hope you're not trying to learn anything from that code, because it is a mess.

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    well this code is made to confuse the reader. its a practice for my final exam and we are supposed to trace it and print its output. it serves absolutely no purpose other than that. also line 55 should be a.word++ not -- i will fix it on the original post also.

    could you please breifly explain what a buffer underrun is?

    so, the ptr in the struct is just to confuse? it serves no purpose?

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    An underrun is when you decrement the pointer so that it goes below the start of a block of memory. In this case, when it runs before the start of the string.
    Code:
    char *word = "hello";
    char *underrun = word -1;
    char *overrun = word + 6;
    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    i think i understand.

    i only have 1 more question.

    on the last 3 lines... when func3 prints a.num and a.word it prints "myotherword" then when the function ends and the printf in main prints a.num and a.word again, it prints "yetanotherword" how does the pointer do this?

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    The same way this works:
    Code:
    #include<stdio.h>
    void foo( int x )
    {
        x = 10;
        printf( "x is %d\n", x );
    }
    
    int main( void )
    {
        int x = 5;
    
        printf( "x is %d\n", x );
        foo( x );
        printf( "x is %d\n", x );
    
        return 0;
    }
    To change a value of something passed to a function, you need its address. You could change x so that it kept the change outside of the function, if you were passing its address. You aren't though, you're just passing its value.

    Pointers work exactly like other variables. They store values. The value they store is an address. So, if you want a pointer to be able to change that address, then you need a pointer to that pointer, not just a single pointer. Think of it as the above example. You can't make x change because you aren't passing a pointer to x. You can't make the pointer change (point to something else) because you aren't actually passing a pointer to that pointer.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    wow. it seems really complicated. i think ill be able to figure it out after a little practice. what is the purpose of declaring a pointer like this?
    Code:
    struct foo {
        int        num;
        char     *word;
        struct  foo *ptr;
    };
    i understand its a pointer to the structure, and i understand pointing to the pointer but if the pointer just points to the structure, why not just point to the structure instead? im sure there is a purpose, apart from this program, what is a more clear application to illustrate its usefulness?

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Read pointers backwards.
    Code:
    struct foo *ptr;
    The variable named ptr...
    * points to...
    An object of type struct foo.

    To figure out what you can do with your pointer, just think of * as meaning I can change the value of...

    Code:
    struct foo *ptr;
    Through the variable ptr...
    I can change value of...
    An object of type struct foo.

    So, given a pointer to a structure, you are allowed to change the contents of that structure.

    Code:
    struct foo * *ptr;
    Through the variable ptr...
    I can change value of...
    An object of type struct foo *. ("pointer to an object struct foo")

    Therefore, we can change the value of the object "struct foo *", meaning, we can make it point at another structure of type foo.

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    thanks for the detailed response. it really cleared everything up. its pretty interesting.

    so let me make sure i got it all.

    when you declare a pointer to a structure inside of a structure you can point to the pointer and change any of the contents of the structure pointed to?

    like the line:

    Code:
    a.ptr->word = "yetanotherword";
    this program obviously is not a very good example but a.ptr points to struct foo and then to word inside struct foo?

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    There are a couple of ways to be able to change word.

    1. Pass the address of the actual portion of the structure that you wish to be able to change. In this case, a pointer to word. Since word is a character pointer, we need a pointer to a pointer.
    Code:
    struct foo
    {
        char * word;
    };
    
    void bar( char ** ptrtocharptr )
    {
        if( ptrtocharptr )
        {
            *ptrtocharptr = "newstringliteral";
        }
    }
    
    ...
    
    struct foo baz;
    
    bar( &(baz.word ) );
    2. Pass the address of the whole structure. Because, given the address of something, your changes will keep. Since word is a part of that structure, if you have its address, your changes will keep:
    Code:
    void bar( struct foo *ptrtostruct )
    {
        if( ptrtostruct )
        {
            ptrtostruct->word = "newstringliteral";
        }
    }
    Just remember, if you want to keep the changes to something, you have to have had a pointer to it, or to the object it is a part of. If you want to change the value of an int, you need a pointer to an int. If you want a pointer to point to something else (to change the pointer's value), you need a pointer to that pointer.

    Just think of pointers like any other variable. They store a value. The value happens to be a memory location. If you want to change a value of something you were passed in your function call, you have to have its address.

    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    OK. i think i got it. thank you for the help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. newbie question on strings & pointers
    By MK27 in forum C Programming
    Replies: 6
    Last Post: 08-05-2008, 05:50 AM
  3. array of character pointers
    By RedRum in forum C++ Programming
    Replies: 6
    Last Post: 05-06-2002, 10:05 PM
  4. Pointers to pointers to strings
    By Natase in forum C Programming
    Replies: 2
    Last Post: 09-17-2001, 11:30 PM
  5. pointer to pointers to arrays of strings??
    By Binkstone in forum C Programming
    Replies: 8
    Last Post: 09-14-2001, 02:56 AM