[ANU] [DCS] [COMP2100/2500] [Description] [Schedule] [Lectures] [Labs] [Homework] [Assignments] [COMP2500] [Assessment] [PSP] [Java] [Reading] [Help]
COMP2100/2500
Lecture 23: The C Programming Language IIISummary
Advanced C concepts you will need in order to write Java wrappers for C code, particularly arrays, pointers and memory allocation.
Outline
Pointers
Arrays and pointers
Dynamic memory allocation
Pointers
Your program and data are represented as arrays of bytes in memory. A pointer (or address) is a location in memory.
If `v' is a variable, then `&v' is the address where `v' is stored.
If `p' is pointer then `*p' is the value stored at location `p'. This is called dereferencing p.
*(&v)==v and &(*p)==p
Pointers are typed:
int *ip; /* (*ip) is an int, * therefore ip is a pointer to an int */ char *cp; /* (*cp) is a char, therefore ... */Pointers in C are like references in Java (but not quite the same).
Richard's tip: read the definition backwards, saying "pointer to" for each asterisk. For example, ip is a pointer to int.
A First Pointer Example
int x=1, y=2; int *ip; ip = &x; y = *ip; /* y gets 1 */ *ip = 0; /* x gets 0 */
Pointers and Function Arguments
Function arguments in C are always passed by value. Java is the same. This means that the function gets a copy of the argument's value, but does not have access to the argument itself. (Contrast with call-by-reference in Pascal for example.)
This means that a function cannot directly modify a variable from the function that called it.
Example: A function to swap the values of two variables.
First attempt:
void swap(int x, int y) { int tmp = x; x = y; y = tmp; } void main(void) { int a=1, b=2; swap(a,b); printf("a=%d, b=%d\n", a, b); }This doesn't work because the function only swaps its copies of the values of a and b.
Second attempt:
void swap(int *xp, int *yp) { int tmp = *xp; *xp = *yp; *yp = tmp; } void main(void) { int a=1, b=2; swap(&a,&b); printf("a=%d, b=%d\n", a, b); }
Address Arithmetic
If p is a pointer to a value of type t, then p + k is a pointer to the k'th value of type t after p.
Here is a program to calculate the number of bytes used to store an integer.
#include <stdio.h> int main(void) { int *ip; printf("%d\n", (int)(ip + 1) - (int)ip); return 0; }On my x86, this program prints 4, so I have 32 bit integers.
What does this do?
#include <stdio.h> int main(void) { int i=0, j=1, k=2; *((&k)+2) = 9; printf("i=%d, j=%d, k=%d\n", i, j, k); return 0; }
Arrays and Pointers
Pointers can be used as an alternative to indexing arrays (and many C programmers think that this is a cute thing to do).
int a[10]; int *ap; ap = a; /* `a' means the same as `&a[0]' */
Kernighan and Ritchie note that using pointers is faster but harder to understand. They therefore recommend pointers. In the 20 years since then, priorities have changed; use indexes!
Mixing Pointers with Indexes
First version, treating the strings as arrays of characters.
void strcpy1(char s[], char t[]) { int i = 0; while ((s[i] = t[i]) != '\0') { i++; } }Second version, using pointers.
void strcpy2(char *s, char *t) { while ((*s++ = *t++) != '\0') {} }Third version, recursive, using both...
void strcpy3(char s[], char t[]) { if ((s[0] = t[0]) != '\0') { strcpy3(&(s[1]),&(t[1])); } }
Pointers are not the same as arrays
char string1[] = "This is the first string."; char *string2 = "This is the second string.";
You cannot alter the value of string1; it is not a variable.
But you can alter the content of the string "This is the first string.".
You can alter the value of string2; it's just a variable.
But you cannot alter the content of the string "This is the second string.". This is probably stored in the read-only, code, segment.
Dynamic Memory
#include <stdlib.h> void *malloc(size_t size) /* Allocates size bytes of memory and returns a * pointer to it, or returns NULL if insufficient * memory available. */ void *calloc(size_t n, size_t size) /* Allocates enough memory for an array of n objects of * size size, initialises it to 0s, and returns a pointer * to it. Returns NULL if there is insufficient memory. */ void free(void *p) /* Deallocate the memory block pointed to by p. */Never:
Reference memory that has been freed, or
free a pointer not allocated with malloc or calloc.
[ANU] [DCS] [COMP2100/2500] [Description] [Schedule] [Lectures] [Labs] [Homework] [Assignments] [COMP2500] [Assessment] [PSP] [Java] [Reading] [Help]
Copyright © 2005, Jim Grundy & Ian Barnes & Richard Walker, The Australian National University
Version 2005.1, Tuesday, 26 April 2005, 14:58:47 +1000
Feedback & Queries to
comp2100@cs.anu.edu.au