Anda di halaman 1dari 15

Pointers are fun!

http://www.youtube.com/watch?v=6pmWojisM_E
CS-1030 Dr. Mark L. Hornick 1

Pointers are

used to store the address of an object

An address is legitimate data by itself in C Every memory location has an address


Ex: int is a datatype pointer to int is also a (separate) datatype

a data type

Since they hold memory addresses, all pointers are the same size in bytes (unlike the data they point to)

CS-1030 Dr. Mark L. Hornick

Pointer declaration confusion

Declaration of a pointer uses the * prefix

int *pValue; // pointer to an integer int* pValue; // another way of declaring the same

Be careful with multiple declarations on one line:


int *pValue1, *pValue2; int* pValue1, pValue2; // No!!!


int* pValue1; // OK int* pValue2; // OK

CS-1030 Dr. Mark L. Hornick

Pointers unary operators

New unary operators:

& prefix address of (can use on pointers or regular variables)


int aValue = 3; int *pValue = &aValue; // sets pValue to the addr of aValue

* prefix - dereference (can only use on pointers)


int someOtherValue; someOtherValue = *pValue; // sets someOtherValue = aValue

CS-1030 Dr. Mark L. Hornick

Pointers unary operators

New unary operators:

++ prefix or postfix increment the address stored in the pointer


int aValue = 3; int *pValue = &aValue; // addr might be 0x1234 pValue++; // new addr is 0x1236; why not 0x1235???? // what does (*pValue)++ do???

-- prefix or postfix decrement the address stored in the pointer

CS-1030 Dr. Mark L. Hornick

Confusing syntax explained


int aValue = 1; // an int int anotherValue = 2; int* pValue = &aValue; // ptr to aValue // above line is same as: // int* pValue; // ptr, but not initd // pValue = &aValue; // now initd pValue = &anotherValue // points to anotherValue // what does pValue = anotherValue mean??? // whatever pValue points to now equals aValue:
*pValue = aValue;// same as anotherValue=aValue;
A common C convention: pointer variable names are prefixed with p
CS-1030 Dr. Mark L. Hornick 6

More Confusing syntax


int aValue = 1; // an int int anotherValue = 2; int* p1 = &aValue; // ptr to aValue int* p2 = &anotherValue;

*p1 = *p2; // same as aValue=anotherValue


p1 = p2; // now both point to anotherValue

CS-1030 Dr. Mark L. Hornick

The NULL pointer


Pointers should only be made to point at valid addresses

The exception is the NULL pointer, where int* pValue = NULL; // points to address 0 // or int* pValue = 0;
This is a convention that allows you to check to see if a pointer is valid

CS-1030 Dr. Mark L. Hornick

Pointing a pointer at a valid address

Since a pointer holds an address, the pointer can be made to point anywhere in (data) memory

uint8_t* pValue; // 16-bit addr of 8-bit value pValue = 0x0038; // what is at 0x38???

Now explain what this does: *pValue = 0xFF;

CS-1030 Dr. Mark L. Hornick

Pointers and arrays

Say you define an array of characters:

char s[]=ABCD;

The string variable is actually a pointer to the beginning of the array, so we can write:

char* ps = s; // or ps = &s[0];

Dereferencing the pointer gives the value of the character at that address:

char c = *ps; // same as c = s[0];

Incrementing the pointer advances the pointer address to the next character in the array:

ps++; // same as ps = &s[1];

CS-1030 Dr. Mark L. Hornick

10

Pointer Arithmetic

Incrementing a character pointer advances the pointer address by one byte, to the next character in the array:

ps++; // value of ps increases by 1;

Say you define an array of longs:


long larray[]= {1L, 2L, 3L, 4L}; long* pl = larray;

Incrementing a long pointer advances the pointer address by four bytes, to the next long in the array:

pl++; // value of pl increases by 4; Pointer arithmetic is dependent on the size of the element the pointer is declared to reference.

CS-1030 Dr. Mark L. Hornick

11

Pointers as function arguments

Consider a function: int16_t add( uint8_t* px, uint16_t* py);


uint8_t* means pointer to unsigned 8-bit int uint16_t* means pointer to unsigned 16-bit int Since Atmega32 uses 2-byte addressing, all pointers are 2 byte variables

GNU GCC passes arguments left to right using registers r25 to r8

px(high) px(low)

Above, value of px is placed in r24:r25 (low, high bytes)

Pxs value is the address of some 8-bit uint8_t value somewhere in memory

... ... ... ... x=3

Value of py (2 bytes) is placed in r22:r23

Calling such a function: uint8_t x=3; uint16_t y=4; uint8_t* px = &x; uint16_t* py = &y; int16_t sum = add(&x, &y); sum = add(px, py);
CE-2810 Dr. Mark L. Hornick

12

Within the function, the arguments must be dereferenced to manipulate the values
Implementing such a function: uint16_t add(uint8_t* px,uint16_t* py ) { uint8_t tempx = *px; uint16_t tempy = *py; uint16_t sum = tempx + tempy; // or uint16_t sum return sum; } = *px + *py;

CE-2810 Dr. Mark L. Hornick

13

The const specifier

Prevents objects passed by address from being changed within a function


Heres the modified declaration of the method that passes by address:

void printValue(const int* pValue); Usage: printName( &value );

CS-1030 Dr. Mark L. Hornick

14

Notation for const and pointers is tricky


int x; const int* ptr1 = &x; // x is constant // Cant use ptr1 to change x, but can change ptr1 to point to another object int* const ptr2 = &x; // ptr2 constant // Cant change ptr2 to another object, but can change value of x const int* const ptr2 = &x; // Cant do either
CS-1030 Dr. Mark L. Hornick 15

Anda mungkin juga menyukai