Art Navsegda
Art Navsegda

Reputation: 45

Access c variable as an array

I've got moderately stuck, googling the right words can't got me to the right answer. Even worse, I've already done that but my own code example lost somewhere in the source code.

#include <stdio.h>

int main()
{
    short x = 0xABCD;
    char y[2] = { 0xAB, 0xCD };
    printf("%x %x\n", y[0], y[1]);
    printf("%x %x\n", (char *)&x[0], (char *)&x[1]);
}

Basically I need to access individual variable bytes via array by pointer arithmetic, without any calculations, just by type casting.

Upvotes: 1

Views: 112

Answers (3)

Alex Reynolds
Alex Reynolds

Reputation: 96967

Put parentheses around your cast:

printf("%x %x\n", ((char *)&x)[0], ((char *)&x)[1]);

Note that endian-ness may change your expected result.

In the future, compile with -Wall to see what the warnings or errors are.

Upvotes: 3

Sourav Ghosh
Sourav Ghosh

Reputation: 134346

If you're only bothered about getting the values, you can store the address of the source variable in a char * and increment and dereference the char pointer to print the values of each byte.

Quoting C11, chapter §6.3.2.3

[....] When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

Something like (consider pseudo-code, not tested)

#include  <stdio.h>

int main(void)
{
    int src = 0x12345678;
    char * t = &src;

    for (int i = 0; i < sizeof(src); i++)
        printf("%x\t", t[i]);

    return 0;
}

should do it.


That said, to elaborate on the accepted answer, the why part:

As per the operator precedence table, array indexing operator has higher precedence over the type-casting, so unless forced explicitly, in the expression

  (char *)&x[0]

the type of x is not changed as expected. So, to enforce the meaningful usage of the type-casting, we need to enclose it into extra par of parenthesis.

Upvotes: 1

It's somewhat supported in C99. By a process known as type punning via union.

union {
  short s;
  char c[2];
} pun;

pun.s = 0xABCD;
pun.c[0] // reinterprets the representation of pun.s as char[2].
         // And accesses the first byte.

Pointer casting (as long as it's to char*, to avoid strict aliasing violations) is also ok.

short x = 0xABCD;
char *c = (char*)&x;

Upvotes: 1

Related Questions