Thread: Simple structure + pointer question

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    81

    Red face Simple structure + pointer question

    Hi,

    I do not understand why the output of the following code like that:

    Name = Apple Pie
    ID = 123
    Price = 1.65

    Name = Greggs Coffee //do not understand
    ID = 733 //why the value will be back to the static
    Price = 3.20 //Was it caused by the keyword "static"?

    to hold the variable constant??

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

    struct sample {
    char *name;
    int *id;
    float price;
    };

    static char product[] = "Greggs Coffee";
    static float price1 = (float) 3.20;
    static int id = 733;

    void printrecord(struct sample *goods)
    {
    printf("Name = %s\n", goods->name);
    printf("ID = %d\n", *goods->id);
    printf("Price = %.2f\n", goods->price);

    goods->name = &product[0]; //Greggs Coffee
    goods->id = &id; //733
    goods->price = price1; //3.20
    }

    main()
    {
    int code = 123, number;
    char name[] = "Apple Pie";

    struct sample item;

    item.id = &code; //123
    item.price = (float) 1.65;
    item.name = name; //Apple Pie

    number = *item.id; //123

    printrecord(&item);

    printf("Name = %s\n", item.name); //Apple Pie
    printf("ID = %d\n", *item.id); //123
    printf("Price = %.2f\n", item.price); //1.65

    return 0;
    }


    Thanks for help.

    gogo

  2. #2
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    Code:
    printrecord(&item);
    This means that the structure that you pass as an arguement to the function 'printrecord' is passed as a pointer to the structure object in main. You could do this, and it would be the same thing:

    Code:
    	struct sample *sptr;
    	sptr = &item;
    	printrecord(sptr);
    The previous way looks better though. It looks cleaner. This means that any changes to the structure applied in the called function affect the structure in main. This is characteristic of passing an arguement by reference rather than by value. If you just did this, try it:
    Code:
                       //call from main
    	printrecord(item); 
    
    void printrecord(struct sample goods) 
    { 
    	printf("Name = %s\n", goods.name); 
    	printf("ID = %d\n", *goods.id); 
    	printf("Price = %.2f\n\n", goods.price); 
    
    	goods.name = &product[0]; //Greggs Coffee 
    	goods.id = &id; //733 
    	goods.price = price1; //3.20 
    }
    Than even though there are changes to the structure, as you can see. Since the structure was passed by value, a copy of the structure was passed. This has no bearing on the structure defined in 'int main()'

    Also, static is a scope specifier. It means that the variables are allocated once and remain that way for the life of the program. In cases with automatic variables, they are destroyed when the the function terminates. 'int main' is a little different because it does not terminate until the program is ended, since it is the point of entry. Try looking up the definition of 'static' to get some examples.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    81
    I am very sorry that I still do not understand why the second printf command will display Greggs Coffee, 3.20 and 773 for the global variables.

    What do I not understand are:

    1) I missed one code in between static variables and printrecord function: void printrecord(struct sample *);
    What is it and why does need it? Is it abstruct class?

    2) number = *item.id; //Why does need it? The number variable seems useless.

    3) printrecord(&item); // really do not understand. Does it pass the address of &item to the printrecord function? If so, were the data of &item are Apple Pie, 123 and 1.65?

    printf("Name = %s\n", item.name); //Apple Pie
    printf("ID = %d\n", *item.id); //123
    printf("Price = %.2f\n", item.price); //1.65

    Why does the outcome will be the global variables? Greggs Coffee, 3.20 and 773.

    Could you explain it to me?

    Thanks for your kind help.

    gogo

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Mercy me, that's a confusing hunk of code you've been given man.

    First, about declaring external variables static... It will only affect their linkage, which doesn't mean a darn thing unless your program is multiple files, so I'm just gonna get rid of those.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    struct sample {
    char *name;
    int *id;
    float price;
    };
    
    char product[] = "Greggs Coffee";
    float price1 = (float) 3.20;
    int id = 733;
    
    //This function does not just print the record it is given...
    //  It also changes the record.
    void printrecord(struct sample *goods)
    {
    // 1. Print the record.
    printf("Name = %s\n", goods->name);
    printf("ID = %d\n", *goods->id);
    printf("Price = %.2f\n", goods->price);
    
    // 2. Change the values in the record to the globals.
    goods->name = &product[0]; //Greggs Coffee
    goods->id = &id; //733
    goods->price = price1; //3.20
    }
    
    main()
    {
    int code = 123, number;
    char name[] = "Apple Pie";
    
    struct sample item;
    
    item.id = &code; //pointer to 123
    item.price = (float) 1.65;
    item.name = name; //Apple Pie
    
    number = *item.id; //123
    
    printrecord(&item);
    // item was printed to the screen, then changed
    
    // now we print item again, but the values in item will
    //  have changed due to printrecord.
    printf("Name = %s\n", item.name); //Apple Pie
    printf("ID = %d\n", *item.id); //123
    printf("Price = %.2f\n", item.price); //1.65
    
    return 0;
    }
    Now for your questions...
    1. printrecord(struct sample *); is called a prototype. Your code will work fine without it, but here's what prototypes are for.. consider the following code...
    Code:
    main ()
    {
     float f = addFloats(1.23, 4.56);
     printf ("%f", f);
     return;
    }
    float addFloats (float a, float b)
    {
     return (a + b);
    }
    When the compiler encounters the call of addFloats in main, it had not yet encountered the function, so it does not know exactly what format the functions arguments are, nor what the format of it's return type it. If the function addFloats was written before main, then this wouldn't have been a problem. This still leaves a dillema, for example, what if two functions call each other, which to put first? The solution is to declare prototypes for each function around the beginning of your program, which tell the compiler what type all the arguments are. Prototypes are also very handy simply because it's nice to have a list of your functions available when you start to use a lot of them.

    2. number = *item.id; You are correct, it is pretty useless, but like I said, this is super confusing code, so it needs some useless stuff. I think that line is just there to hammer in the idea that item.id is not an int, just a pointer to an int.

    3. Understand, this is what happens...
    printrecords is called...
    the structure is printed...
    the structure is changed to global variables...
    printrecords ends...
    the structure is printed.

    The lines that change the struct are right there in printrecords...
    goods->name = &product[0]; //Greggs Coffee
    goods->id = &id; //733
    goods->price = price1; //3.20

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    81
    Yes, // item was printed to the screen, then changed
    // now we print item again, but the values in item will
    // have changed due to printrecord.

    They are clearly explained. Thanks.

    Yes, I got the prototype now. But, in this case is no use as the printrecord is before the main function. It will be useful if printrecord function was put after main().

    Thanks for your kind help.

    gogo

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. Passing by Reference. Simple question.
    By d3m105 in forum C Programming
    Replies: 6
    Last Post: 10-31-2007, 12:47 PM
  3. Simple C# structure question
    By sketch in forum C# Programming
    Replies: 4
    Last Post: 09-14-2007, 04:29 PM
  4. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM