panchiamit
panchiamit

Reputation: 1

Structure - Access Structure element without . and ->

I am required to access some elements from nested structure without using . and ->

I need to print out the values for keyValue and alternateKeyValue from the Test laptop definition without using the . or -> operators to directly reference the qwerty struct or its members.

Here's the structure.

typedef struct
{
    bool leftButton;
    bool rightButton;
    bool middleButton;
    bool mouseOn;
    mouse_direction_E direction;
} mouse_S;

typedef struct
{
    char keyValue;
    char alternateKeyValue;
} keyboard_S;

typedef struct
{    
    mouse_S simpleMouse;
    keyboard_S qwerty;
} laptop_S;

laptop_S test=
{

    .simpleMouse =
    {
        .leftButton = false,
        .rightButton = false,
        .middleButton = false,
        .mouseOn = false,
        .direction = MOUSE_NONE,
    },
    .qwerty =
    {
        .keyValue = '5',
        .alternateKeyValue = '%'
    },
};

int main()
{

    char c = tesla.qwerty.keyValue;
    char d = tesla.qwerty.alternateKeyValue;
    printf("KeyValue = %c\n", c);
    printf("alternateKeyValue = %c\n", d);
}

This works, but is there a way to access KeyValue and alternateKeyValue without using '.'?

Upvotes: 0

Views: 586

Answers (2)

Srikanth Gangula
Srikanth Gangula

Reputation: 11

More straightforward and simpler 3 Line code could be...

//Get the address of the tesla      
  char *addressoftesla  = (laptop_S*)(&tesla);

//structure of tesla = simpleMouse + qwerty + 2 byte paddings

/* Get the value at the starting address of qwerty i.e keyValue*/
  printf("keyValue of tesla keyboard is %c\n",*(addressoftesla+sizeof(mouse_S)));

/* Get the value at the starting address of qwerty i.e alternatekeyValue */
  printf("alternatekeyValue of tesla keyboard is %c\n",*(addressoftesla+sizeof(mouse_S)+1));

  /*
  * More info for further understanding: 
  * A simple check to see all the values in the each field of structure
  * tesla - you can also use sizeof to get the each structure and entire 
  * structure byte sizes and the same can be done using offsetof as in 
  * other solution
  */
  for(int i = 0; i< 12; i++)
  {
      printf("value at tesla[i] is %d \n",*(addressoftesla+i));
  }

Upvotes: 1

Bodo Thiesen
Bodo Thiesen

Reputation: 2514

Probably they want you to use something like this:

union {
    mouse_S    mouse;
    keyboard_S keyboard;
    laptop_S   laptop;
} * oh; // oh = offset helper
size_t offset_of_mouse_leftButton = (char*)&oh->mouse->leftButton - (char*)&oh->mouse; // this should be 0
size_t offset_of_mouse_rightButton = (char*)&oh->mouse->rightButton - (char*)&oh->mouse; // but this one can be anything
size_t offset_of_mouse_middleButton = (char*)&oh->mouse->middleButton - (char*)&oh->mouse; // this too
// ...
size_t offset_of_keyboard_alternateKeyValue = (char*)&oh->keyboard->alternateKeyValue - (char*)&oh->keyboard;
// ...

and then with a void * to keyboard_S:

int get_keyValue(void * _keyboard) {
    // usual way:
    // keyboard_S * keyboard = _keyboard;
    // return keyboard->keyValue;
    // requested way:
    return *(CHAR*)((char*)_keyboard + offset_of_keyboard_keyValue);
}

The type CHAR should be written in lowercase and is the type of the element keyValue. The other char must be char for every type, whatever it is. Same for the chars above in the offset_of_ variable definitions.

So, I guess, the rest is your homework.

Upvotes: 2

Related Questions