Thread: what does a structure variable mean?

  1. #1
    Im a Capricorn vsriharsha's Avatar
    Join Date
    Feb 2002
    Posts
    192

    Lightbulb what does a structure variable mean?

    Hello,

    The following is a sample that I've tried...
    Code:
    struct st
    {
         char ch[4];
         int i;
    };
    
    int main()
    {
         struct st mystruct;
         mystruct.ch[0] = 'A';     // Ascii value 0x41 
         mystruct.ch[1] = 'B';     // Ascii value 0x42
         mystruct.ch[2] = 'C';     // Ascii value 0x43
         mystruct.ch[3] = 'D';     // Ascii value 0x44
         mystruct.i = 97;
    
         printf("Type 1: 0x%x\n",mystruct);
         printf("Type 2: %c\n",mystruct);
         return 0;
    }
    And the output is:
    Code:
    Type 1: 0x44434241
    Type 2: A
    I've used gcc 3.1 compiler to compile it on Redhat Linux 8.0 (cant change any of them )
    My Question
    What type will a structure variable assume? As can be seen from above code, if I print the structure variable as an int using %x, it prints the first 4 bytes and if I print it as a character, it prints only the first byte.
    So, how is it assuming it all? Or, is it just an Integer and since i've used %c, it is getting type-casted (internally or by printf) and getting printed??
    Last edited by vsriharsha; 08-26-2004 at 09:37 AM. Reason: Type error
    Help everyone you can

  2. #2
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    First of all, the program you posted can't give the stated output. Next time cut-and-paste your program to the message.

    your program has
    Code:
         mystruct.ch[0] = 'A';     // Ascii value 0x41 
         mystruct.ch[1] = 'B';     // Ascii value 0x42
         mystruct.ch[2] = 'C';     // Ascii value 0x43
         mystruct.ch[3] = 'D';     // Ascii value 0x44
    should be (I'm guessing)

    Code:
         mystruct.ch[0] = 'A';     // Ascii value 0x41 
         mystruct.ch[1] = 'B';     // Ascii value 0x42
         mystruct.ch[2] = 'C';     // Ascii value 0x43
         mystruct.ch[3] = 'D';     // Ascii value 0x44
    Now, as to what's happening:


    When a struct is used as an argument to a function, the entire struct is pushed on to the stack.

    If you want to see how the elements are stored, put the following in your program:



    Code:
      char *chpoint;
      int *intpoint;
      int num_ints;
      int i;
    
       ...
     
         chpoint = (char *)&mystruct;     
         intpoint = (int *)&mystruct;
    
         num_ints = sizeof(mystruct)/sizeof(int);
    
         printf("sizeof(mystruct) = %d\n", sizeof(mystruct));
    
         for (i = 0; i < sizeof(mystruct); i++) {
           printf("0x%08x  0x%02x\n", &chpoint[i], chpoint[i]);
         }
         printf("\n");
    
         for (i = 0; i < num_ints; i++) {
           printf ("0x%08x  0x%08x\n", &intpoint[i], intpoint[i]);
         }
         printf("\n");
    Now in this case, the elements of struct are packed into two ints

    The first int contains the bytes 0x41, 0x42, 0x43, and 0x44 (in that order).
    The second int contains the value of mystruct.i (decimal 97, the value of the ascii char 'a'.

    Now, when mystruct is pushed on the stack, apparently the two ints are pushed in reverse order so that the top of the stack in printf is the int containing the four chars.

    Your printf for type1 tells the printf to get an int off of the stack and print its value in hex, so you get 0x44434241 (it thinks it is an int, and this is how ints are stored in little-endian fashion).

    Your printf for type 2 tells printf to print a char. Now, chars are always passed as int, so printf gets an int off of stack: (the first four butes of the struct), and print the char value (the least significant byte of the int is 0x41).

    Ttttttthat's all folks (unless you want to try some things and tell us something different).

    Dave

  3. #3
    Has a Masters in B.S.
    Join Date
    Aug 2001
    Posts
    2,263
    pretty good explaination... Mr.Evans less garbled then what i probably would have done, but more generally what it comes down to is memory is memory its all in how you treat it.
    ADVISORY: This users posts are rated CP-MA, for Mature Audiences only.

  4. #4
    Im a Capricorn vsriharsha's Avatar
    Join Date
    Feb 2002
    Posts
    192
    Hi Dave,
    Thats cool, I just wanted that........
    So, finally the part that i missed was, its essentially passing a structure to a function..... ( sometimes you really overlook the obvious...... )....

    Thanks,
    harsha.
    Help everyone you can

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by no-one
    pretty good explaination... Mr.Evans less garbled then what i probably would have done, but more generally what it comes down to is memory is memory its all in how you treat it.
    Another thing it boils down to is that printf() doesn't actually know what you pushed on the stack. It gets things off of the stack according to the format specifiers: %d gets an int, %x gets an int, %c pops an int and uses the least significant 8-bits of the integer. There is not a format specifier for a struct (obviously); that's why you would print the elements of the struct according to the struct definition.

    Of course there is no guarantee that an int is 32 bits; it just happens to be for lots of compilers that users of this board typically encounter. Any tricks that depend on size of int or endianness of storage are Bad Things.

    On the other hand, I think it is a Good Thing to try to understand what's happing "behind the curtain", like seeing how bytes are stored, how arguments are pushed, etc.

    Best regards,

    Dave

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    your program has
    Code:
         mystruct.ch[0] = 'A';     // Ascii value 0x41 
         mystruct.ch[1] = 'B';     // Ascii value 0x42
         mystruct.ch[2] = 'C';     // Ascii value 0x43
         mystruct.ch[3] = 'D';     // Ascii value 0x44
    should be (I'm guessing)
    Code:
         mystruct.ch[0] = 'A';     // Ascii value 0x41 
         mystruct.ch[1] = 'B';     // Ascii value 0x42
         mystruct.ch[2] = 'C';     // Ascii value 0x43
         mystruct.ch[3] = 'D';     // Ascii value 0x44
    I don't see any difference between these two...
    If you understand what you're doing, you're not learning anything.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Well you could just turn on some warnings and then fix the code
    Code:
    $ gcc -W -Wall hello.c
    hello.c: In function `main':
    hello.c:17: warning: unsigned int format, st arg (arg 2)
    hello.c:18: warning: int format, st arg (arg 2)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by Salem
    Well you could just turn on some warnings and then fix the code
    Code:
    $ gcc -W -Wall hello.c
    hello.c: In function `main':
    hello.c:17: warning: unsigned int format, st arg (arg 2)
    hello.c:18: warning: int format, st arg (arg 2)
    An excellent point: the compiler (or some other tool, like lint) can sometimes point out your oopses, but printf() still doesn't know or care what you used as arguments. It gets its information from your format specification. The original post asked how he could be getting the output that he saw.

    Dave

  9. #9
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by itsme86
    I don't see any difference between these two...
    That's funny: I don't either.

    Oh, well...


    Dave

  10. #10
    Im a Capricorn vsriharsha's Avatar
    Join Date
    Feb 2002
    Posts
    192
    Hi..
    Sorry for the confusion...
    In my First (original) post, there was a typo error wherein, I assigned 'A','B','C','D' to mystruct.ch[0]. (Forgot to replace 0 with 1, 2 and 3 respectively and that was what Dave was pointing to. So, I went and edited the post (notice the comment below) so that others would stop pointing that error first....

    Cheers,
    Harsha...
    Help everyone you can

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C interview questions
    By natrajdreams in forum C Programming
    Replies: 7
    Last Post: 12-12-2010, 12:40 PM
  2. pthread question how would I init this data structure?
    By mr_coffee in forum C Programming
    Replies: 2
    Last Post: 02-23-2009, 12:42 PM
  3. Replies: 5
    Last Post: 02-14-2006, 09:04 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Variable is not a structure and Sort char **
    By ChazWest in forum C Programming
    Replies: 1
    Last Post: 03-08-2002, 09:40 AM