Exercise 5-6. Rewrite appropriate programs from earlier chapters and exercises with pointers instead of array indexing. Good possibilities include
getline(Chapters 1 and 4),atoi,itoa, and their variants (Chapters 2, 3, 4),reverse(Chapter 3),strindexandgetop(Chapter 4).
This exercise is about translation: every array subscript a[i] can be written as *(a+i), and walking an array with an index can be replaced by advancing a pointer. The pointer versions are often more compact and are idiomatic C. Below are pointer rewrites of five key functions.
Solution
/* K&R Exercise 5-6 — pointer rewrites of earlier functions
* Compile: gcc -ansi -Wall ex5-6.c -o ex5-6 */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/* getline — pointer version (Ch 1) */
int my_getline(char *s, int lim)
{
char *p = s;
int c;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
*p++ = c;
if (c == '\n')
*p++ = c;
*p = '\0';
return p - s;
}
/* atoi — pointer version (Ch 2) */
int my_atoi(const char *s)
{
int n = 0, sign;
while (isspace(*s)) s++;
sign = (*s == '-') ? -1 : 1;
if (*s == '+' || *s == '-') s++;
while (isdigit(*s))
n = 10 * n + (*s++ - '0');
return sign * n;
}
/* itoa — pointer version (Ch 3) */
static void rev(char *s, char *e)
{
char tmp;
for (e--; s < e; s++, e--)
{ tmp = *s; *s = *e; *e = tmp; }
}
void my_itoa(int n, char *s)
{
char *p = s;
int neg = (n < 0);
if (neg) n = -n;
do { *p++ = (n % 10) + '0'; } while ((n /= 10) > 0);
if (neg) *p++ = '-';
*p = '\0';
rev(s, p);
}
/* reverse — pointer version (Ch 3) */
void my_reverse(char *s)
{
char *e = s;
char tmp;
while (*e) e++;
for (e--; s < e; s++, e--)
{ tmp = *s; *s = *e; *e = tmp; }
}
/* strindex — pointer version, returns rightmost match (Ch 4) */
int my_strindex(const char *s, const char *t)
{
const char *p, *q, *r;
int last = -1;
for (p = s; *p; p++) {
for (q = p, r = t; *r && *q == *r; q++, r++)
;
if (*r == '\0')
last = (int)(p - s);
}
return last;
}
int main(void)
{
char buf[50];
my_itoa(12345, buf); printf("itoa: %s\n", buf); /* 12345 */
my_itoa(-999, buf); printf("itoa: %s\n", buf); /* -999 */
printf("atoi: %d\n", my_atoi(" -42abc")); /* -42 */
char s[] = "hello";
my_reverse(s); printf("reverse: %s\n", s); /* olleh */
printf("strindex: %d\n", my_strindex("abcabc","bc")); /* 4 */
return 0;
}
Array vs Pointer at a Glance
| Pattern | Array version | Pointer version |
|---|---|---|
| Walk forward | while (s[i]) i++; |
while (*s) s++; |
| Copy loop | while ((s[i]=t[i])!='\0') i++; |
while ((*s++=*t++)); |
| Length | i - start |
p - s |
What This Exercise Teaches
- Array indexing is pointer arithmetic —
a[i]is defined as*(a+i); both compile to the same machine code - Pointer subtraction gives length —
p - sis the number of elements between two pointers into the same array; this is anint(orptrdiff_t) - Advancing the pointer vs advancing the index — the pointer version is often more concise but requires care: unlike an index variable, the pointer itself is modified and cannot be rewound without saving the original
Set Up Your C Environment
← Exercise 5-5 |
Chapter 5 Solutions |
Exercise 5-7 →
Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie