150 likes | 279 Views
Pointers are fun!. http://www.youtube.com/watch?v=6pmWojisM_E. 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 …a data type Ex: int is a datatype “pointer to int” is also a (separate) datatype
E N D
Pointers are fun! http://www.youtube.com/watch?v=6pmWojisM_E CS-1030 Dr. Mark L. Hornick
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 • …a data type • Ex: int is a datatype • “pointer to int” is also a (separate) datatype • 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 0x1234pValue++; // 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 intint anotherValue = 2; int* pValue = &aValue; // ptr to aValue// above line is same as:// int* pValue; // ptr, but not init’d// pValue = &aValue; // now init’dpValue = &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
More Confusing syntax int aValue = 1; // an intint anotherValue = 2; int* p1 = &aValue; // ptr to aValueint* p2 = &anotherValue;*p1 = *p2; // same as aValue=anotherValuep1 = 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, whereint* 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) memoryuint8_t* pValue; // 16-bit addr of 8-bit valuepValue = 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
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 theelement the pointer is declared to reference. CS-1030 Dr. Mark L. Hornick
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 • Above, value of px is placed in r24:r25 (low, high bytes) • Px’s value is the address of some 8-bit uint8_t value somewhere in memory • 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); px(high) px(low) . . . . . . . . . . . . x=3 CE-2810 Dr. Mark L. Hornick
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 = *px + *py; return sum; } CE-2810 Dr. Mark L. Hornick
The const specifier • Prevents objects passed by address from being changed within a function • Here’s the modified declaration of the method that passes by address: • void printValue(const int* pValue); • Usage: printName( &value ); CS-1030 Dr. Mark L. Hornick
Notation for const and pointers is tricky int x; const int* ptr1 = &x; // x is constant // Can’t use ptr1 to change x, but can change ptr1 to point to another object int* const ptr2 = &x; // ptr2 constant // Can’t change ptr2 to another object, but can change value of x const int* const ptr2 = &x; // Can’t do either CS-1030 Dr. Mark L. Hornick