# Lecture #3: Pointers

Reading: Holmes, Chapters 8 and 9
Handouts: Pointers, Confusion, and All That; num.c; prenv.c
Homework: Adssignment #2, due Thursday, October 16, at 6PM
1. Greetings and felicitations
2. Review precedence table quickly
1. draw this, show simple example: for(i = 0, p = x; *p; i++, p++);
2. * operator, & operator
3. pointer arithmetic; why p - x is only legal operation; discuss p - 1, p + 1
4. Pointers and Arrays
1. rework above example as arrays
2. describe: pointer constant (array name), pointer variable
3. difference between int *x and int x
4. multiple dimensions: p = &a with int a
5. Multiply indirect pointers
1. show array of pointers
2. walk through (and draw) pointer confusion
6. Strings
1. NUL byte
2. show strcat, strcpy (do shortest versions of this), index
3. do sprintf(buf, "%s: check out line %d", filename, lineno);
7. Command-line interface as example of pointer args
1. argv, argc; show num x y z
2. envp; show printenv PATH
8. Arrays vs. Pointers again
1. allocation of arrays
2. malloc, free for pointers
3. realloc: warn about p = realloc(p, 10000)

# Pointers, Confusion, and All That

This very short, very confusing program shows the type of code that programmers wh o become addicted to pointers in C can write. It also is an excellent exercise in using pointers; if you can read this and figure out what it prints, you will be able to read and understand (almost) any use of C pointers! This exercise is from Alan Feuer's marvelous book The C Puzzle Book.

```char *c[] = {
"ENTER",
"NEW",
"POINT",
"FIRST"
};

char **cp[] = {  c+3, c+2, c+1, c };
char ***cpp = cp;

main()
{
printf("%s", **++cpp );
printf("%s ", *--*++cpp+3 );
printf("%s", *cpp[-2]+3 );
printf("%s\n", cpp[-1][-1]+1 );
}
```

# num.c

This program prints a file, putting the file name and line number in front of each line. For example, if the file hello contains:
```hi there
how are you?
```
the command
```num hello
```
prints
```hello,   1:hi there
hello,   2:how are you?
```
And now, the program!
```/*
* program to print a file with file name and line number
* prefixing each line
* invocation:
*	num			print stdin with line numbers
*	num arg1 ...		print contents of arg1 with line numbers
* exit code: number of files not opened
* author: Matt Bishop, bishop@cs.ucdavis.edu, 9/16/96
*/
#include <stdio.h>
#include <stdlib.h>

/*
* print the given file, with the file name and line
* number in front
* arguments:	fn	pointer to file name
*	     	fp	file pointer
*/
void cat(char *fn, FILE *fp)
{
register int c;			/* input character */
register int lno = 0;		/* line number */
register int nlstate = 1;	/* 1 if last char a newline */

/*
*/
while((c = getc(fp)) != EOF){
/* was the previous char a newline */
if (nlstate){
/* one more line */
lno++;
/* print the line number and file name */
if (fn == NULL) printf("%4d: ", lno);
else		printf("%s,%4d: ", fn, lno);
/* we now clear the record of the newline */
nlstate = 0;
}
/* print the character */
putchar(c);
/* if it's a newline, set the flag */
if (c == '\n')
nlstate = 1;
}
}

/*
* the main routine
*/
int main(int argc, char *argv[])
{
register int nerr = 0;	/* nuber of files not opened */
register char **a;	/* used to walk argument list */
register FILE *fp;	/* pointer to file being processed */

/*
* no argument -- use stdin
*/
if (argc == 1){
cat(NULL, stdin);
return(EXIT_SUCCESS);
}

/*
* walk the arg list, doing each file
*/
for(a = &argv; *a != NULL; a++)
/* open the file */
if ((fp = fopen(*a, "r")) == NULL){
/* oops ... say what happened */
perror(*a);
nerr++;
}
else{
/* print the file */
cat(*a, fp);
}

/*
* status is the number of files not opened
*/
return(nerr);
}
```

# prenv.c

This program prints all environment variables that are exported to the subprocess. If no arguments are given, it prints all the environment variables and their values; if arguments ar givn, it prints the values of those environment variables.

```/*
* program to print environment variables
* invocation:
*	prenv		print argument list
*	prenv arg1 ...	print value of argument(s)
* author: Matt Bishop, bishop@cs.ucdavis.edu, 9/16/96
*/
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>

int main(int argc, char *argv[], char *envp[])
{
register int i;			/* counter in for loops */
register int narg;		/* number of current argument */
register int len;		/* length of current argument */
register int found;		/* 1 if env. variable found */
register int exstat = 0;	/* exit status code */

/*
* no arguments; just print the environment
* variables and their values
*/
if (argc == 1){
/* just loop and print */
for(i = 0; envp[i] != NULL; i++)
printf("%s\n", envp[i]);
/* all done! */
return(EXIT_SUCCESS);
}

/*
* arguments given; just print the values
* associated with these named variables
*/
for(narg = 1; argv[narg] != NULL; narg++){
/* just an optimization ... */
len = strlen(argv[narg]);
/* assume no such variable */
found = 0;
/*
* now look for the variable
*/
for(i = 0; envp[i] != NULL; i++)
/* see if this one is it*/
if (strncmp(envp[i], argv[narg], len) == 0){
/* name= means value follows = */
if (envp[i][len] == '='){
printf("%s\n", envp[i] + len + 1);
found++;
}
/* name means value is empty */
/* anything else, it doesn't match */
else if (!envp[i][len]){
putchar('\n');
found++;
}
}
/*
* did we find it?
*/
if (!found){
/* nope -- print error message */
fprintf(stderr, "%s: no such variable\n",
argv[narg]);
/* one more unknown environment variable */
exstat++;
}

}

/*
* return number of unknown environment variables
*/
return(exstat);
}

```

You can also see this document as a RTF document, a Postscript document, or a plain ASCII text document. Send email to cs40@csif.cs.ucdavis.edu.

Department of Computer Science
University of California at Davis
Davis, CA 95616-8562