The C Language
Prof. Stephen A. Edwards
Copyright © 2001 Stephen A. Edwards All rights reserved
Copyright © 2001 Stephen A. Edwards All rights reserved
The C Language
Copyright © 2001 Stephen A. Edwards All rights reserved
C History
Copyright © 2001 Stephen A. Edwards All rights reserved
BCPL
Copyright © 2001 Stephen A. Edwards All rights reserved
C History
Copyright © 2001 Stephen A. Edwards All rights reserved
C History
Copyright © 2001 Stephen A. Edwards All rights reserved
Hello World in C
#include <stdio.h>
void main()
{
printf(“Hello, world!\n”);
}
Preprocessor used to share information among source files
+ Cheaply implemented
+ Very flexible
Copyright © 2001 Stephen A. Edwards All rights reserved
Hello World in C
#include <stdio.h>
void main()
{
printf(“Hello, world!\n”);
}
Program mostly a collection of functions
“main” function special: the entry point
“void” qualifier indicates function does not return anything
I/O performed by a library function: not included in the language
Copyright © 2001 Stephen A. Edwards All rights reserved
Euclid’s algorithm in C
int gcd(int m, int n)
{
int r;
while ( (r = m % n) != 0) {
m = n;
n = r;
}
return n;
}
“New Style” function declaration lists number and type of arguments
Originally only listed return type. Generated code did not care how many arguments were actually passed.
Arguments are call-by-value
Copyright © 2001 Stephen A. Edwards All rights reserved
Euclid’s algorithm in C
int gcd(int m, int n)
{
int r;
while ( (r = m % n) != 0) {
m = n;
n = r;
}
return n;
}
Automatic variable
Storage allocated on stack when function entered, released when it returns.
All parameters, automatic variables accessed w.r.t. frame pointer.
Extra storage needed while evaluating large expressions also placed on the stack
n
m
ret. addr.
r
Frame pointer
Stack pointer
Excess arguments simply ignored
Copyright © 2001 Stephen A. Edwards All rights reserved
Euclid’s algorithm in C
int gcd(int m, int n)
{
int r;
while ( (r = m % n) != 0) {
m = n;
n = r;
}
return n;
}
Expression: C’s basic type of statement.
Arithmetic and logical
Assignment (=) returns a value, so can be used in expressions
% is remainder
!= is not equal
Copyright © 2001 Stephen A. Edwards All rights reserved
Euclid’s algorithm in C
int gcd(int m, int n)
{
int r;
while ( (r = m % n) != 0) {
m = n;
n = r;
}
return n;
}
High-level control-flow statement. Ultimately becomes a conditional branch.
Supports “structured programming”
Each function returns a single value, usually an integer. Returned through a specific register by convention.
Copyright © 2001 Stephen A. Edwards All rights reserved
Euclid Compiled on PDP-11
.globl _gcd r0-r7
.text PC is r7, SP is r6, FP is r5
_gcd:
jsr r5,rsave save sp in frame pointer r5
L2:mov 4(r5),r1 r1 = n
sxt r0 sign extend
div 6(r5),r0 m / n = r0,r1
mov r1,-10(r5) r = m % n
jeq L3
mov 6(r5),4(r5) m = n
mov -10(r5),6(r5) n = r
jbr L2
L3:mov 6(r5),r0 return n in r0
jbr L1
L1:jmp rretrn restore sp ptr, return
int gcd(int m, int n)
{
int r;
while ( (r = m % n) != 0) {
m = n;
n = r;
}
return n;
}
Copyright © 2001 Stephen A. Edwards All rights reserved
Euclid Compiled on PDP-11
.globl _gcd
.text
_gcd:
jsr r5,rsave
L2:mov 4(r5),r1
sxt r0
div 6(r5),r0
mov r1,-10(r5)
jeq L3
mov 6(r5),4(r5)
mov -10(r5),6(r5)
jbr L2
L3:mov 6(r5),r0
jbr L1
L1:jmp rretrn
Very natural mapping from C into PDP-11 instructions.
Complex addressing modes make frame-pointer-relative accesses easy.
Another idiosyncrasy: registers were memory-mapped, so taking address of a variable in a register is straightforward.
Copyright © 2001 Stephen A. Edwards All rights reserved
Pieces of C
Copyright © 2001 Stephen A. Edwards All rights reserved
C Types
Copyright © 2001 Stephen A. Edwards All rights reserved
C Type Examples
int i;
int *j, k;
unsigned char *ch;
float f[10];
char nextChar(int, char*);
int a[3][5][10];
int *func1(float);
int (*func2)(void);
Integer
j: pointer to integer, int k
ch: pointer to unsigned char
Array of 10 floats
2-arg function
Array of three arrays of five …
function returning int *
pointer to function returning int
Copyright © 2001 Stephen A. Edwards All rights reserved
C Typedef
int (*func2)(void)
use
typedef int func2t(void);
func2t *func2;
Copyright © 2001 Stephen A. Edwards All rights reserved
C Structures
struct {
char *name;
int x, y;
int h, w;
} box;
box.x = 5;
box.y = 2;
Copyright © 2001 Stephen A. Edwards All rights reserved
Struct bit-fields
struct {
unsigned int baud : 5;
unsigned int div2 : 1;
unsigned int use_external_clock : 1;
} flags;
Copyright © 2001 Stephen A. Edwards All rights reserved
C Unions
union {
int ival;
float fval;
char *sval;
};
Copyright © 2001 Stephen A. Edwards All rights reserved
Alignment of data in structs
4
3
2
1
4
3
2
1
Copyright © 2001 Stephen A. Edwards All rights reserved
Alignment of data in structs
struct {
char a;
int b;
char c;
}
a
b
b
b
b
c
a
b
b
b
b
c
Pad
Copyright © 2001 Stephen A. Edwards All rights reserved
C Storage Classes
#include <stdlib.h>
int global_static;
static int file_static;
void foo(int auto_param)
{
static int func_static;
int auto_i, auto_a[10];
double *auto_d = malloc(sizeof(double)*5);
}
Linker-visible. Allocated at fixed location
Visible within file. Allocated at fixed location.
Visible within func. Allocated at fixed location.
Copyright © 2001 Stephen A. Edwards All rights reserved
C Storage Classes
#include <stdlib.h>
int global_static;
static int file_static;
void foo(int auto_param)
{
static int func_static;
int auto_i, auto_a[10];
double *auto_d = malloc(sizeof(double)*5);
}
Space allocated on stack by function.
Space allocated on stack by caller.
Space allocated on heap by library routine.
Copyright © 2001 Stephen A. Edwards All rights reserved
malloc() and free()
int *a;
a = (int *) malloc(sizeof(int) * k);
a[5] = 3;
free(a);
Copyright © 2001 Stephen A. Edwards All rights reserved
malloc() and free()
Copyright © 2001 Stephen A. Edwards All rights reserved
malloc() and free()
Copyright © 2001 Stephen A. Edwards All rights reserved
Dynamic Storage Allocation
Free
malloc(
)
Copyright © 2001 Stephen A. Edwards All rights reserved
Dynamic Storage Allocation
Copyright © 2001 Stephen A. Edwards All rights reserved
Dynamic Storage Allocation
Copyright © 2001 Stephen A. Edwards All rights reserved
Simple Dynamic Storage Allocation
Copyright © 2001 Stephen A. Edwards All rights reserved
Simple Dynamic Storage Allocation
Next
Size
Next
Size
Size
Free block
Allocated block
malloc(
)
First large-enough free block selected
Free block divided into two
Previous next pointer updated
Newly-allocated region begins with a size value
Copyright © 2001 Stephen A. Edwards All rights reserved
Simple Dynamic Storage Allocation
free(a)
Appropriate position in free list identified
Newly-freed region added to adjacent free regions
Copyright © 2001 Stephen A. Edwards All rights reserved
Dynamic Storage Allocation
Copyright © 2001 Stephen A. Edwards All rights reserved
Memory Pools
Copyright © 2001 Stephen A. Edwards All rights reserved
Arrays
Filippo Brunelleschi, Ospdale degli Innocenti, Firenze, Italy, 1421
Copyright © 2001 Stephen A. Edwards All rights reserved
Multidimensional Arrays
2
2
2
3
2
2
2
3
2
2
2
3
...
10
Seagram Building, Ludwig Mies van der Rohe,1957
Copyright © 2001 Stephen A. Edwards All rights reserved
Multidimensional Arrays
int a[10][3][2];
void examine( a[][3][2] ) { … }
a + k + 2*(j + 3*i)
Copyright © 2001 Stephen A. Edwards All rights reserved
Multidimensional Arrays
int ***a;
The value
int **
int *
int
int ***a
Copyright © 2001 Stephen A. Edwards All rights reserved
C Expressions
y = a*x*x + b*x + c;
Copyright © 2001 Stephen A. Edwards All rights reserved
C Expression Classes
Copyright © 2001 Stephen A. Edwards All rights reserved
Bitwise operators
#define MASK 0x040
if (a & MASK) { … } /* Check bits */
c |= MASK; /* Set bits */
c &= ~MASK; /* Clear bits */
d = (a & MASK) >> 4; /* Select field */
Copyright © 2001 Stephen A. Edwards All rights reserved
Lazy Logical Operators
if ( a == 3 && b == 4 && c == 5 ) { … }
equivalent to
if (a == 3) { if (b ==4) { if (c == 5) { … } } }
if ( i <= SIZE && a[i] == 0 ) { … }
Copyright © 2001 Stephen A. Edwards All rights reserved
Conditional Operator
a := 5 + valof{ int i, s = 0; for (i = 0 ; i < 10 ; i++) s += a[I];
return s; }
Copyright © 2001 Stephen A. Edwards All rights reserved
Side-effects in expressions
a++ increment a afterwards
a = 5 changes the value of a
a = foo() function foo may have side-effects
Copyright © 2001 Stephen A. Edwards All rights reserved
Pointer Arithmetic
int *p, *q;
*(p+5) equivalent to p[5]
p->field means (*p).field
Copyright © 2001 Stephen A. Edwards All rights reserved
C Statements
Copyright © 2001 Stephen A. Edwards All rights reserved
The Switch Statement
switch (expr) {
case 1: …
break;
case 5:
case 6: …
break;
default: …
break;
}
tmp = expr;
if (tmp == 1) goto L1
else if (tmp == 5) goto L5
else if (tmp == 6) goto L6
else goto Default;
L1: …
goto Break;
L5:;
L6: …
goto Break;
Default: …
goto Break;
Break:
Copyright © 2001 Stephen A. Edwards All rights reserved
Switch Generates Interesting Code
if (e == 1) goto L1;
else if (e == 10) goto L2;
else if (e == 100) goto L3;
table = { L1, L2, Default, L4, L5 };
if (e >= 1 and e <= 5) goto table[e];
Copyright © 2001 Stephen A. Edwards All rights reserved
setjmp/longjmp
#include <setjmp.h>
jmp_buf jmpbuf;
void top(void) {
switch (setjmp(jmpbuf)) {
case 0: child(); break;
case 1: /* longjmp called */ break;
} }
void deeplynested() { longjmp(jmpbuf, 1); }
Space for a return address and registers (including stack pointer, frame pointer)
Stores context, returns 0
Returns to context, making it appear setjmp() returned 1
Copyright © 2001 Stephen A. Edwards All rights reserved
The Macro Preprocessor
#define PI 3.1415926535
#define min(x,y) ((x) < (y) ? (x) : (y))
#ifdef __STDC__
#include “myheaders.h”
Copyright © 2001 Stephen A. Edwards All rights reserved
Macro Preprocessor Pitfalls
#ifndef __MYHEADER_H__
#define __MYHEADER_H__
/* Declarations */
#endif
Copyright © 2001 Stephen A. Edwards All rights reserved
Macro Preprocessor Pitfalls
Copyright © 2001 Stephen A. Edwards All rights reserved
Macro Preprocessor pitfalls
int min(int a, int b)
{ if (a < b) return a; else return b; }
#define min(a,b) ((a) < (b) ? (a) : (b))
min(a++,b)
Copyright © 2001 Stephen A. Edwards All rights reserved
Macro Preprocessor Pitfalls
#define mult(a,b) a*b
mult(5+3,2+4)
5 + (3*2) + 4 = 15 not (5+3) * (2+4) = 48 as intended
#define mult(a,b) (a)*(b)
Copyright © 2001 Stephen A. Edwards All rights reserved
Nondeterminism in C
int a;
a = 1 << 16; /* Might be zero */
a = 1 << 32; /* Might be zero */
Copyright © 2001 Stephen A. Edwards All rights reserved
Nondeterminism in C
Copyright © 2001 Stephen A. Edwards All rights reserved
Nondeterminism in C
Copyright © 2001 Stephen A. Edwards All rights reserved
Summary
Copyright © 2001 Stephen A. Edwards All rights reserved
Summary of C types
Copyright © 2001 Stephen A. Edwards All rights reserved
Summary of C expressions
Copyright © 2001 Stephen A. Edwards All rights reserved
Summary of C statements
Copyright © 2001 Stephen A. Edwards All rights reserved
Summary of C
Copyright © 2001 Stephen A. Edwards All rights reserved
The Main Points
Copyright © 2001 Stephen A. Edwards All rights reserved