pointers chapters 6+9 in abc. abp 12 int a = 1, b = 2, *p; & - reference operator (address) * -...
Post on 20-Dec-2015
215 views
TRANSCRIPT
a b p
1 2
int a = 1, b = 2, *p;
& - reference operator (address)
* - dereference operator (value)
p = &a; // *p is now 1
a b p
1 2
Pointers
Why are they important?
• Call by reference
• Efficient argument passing to functions
• Dynamic memory allocation
• Efficient memory manipulation
Call by reference#include <stdio.h>
void swap(int *p, int *q)
{
int tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
int main(void)
{
int i = 3, j = 5;
swap(&i, &j);
printf( “%d %d\n”, i, j );
return 0;
}
Define pointers as paramsDefine pointers as params
Use dereferenced valuesUse dereferenced values
Pass addresses as argumentsPass addresses as arguments
Arrays and Pointers
a[i] is equivalent to *(a + i)
p[i] is equivalent to *(p + i)
for ( p = a; p < &a[ N ]; ++p ) sum += *p;
is equivalent to:
for ( i = 0; i < N; ++i ) sum += a[i];
An array name is an address!
The main difference between the two: a pointer can be modified, an array cannot, it is a CONSTANT pointer!
Pointer Arithmetic and Element Size
double a[2], *p = NULL, *q = NULL;
p = a;
q = p +1;
printf(“%d\n”, q - p);
printf(“%d\n”, (int)q - (int)p);
points to the base of the arraypoints to the base of the array
equivalent to q = &a[ 1 ]equivalent to q = &a[ 1 ]
1 is printed1 is printed
sizeof(dobule)==8 is printedsizeof(dobule)==8 is printed
Passing an array to a function
double sum(double a[], int n)
{
int i = 0;
double sum = 0.0;
for ( i = 0; i < n; ++i )
sum += a[i];
return sum;
}
What will sum(a+3, 3) compute?
Base address is passed call by value.Base address is passed call by value.
Strings
char s[] = “abcde” sa b c d e \0
#include <string.h>
char *strcat(char *s1, const char *s2);
int strcmp(const char *s1, const char *s2);
char *strcpy(char *s1, const char *s2);
unsigned strlen(const char *s);
An implementation example
char *strcat( char *s1, const char *s2 )
{
register char *p = s1;
while ( *p )
++p;
while ( *p++ = *s2++ ) ;
return s1;
}
Dynamic memory allocation
• #include <stdlib.h>
• Functions work with void * - a generic pointer; all return NULL on failure
• size_t is typically unsigned int
void *calloc( size_t n, size_t el_size)
//all allocated bytes are initialized to zero
void *malloc( size_t size )
//no initialization
void free( void *ptr )
Lexicographical sort (lexi-sort.c)int main(void)
{
char *w[N];
char word[MAXWORD];
int n = 0, i = 0;
for ( i = 0; scanf("%s", word) == 1; ++i )
{
if ( i >= N ) {
printf( “Sorry, at most %d words can be sorted.”, N );
exit(1);
}
w[i] = calloc(strlen(word) + 1, sizeof(char));
assert(w[i]!=NULL);
strcpy(w[i], word);
}
an array of pointersan array of pointers
work spacework space
Check allocationCheck allocation
Lexicographical sort
n = i;
sort_words( w, n );
for ( i = 0; i < n; ++i )
printf( “%s\n”, w[i] );
return 0;
}
print the sorted wordsprint the sorted words
void sort_words( char *w[], int n )
{
int i = 0, j = 0;
for ( i = 0; i < n; ++i )
for ( j = i + 1; j < n; ++j )
if ( strcmp(w[i], w[j]) > 0 )
swap( &w[i], &w[j] );
}
void swap( char **p, char **q )
{
char *temp = NULL;
temp = *p;
*p = *q;
*q = temp;
}
Lexicographical sort
n elements to be sortedn elements to be sorted
Arguments to main() (echo.c)
#include <stdio.h>
void main(int argc, char *argv[])
{
int i = 0;
printf( “argc = %d\n”, argc );
for ( i = 0; i < argc; ++i )
printf( “argv[%d] = %s\n”, i, argv[i] );
}
Multidimensional Arrays
int a[5][2]={{1,2},{3,4},{5,6},{7,8},{9,10}};
a[i][j] is equivalent to *(&a[0][0]+2*i+j)
What is **(a+3) ?
What is *(a[2]+1) ?
Functions as argumentsdouble sum_square( double f(double), int m, int n )
{
int k = 0;
double sum = 0.0;
for ( k = m; k <= n; ++k )
sum += f(k) * f(k);
return sum;
}
double sum_square( double (*f)(double), int m, int n )
{
.....
Functions as arguments#include <stdio.h>
#include <math.h>
double f(double), sin(double), sum_square(double (*)(double), int, int);
int main(void)
{
printf( “%s%.7f\n%s%.7f\n”,
“ First computation: ”, sum_square(sin, 2, 13),
“Second computation: ”, sum_square(f, 1, 10000));
return 0;
}
double f(double x)
{
return 1.0 / x; First computation: 5.7577885
} Second computation: 1.6448341
The qsort function (int-qsort.c)
qsort's prototype in stdlib.h:
void qsort(void *array,
size_t n_elem,
size_t elem_size,
int compare(const void *, const void *));
compare(a,b) returns negative int if a<b
returns 0 if a=b
returns positive int if a>b
// qsort an array of ints
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define KEYSIZE 16
int compare_int(const void *p1, const void *p2);
void print_array(char *title, int *key, int n_elem);
int main(void)
{
int key[] = { 4, 3, 1, 67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1 };
print_array("before ", key, KEYSIZE);
qsort(key, KEYSIZE, sizeof(int), compare_int);
print_array("after ", key, KEYSIZE); return 0;
}
void print_array(char *title, int *key, int n_elem) {
int i;
printf("\n %s:\n",title); for (i = 0; i < n_elem; ++i)
printf("%4d", key[i]); putchar('\n');
}
// the compare function to be passed as a parameter to qosrt
int compare_int(const void *p1, const void *p2) {
const int *q1 = p1, *q2 = p2;
return ((*q1) - (*q2)); }
Linked lists typedef struct list { int data; struct list * next;} ll;
void insert( ll *p, int a ) { //assume p!=NULLstruct list *q = p->next;p->next = (ll *)malloc( sizeof( ll ) );assert(p->next != NULL);p->next->data = a;p->next->next = q;
}
data next
Linked lists
void remove( ll *p ) { //assume p,p->next != NULLll *q = p->next;p->next = q->next;free( q );
}
LINKED#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef char DATA;
struct linked_list
{
DATA d;
struct linked_list *next;
};
typedef struct linked_list ELEMENT;
typedef ELEMENT *LINK;
We will use chars in the exampleWe will use chars in the example
Iterative List Creation
LINK string_to_list( char s[] )
{
int i = 0;
LINK head = NULL, tail = NULL;
if ( s[0] != ‘\0’ )
{
head = ( ELEMENT* )malloc( sizeof( ELEMENT ) );
head→d = s[0];
tail = head;
String is not emptyString is not empty
for ( i=1; s[i] != ‘\0’; ++i )
{
tail→next = ( ELEMENT* )malloc( sizeof( ELEMENT ) );
tail = tail→next;
tail→d = s[i];
}
tail→next = NULL;
}
return head;
}
insert elements at the end of the listinsert elements at the end of the list
mark the end of the listmark the end of the list