[sdiy] Pointers in C

Neil Johnson neil.johnson97 at ntlworld.com
Sat Dec 31 14:50:08 CET 2011


Hi Paul,

>   or am I nuts?

Yes, definitely.  But that's nothing to do with pointers.

Think of a pointer as: "a thing which points to a thing".

Now, the type of thing it points to is specified in the pointer's  
type, so an "int *" points to an int, a "char *" points to a char, a  
"float *" points to a float.

Operations on pointers preserve the properties of the pointer type.   
So, for example, adding 1 to a pointer is a way of saying "point to  
the next thing".  On a simple processor this will result in the  
numerical value of the pointer being increased by the size of the  
thing being pointed to (e.g., 1 for a char, 4 for an int).

(Note: this is a simplification for this email... in general you  
cannot assume that pointers are nicely-behaved integers.  Some large  
IBM mainframes have 768-bit pointers that include all sorts of access  
permissions, etc.  The exception being two pointers into the same  
array where you are allowed to compute the difference between them).

So, a pointer points to a thing, and the compiler will manage the  
pointer arithmetic for you.

Now, accessing bytes when given a pointer to an int.  Tricky.

If you know the endianess of your processor then its a little easier  
since you can make some assumptions.  But that produces non-portable  
code, which may or may not be an issue for you.

For now lets assume a little endian processor.  So then we can  
reasonably say that a pointer points to the least-significant byte of  
a multibyte type.  In which case you can do something like Colin  
suggested, which would work just fine.

The better approach would be the the shift-and-mask suggested by  
Olivier.  And on an ARM this could well be faster too since the 4- 
byte int would be loaded in one memory operation, and shifting right  
is a single-cycle pass through the barrel-shifter.  Something like:

int i;
int *my_ptr;
unsigned long ul = *my_ptr;
for ( i = 0; i < sizeof(unsigned long); i++ )
{
    unsigned char uc = ul & 0xFF;
    do_something_with( uc );
    ul >>= 8;
}

Or if you just have the unsigned long itself then you don't need to  
mess with pointers, but still need to unpack it a byte at a time.

Cheers,
Neil
--
http://www.njohnson.co.uk







More information about the Synth-diy mailing list