Pointer definitions, usage, operations, arrays of pointers, function pointers Referencing addresses,...
Preview:
Citation preview
- Slide 1
- Pointer definitions, usage, operations, arrays of pointers,
function pointers Referencing addresses, Pointers
- Slide 2
- The Pointer Concept and Usage in C Concept of Pointer as memory
address Pointer definitions Usage of pointers Operations on
pointers Function arguments: Call by Value/Reference Arrays of
pointers and Pointer types of Functions The const qualifier
Pointers to Functions
- Slide 3
- Concept of Pointer as memory address All programs exist in RAM
when executing Data and Code Variables and data structures (eg.
arrays) are allocated memory locations (addresses) In static
blocks, in stack frames, on the heap It is often useful to exploit
knowledge of data structures along with location, or address, data
It is the ability to define a variable that stores address values,
coupled with the ability to indirectly access meaningful data
values, that makes pointers useful.
- Slide 4
- Concept of Pointer as memory address For program codes produced
by a compiler, RAM is partitioned into blocks of memory according
to what kind of data is placed in the blocks Executable
instructions (code) Data Stacks Heaps Buffers For programmer
defined variables, names are used int intVarname = 64 ; float
fltVarName = 3.14159 ; Although we usually think of the value
stored in a variable, the variable name actually refers to a RAM
address (at which the value is stored) However, the names of scalar
variables do not correspond directly to their address location
values intVarname does not have a value ! CODE DATA BUFFERS STACKS
HEAP Code Block Address Data Block Address Heap Block Address Stack
Block Address Buffer Block Address intVarname fltVarname 64
3.14159
- Slide 5
- Pointer definitions C defines two pointer related operators * -
dereferencing (asterisk) & - address_of (ampersand) Examples:
// Variable name for an integer storage with value 5 int Varname =
5 ; /* Variable name for a pointer-to-integer storage with value
set to the RAM address of Varname */ int * ptrVarname =
&Varname ; The strongly typed nature of the C language dictates
that all pointers must be type-specific. Each pointer variable is
said to point to a RAM address where it is expected that data of a
compatible type is stored. Any type incompatibility will be
reported as a compiler error.
- Slide 6
- Usage of pointers Declarations int N, *ptrN ; // N is an int
variable, ptrN is pointer double * X, * Y ; // Must always use *
for each pointer Assigning values ptrN = &N ; // Use the
address-of operator to get the RAM address X = Y ; // Can assign
type compatible pointers *X = 24.53 ; /* Use dereferencing to
assign compatible values that will be stored at the RAM location X
is pointing to */ *Y = *X ; /* Copy the value stored where X is
pointing to where Y is pointing */ WARNING! Be careful to separate
the notion of data value from memory address Variables that hold
meaningful data provide direct access to RAM Pointers that hold
address data provide indirect access to RAM when dereferencing them
to get at meaningful data
- Slide 7
- Usage of pointers There is a special constant that deserves
emphasis NULL If a pointer variable is not assigned a value then it
cannot referenced. It is useful to have a value that can be
referenced, but which indicates no particular value of the address
int * ptr = NULL ; This provides advantages in programming logic
because one can test the value of a pointer if ( ptr != NULL ) { /*
perform logic */ } We will see much more use of NULL pointers in
future discussion of dynamic linked lists and other advanced data
structures
- Slide 8
- Operations on pointers The following operations are meaningful
for pointers and define pointer arithmetic Assume the declarations:
int aN [100] ; char aC [256] ; double aD [ 1000 ] ; int * pN ; char
* pC ; double * pD ; The following are valid statements: pN = aN ;
pC = aC ; pD = aD ; // Array names are pointers !! pN = &aN[0]
; pC = &aC[0] ; pD = &aD[0] ; // Equivalent to above pN =
pN + 1 ; // Points to aN[1] pN++ ; ++pN ; // . and then to aN[2],
then aN[3] pN -= 3 ; // . and now back to aN[0] Note above that we
have used +, -=, and ++ All arithmetic operations on pointers must
involve integer addition or subtraction only !
- Slide 9
- Operations on pointers Pointers are often used with arrays.
Assume the following: float A[1000], * ptrA = &A[0], * ptrB =
&A[49] ; Consider the following equivalent statements A[5] =
6.73 ; ptrA[5] = 6.73 ; *(ptrA+5) = 6.73 ; Now consider a problem.
Using pointer arithmetic only, determine the array subscript
corresponding to the position of the pointer relative to the
beginning of the array: Assume: int Subscript ; Answer: Subscript =
( ptrB ptrA ) / sizeof( float ) ; // the value above is 49 Note
that pointers can be subtracted from each other, but not added! If
A, B, C and D are compatible pointers, then consider the
expressions: A B OKA + B ERR A B + COKA + B CERR A B + C D OKA + (B
- C) OK (A B) + (C D) OK A B D + C ERR
- Slide 10
- Arrays of pointers Problem: Sort a 2D array in ascending order
on first column: double X[1000][50000] ; Note that the size of the
rows is immense so exchanging rows will take a lot of processing
time Answer: Use an array of pointers: double * pX[1000], * tptr ;
Initialize each element to point to the beginning of each row for(
k=0; k
- The const qualifier When both the pointer, and the data to
which it points, are intended to be modified non-const pointer to
non-const data Example: Assume: int N = 5, A[5] = {1,2,3,4,5} ;
Function: void Add1 ( int * B, int n ) { for( ; n>0 ; n--, B++ )
(*B)++ ; return ; } Note that both the pointer B, and the array
values (in A) are modified during the call: Add1( A, N ) ;
- Slide 16
- The const qualifier When the pointer to data is intended to be
modified, but the data to which it points must not be modified
non-const pointer to const data Example Assume: int N; const char
A[5] = {M,e,s,s,a,g,e,\0} ; Function: int StrLen ( const char * S )
{ int n = 0 ; for( ; *S != \0 ; S++ ) n++ ; return n ; } Note that
the pointer S is modified, but the values in the string A are not
modified in the call: N = StrLen( A ) ; Any attempt to modify data
in A results in a compiler error.
- Slide 17
- The const qualifier When the pointer to data must not be
modified, but the data to which it points may be modified const
pointer to non-const data Example Assume: float Pi = 3.14159, *
const ptrPi = &Pi ; Function: void ChangePi ( float * const P )
{ const float Q = 3.14 ; *P = 3.1415 ; P = &Q ; // Compiler
error ! return ; } Note that the value of Pi may change, but the
pointer P may not be modified to point at Q in the call: ChangePi(
ptrPi ) ; Also note that all array names represent const
pointers.
- Slide 18
- The const qualifier When neither the pointer to data, or the
data to which it points, may be modified const pointer to const
data This technique is used to promote maximum protection over data
and references to data Example: int main ( ) { int N = 3, * ptrN =
&N ; const int X = 5, * const ptrX = &X ; *ptrX = 3 ; //
Compiler error ptrX = &N ; // Compiler error ptrX = ptrN ; //
Compiler error } Always think about data protection when using
const.
- Slide 19
- Pointers to Functions Since function codes and data occupy
memory during program execution, it makes sense that we could refer
to the locations of the code, or data. When referring to data we
may use and possibly modify the data When referring to code,
however, one must never modify the code data (unpredictable side
effects) This leads to the notion of a pointer to a function
Example prototypes: void Bubble( int A[ ], const int N, int
(*compare)( int x, int y ) ) ; or void Bubble( int [ ], const int,
int (*)( int, int ) ) ;
- Slide 20
- Pointers to Functions Example function definitions: void
Bubble( int A[ ], const int N, int (*compare)( int x, int y ) ) {
int p, q ; for( p=1 ; p