260 likes | 371 Views
Engineering Problem Solving with C Fundamental Concepts. Chapter 6 Pointers. Addresses and Pointers. Address Operator. A variable can be referenced using the address operator & example: scanf(“%f”, &x); This statement specifies that the value read is to be stored at the address of x.
E N D
Engineering Problem Solving with C Fundamental Concepts Chapter 6 Pointers Etter/Ingber
Addresses and Pointers Etter/Ingber
Address Operator • A variable can be referenced using the address operator & example: scanf(“%f”, &x); • This statement specifies that the value read is to be stored at the address of x Etter/Ingber
Pointer Assignment • A pointer is a variable that holds the address of a memory location • If a variable p holds the address of another variable q, then p is said to point to q • If q is a variable at location 100 in memory, then p would have the value 100 (q’s address) Etter/Ingber
How to declare a pointer variable • pointer variables are declared using an asterisk ( * ) The asterisk is called the indirection operator or the de-referencing operator). example: • int a, b, *ptr; ptr is a pointer to an integer • when a pointer is defined, the type of variable to which it will point must be specified. (i.e. a pointer defined to point to an integer cannot also point to a floating point variable.) Etter/Ingber
Example int *iPtr; double* dPtr; • the variable iPtr is declared to point to an int • the variable dPtr is declared to point to a double • neither variable has not been initialized in the above example • declaring a pointer creates a variable capable of holding an address Etter/Ingber
int a, *iPtr;char* s;double *dPtr; Example a ? iPtr s dPtr ? - ? ? Etter/Ingber
More about declaring pointers • When using the form int* p, q; the * operator does not distribute. • In the above example p is declared to be a pointer to int. p is declared to be an int. Etter/Ingber
Assigning values to a pointer • the assignment operator (=) is defined for pointers • the right operand can be any expression that evaluates to the same type as the left • the operator & in front of an ordinary variable produces the address of that variable. The & operator is called to addressof operator Etter/Ingber
Example • example - int I=6, j; int *iPtr; iPtr = &I; j = *iPtr; I iPtr j 6 6 Etter/Ingber
Practice! • Give a memory snapshot after each set of assignment statements • int a=1, b=2, *ptr; • ptr = &b; • int a=1, b=2, *ptr=&b; • a = *ptr; Etter/Ingber
NULL pointer • A pointer can be assigned or compared to the integer zero, or, equivalently, to the symbolic constant NULL, which is defined in <stdio.h>. • A pointer variable whose value is NULL is not pointing to anything that can be accessed Etter/Ingber
Example- int *iPtr=0;char *s=0;double *dPtr=NULL; iPtr s dPtr Etter/Ingber
Pointer Assignments • A pointer can point to only one location at a time, but several pointers can point to the same location. • Example • /* Declare and initialize variables. */ • int x=-5, y = 8, *ptr1, *ptr2; • /* Assign both pointers to point to x. */ • ptr1 = &x; • ptr2 = ptr1; • The memory snapshot after these statements are executed is • ptr1 ptr2 • x y -5 8 Etter/Ingber
Pointer Arithmetic • Four arithmetic operations are supported • +, -, ++, -- • only integers may be used in these operations • Arithmetic is performed relative to the variable type being pointed to Example: p++; • if p is defined as int *p, p will be incremented by 4 (system dependent) • if p is defined as double *p, p will be incremented by 8(system dependent • when applied to pointers, ++ means increment pointer to point to next value in memory Etter/Ingber
Comparing Pointers • You may compare pointers using relational operators • Common comparisons are: • check for null pointer (p == NULL) • check if two pointers are pointing to the same object • (p == q) Is this equivalent to • (*p == *q) • compare two pointers that are pointing to a common object such as an array. Etter/Ingber
Pointers and Arrays • The name of an array is the address of the first elements (i.e. a pointer to the first element) • The array name is a constant that always points to the first element of the array and its value can not be changed. • Array names and pointers may often be used interchangeably. Example int num[4] = {1,2,3,4}, *p; p = num; /* above assignment is the same as p = &num[0]; */ printf(“%i”, *p); p++; printf(“%i”, *p); Etter/Ingber
More Pointers and Arrays • You can also index a pointer using array notation Example: char string[] = “This is a string”; char *str; int i; str = string; for(i =0; str[i]; i++) //look for null printf(“%c”, str[i]); Etter/Ingber
Two-Dimensional Arrays • A two-dimensional array is stored in sequential memory locations, in row order. • Array definition: int s[2][3] = {{2,4,6}, {1,5,3}}, *sptr=&s; • Memory allocation: • s[0][0] 2 • s[0][1] 4 • s[0][2] 6 • s[1][0] 1 • s[1][1] 5 • s[1][2] 3 • A pointer reference to s[0][1] would be *(sptr+1) • A pointer reference to s[1][1] would be *(sptr+4) • row offset * number of columns + column offset Etter/Ingber
Pointers in Function References • In C, function references are call-by-value except when an array name is is used as an argument. • An array name is the address of the first element • Values in an array can be modified by statements within a function • To modify a function argument, a pointer to the argument must be passed • The actual parameter that corresponds to a pointer argument must be an address or pointer. Etter/Ingber
switch Example void switch2(int *a, int *b) { /* Declare Variables. */ int temp; /* Switch values pointed to by a and b. */ temp = *a; *a=*b; *b=temp; /* Void return. */ return; } Etter/Ingber
Dynamic Memory Allocation • Dynamically allocated memory is determined at runtime • A program may create as many or as few variables as required, offering greater flexibility • Dynamic allocation is often used to support data structures such as stacks, queues, linked lists and binary trees. • Dynamic memory is finite • Dynamically allocated memory may be freed during execution Etter/Ingber
Dynamic Memory Allocation • Memory is allocated using the: • malloc function (memory allocation) • calloc function (cleared memory allocation) • Memory is released using the: • free function • The size of memory requested by malloc or calloc can be changed using the: • realloc function Etter/Ingber
malloc and calloc • Both functions return a pointer to the newly allocated memory • If memory can not be allocated, the value returned will be a NULL value • The pointer returned by these functions is declared to be a void pointer • A cast operator should be used with the returned pointer value to coerce it to the proper pointer type Etter/Ingber
Example of malloc and calloc int npts = 500; double *x; int *p; /* Allocate memory for 500 doubles. */ x = (double *)malloc(npts*sizeof(double)); /* Allocate memory for 500 integers. */ p = (int *)calloc(npts*sizeof(int)); Etter/Ingber
Common Pointer Problems • Using un-initialized pointers int *iPtr; *iPtr = 100; iPtr has not been initialized. The value 100 will be assigned to some memory location, resulting in various types of errors. • Failing to reset a pointer after changing it’s value • Incorrect/unintended syntax Etter/Ingber