Search code examples
arrayscbyteendianness

Algorithmically finding the N-th byte of an integer in C


It is possible to find the value stored at an individual byte of memory of an int by creating a pointer of a byte type, such as char, and initializing to the address of the int. The code should look something like this:

#include <stdio.h>
#include <stdlib.h>

typedef char BYTE;

int main() {
    // Create an array of integers
    int num = 2147483647;
    BYTE *b = &num;
    
    // Loop over bytes
    for (int i = 0; i < sizeof(int); i++)
    {
        // Print value of i-th byte
        printf("%i\n", b[i]);
    }

    return 0;
}

While this works for finding the value of a byte within a 4-byte integer, I am looking for a way to find the same value only by utilizing an algorithm. My understanding is that the code above cannot be used for memory-safe languages, such as C#.

The prototype for a function that uses this algorithm might look something like this (assuming we have a type defined that is exactly one byte long):

// n is the integer from which we are getting the byte, index is the position of that byte
BYTE get_byte_from_int(int n, int index);

I assume that this algorithm would require a bit of division and modulus, but I'm struggling a lot with actually figuring out what to do.


Solution

  • you can use memcpy, unions or pointer punning if you want n'th byte from the binary representation of an integer.

    typedef unsigned char BYTE;
    
    BYTE get_byte_from_int(int n, int index)
    {
        union
        {
            int i;
            BYTE b[sizeof(int)];
        }ui = {.i = n};
    
        return ui.b[index];
    }
    
    BYTE get_byte_from_int(int n, int index)
    {
        unsigned char *pb = (unsigned char *)&n;
        return pb[index];
    }
    
    BYTE get_byte_from_int(int n, int index)
    {
        unsigned char pb[sizeof(n)];
    
        memcpy(pb, &n, sizeof(pb));
        return pb[index];
    }
    

    If you want n'th "arithmetic" byte use bit shift operations:

    BYTE get_byte_from_int(int n, int index)
    {
        return (((unsigned)n) >> (index * 8)) & 0xff;
    }