开发者

C Struct trouble [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center. 开发者_开发百科 Closed 12 years ago.

Below is some code I created to try to get a better understanding of how C uses structs.

As you might guess, I am not getting my desired results.

What I don't understand is how to access a struct within a struct AND I don't know what this code is actually doing.

EDIT

To be clearer, this code is not functioning. It is not printing the desired values. It is not printing 3 or 4 from Value or Suit.

Further Edit

Apparently the editor I was using was not saving the file properly. When I compiled it by hand I got the results I expected. Sorry for the confusion.

#include <stdio.h>

struct card 
{
    unsigned int value;
    unsigned int suit;
};


struct board
{
    struct card deck[52];
};


int main()
{
    struct board b;
    b.deck[0].value = 3;
    b.deck[0].suit = 4;
    
    printf("Card Value: %d Suit: %d \n", b.deck[0].value, b.deck[0].suit);
    
    return 0;
}


First determine if your struct is a true "C" struct or a "C++ struct". While they are both similar (or identical) in typing, if you use a C++ compiler, to get a true "C struct" you need to add the following around the struct:

extern "C" {
  ... // true C structs go here
}

Note that this is only an example of how a compiler might manage it's memory, real compilers manage their memory in manners which optimize the use of the underlying hardware. So the actual numbers, offsets, or order of operations might be wrong for your compiler; but, the general idea will be the same.

With C structs, the symbols (names) for the fields are translated into offsets. So when you use a C struct, the compiler builds an offset table based on the space each field needs (or the next address after that space which aligns with the memory subsystem). Later when you access that field, the running program adds the offset to the address of the beginning of the struct.

struct MyStruct {
  int x;
  int y;
  int z;
};

struct MyStruct coordinates;
coordinates.x = 3;
coordinates.y = 5;
coordinates.z = 7;

// assuming an int takes 4 bytes, and addressing is one address per byte
// the running (conceputual) code might look like

I've labeled address 0x00002300 as "coordinate"
I've labeled ".x" as "+0";
I've labeled ".y" as "+4";
I've labeled ".z" as "+8";

Which would have the code perform the following memory assignments

set 0x00002300 + 0 (which is 0x00002300) to 0x00000003
set 0x00002300 + 4 (which is 0x00002304) to 0x00000005
set 0x00002300 + 8 (which is (0x0002308) to 0x00000007

Note that in this theoretical example, the compiler made sure that the offsets were large enough to hold the values. Real world compilers might use more or less than a +4 offset for an int because their ints might take up more or fewer than 4 bytes, the address may not be one address per byte, or the memory subsystem might not be able to fetch an int from certain addresses. (Many memory subsystems must "align" data to the width of the data bus).

When you start mixing in arrays, the compiler keeps a note of the size of the whole struct, and uses that as an offset based on the array index. So

struct MyStruct coordinates[10];

coordinates[3].x = 3;
coordinates[3].y = 5;
coordinates[3].z = 7;

// assuming an int takes 4 bytes, addressing is one address per byte,
// and the entire "coordinates" struct takes up 12 bytes,
// the running (conceputual) code might look like

I've labeled address 0x00002300 as "coordinate"
I've labeled ".x" as "+0";
I've labeled ".y" as "+4";
I've labeled ".z" as "+8";
I've labeled the coordinate offset to be +12 which is "C" in Hex

Which would have the code perform the following memory assignments

set 0x00002300 + (3*c = 0x24) + 0 (which is 0x00002324) to 0x00000003
set 0x00002300 + (3*c = 0x24) + 4 (which is 0x00002328) to 0x00000005
set 0x00002300 + (3*c = 0x24) + 8 (which is (0x000232c) to 0x00000007

As for C++ structs, they are really C++ classes with the "default" scope set to "public" so

struct MyStruct {
   int x;
   int y;
   int z;
};

Compiled by a C++ compiler without the surrounding "extern "C" {" directive, will be treated exactly like

class MyStruct {
  public:
    int x;
    int y;
    int z;
};

And will rely heavily on the default implementations for the Constructor, copy-Constructor, etc.


No problem found in your program.. what is your desired output?

$ gcc test.c
$ ./a.exe
Card Value: 3 Suit: 4


A member of a struct is accessed by subscripting: board.deck accesses the deck member of the struct instance kept by the local variable board. board.deck is an array of card's, so further subscripting (via array bracket notation) is used to access an individual card instance. Then again, the dot notation is used to access a member of this very first card structure in board.


Your program is correct and has no errors.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜