Lots of students were prevented from coming to class by
our snowstorm. I hope that these notes help you a little
bit. Also check with other students who did make it to
class and took notes.
Karen
Allowed Operations on Pointers
int *px, *py;
int x, y;
px = &x; /* get address */
py = &y;
px = py; /* assignment */
/* both lhs and rhs are same type */
px = NULL; /* assignment to NULL */
if ( px == NULL) /* comparison */
printf("pointer is NULL\n");
NOT Allowed on Pointers
int *px, *py, *pz;
px = 12; /* assignment to non-NULL literal */
pz = px + py; /* add or subtract of */
/* two pointer values */
px = py * 2; /* multiply or divide of */
/* pointer value(s) */
Draw a Diagram:
int x, y, z; int *px, *py, *pz; px = &x; py = &y; pz = &z; *px = 24; py = px; z = 25; *py = x - z;
(Karen's start to a diagram)
--- ---
x | | | | px
--- ---
--- ---
y | | | | py
--- ---
--- ---
z | | | | pz
--- ---
Arrays
.
| . |
|--------|
/ | | base
/ |--------|
| | | base + (1 * size)
| |--------|
array | | | base + (2 * size)
(one | |--------|
element | | | base + (3 * size)
per | |--------|
box) | . |
.
.
0 1 2 3 4 (index)
---------------------
| | | | | |
| | | | | |
---------------------
How this array is filled in in later class examples.
0 1 2 3 4 (index)
---------------------
| 1 | 2 | 3 | 4 | 5 |
---------------------
Declare:
int a[5];
Use:
a[0] = 1; a[1] = 2;
As allocated within memory:
(one integer fits into a box)
.
| . |
|--------|
/ | | a
/ |--------|
| | |
| |--------|
| | |
| |--------|
| | |
\ |--------|
\ | |
|--------|
| . |
.
Again, what memory (this array) looks like when filled in.
.
| . |
|--------|
/ | 1 | a
/ |--------|
| | 2 |
| |--------|
| | 3 |
| |--------|
| | 4 |
\ |--------|
\ | 5 |
|--------|
| . |
.
C uses pointer notation with arrays:
a[i] is equivalent to *(a + i)
and
&(a + i) is equivalent to a + i
int a[5];
int *ap;
ap = a;
ap++; /* ap has the address of a[1] */
*ap = 2;
ap++; /* OK. */
a++; /* BAD! NOT ALLOWED! */
/* a is a label, not a pointer! */
#include <stdio.h>
# define MAXARRAYSIZE 5
main()
{
int intarray[MAXARRAYSIZE];
int *iap; /* a pointer to an int */
int k; /* loop induction variable */
/* one implementation */
/* notice the use of pointers and pointer arithmetic! */
iap = intarray;
for ( k = 0; k < MAXARRAYSIZE; k++) {
*iap = k + 1;
iap++;
}
iap = intarray;
for ( k = 0; k < MAXARRAYSIZE; k++) {
printf("%d\n", *iap);
iap++;
}
/* another implementation */
for ( k = 0; k < MAXARRAYSIZE; k++) {
intarray[k] = k + 1;
}
for ( k = 0; k < MAXARRAYSIZE; k++) {
printf("%d\n", intarray[k]);
}
}
From the lecture notes:
int a = 3;
int b = 8;
int c = 0;
int *cp;
c = a + b;
cp = &c;
cp++; /* allowed, but probably
not reasonable */
Contrast this code with:
iap = intarray;
for ( k = 0; k < MAX; k++) {
.
.
iap++; /* correct and reasonable? */
}
C does not do any sort of
bounds checking!
int ar[12]; ar[12] = -1; /* No compiler error! */ ar[300] = ar[300] + 3; /* OK! */
This leads to the question:
Why no bounds checking?
#include <stdio.h>
void increment (int a);
main() {
int x;
x = 1;
printf("before call, x = %d\n", x);
increment( x);
printf("after call, x = %d\n", x);
}
void increment(int a) {
a++;
}
Some explanation of this slide:
This program prints
before call, x = 1 before call, x = 1
The reason for this output is that C implements only call by value parameter passing.
If we wanted the increment function to increment x,
then the main program must pass a pointer to x,
rather than a copy of x.
Here's the code to do that, with underlines showing items
that changed in the code:
#include <stdio.h>
void increment (int *a);
main() {
int x;
x = 1;
printf("before call, x = %d\n", x);
increment(& x);
printf("after call, x = %d\n", x);
}
void increment(int *a) {
(*a)++;
}
int main() {
x = a();
}
int a (){
y = b();
}
int b (){
z = c();
}
int c (){
}
main calls a
a calls b
b calls c
c returns to b
b returns to a
a returns to main
The call tree for this code:
main
|
\ /
a
|
\ /
b
|
\ /
c