Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in
Follow pointers by hand, predict sizeof values, find classic bugs, then write code with addresses - minmax, strings, matrices. Chapter 2.
Unless stated otherwise, we assume a 64-bit PC running Linux: an int is 4 bytes, a pointer 8. Programs are compiled with gcc -std=c11 -Wall -Wextra -Werror.
Exercise · Follow the arrows
What does this program print? Draw the variables and the pointers after each line.
#include <stdio.h>
int main(void )
{
int a = 1 , b = 2 ;
int *p = &a, *q = &b;
*p = *q + 1 ;
p = q;
*p = 10 ;
*q = *q + a;
printf("a = %d, b = %d, *p = %d\n" , a, b, *p);
return 0 ;
}
Exercise · How many bytes?
What does this program print?
#include <stdio.h>
#include <string.h>
int main(void )
{
char s[] = "abc" ;
char *p = s;
int t[5 ];
char m[10 ] = "abc" ;
printf("%zu %zu %zu %zu %zu %zu %zu\n" , sizeof s, sizeof p, strlen(s),
sizeof t, sizeof t / sizeof t[0 ], sizeof m, strlen(m));
return 0 ;
}
We then add this function, called with f(t):
void f(int u[])
{
printf("%zu\n" , sizeof u / sizeof u[0 ]);
}
What would it print? Why does gcc -Wall -Werror refuse to compile it?
Exercise · Three bugs
Each of these programs is wrong. Say why, what gcc -Wall -Wextra says about it, and fix it.
First program:
#include <stdio.h>
int main(void )
{
int n;
if (scanf("%d" , n) != 1 )
return 1 ;
printf("%d\n" , n);
return 0 ;
}
Second program:
int main(void )
{
int *p;
*p = 3 ;
return 0 ;
}
Third program:
#include <stdio.h>
int somme(int t[])
{
int s = 0 ;
for (size_t i = 0 ; i < sizeof t / sizeof t[0 ]; i++)
s += t[i];
return s;
}
int main(void )
{
int t[4 ] = {1 , 2 , 3 , 4 };
printf("%d\n" , somme(t));
return 0 ;
}
Exercise · Two results
A C function returns only one value. Write
void minmax(const int t[], size_t n, int *min, int *max);
which stores in *min and *max the smallest and the largest element of the array t of n elements (n ≥ 1). Call it from main on {3, -1, 4, 1, -5, 9, 2, 6}.
Exercise · Strings without indices
Write, without using square brackets (only pointers, * and ++):
A function size_t longueur(const char *s), which returns the number of characters in s. A function void inverser(char *s), which reverses s in place: "bonjour" becomes "ruojnob". Why does inverser("bonjour") compile, and what happens at run time? How should it be called correctly?
Exercise · Transpose
A matrix of h rows and w columns is stored row by row in a one-dimensional array: the cell (column x, row y) is a[x + y * w].
Write void transposer(const int a[], int b[], size_t w, size_t h), which stores in b the transpose of a (w rows, h columns). Why not write void transposer(int a[][w], …)? What would be possible if w were a constant?