Professional Documents
Culture Documents
C Review
C Review
January 2016
January 2016
1 / 40
Introduction
Table of contents:
Basic preprocessor use
Pointer recap
Linked lists in Pintos
Misc.
January 2016
2 / 40
The C Preprocessor
January 2016
3 / 40
#define
What?
#define identifier replacement
Example: #define PI 3.0
Subsequent occurences of identifier will be replaced by
replacement
Usage
Use #define to replace small amounts of code to make it more
readable or avoid magic numbers
Use it to define constants at compile time:
#define DEBUG 1
January 2016
4 / 40
Macros
What?
#define can also be used with parameters.
#define identifier( params ) replacement
Example: #define P(X) printf(%d,(X))
Subsequent occurences of identifier will be replaced by
replacement, with params substituted in.
Usage
Use #define to replace small amounts of code to make it more
readable or define simple functionality
Macros have less execution overhead than a function call
January 2016
5 / 40
Macro Safety
Some general points to be aware of when using macros in C:
You should surround each term of a macro with parentheses:
#define TWICE(x) x * 2
TWICE(3 + 5)
result: 3 + 5 * 2
You should surround the whole macro replacement with parentheses:
#define TWICE(x) (x) * 2
10 / TWICE(5)
result: 10 / (5) * 2
The correct version of this macro is:
#define TWICE(x) ((x) * 2 )
January 2016
6 / 40
January 2016
7 / 40
Macro examples
Return max of two elements
#define MAX(x, y) do { typeof(x) _x = (x); \
typeof(y) _y = (y); \
_x > _y ? _x : _y } while (0)
January 2016
8 / 40
Include Guards
This problem appears when multiple files include the same header
my lib.h
struct my_struct {int x;};
my extended lib.h
#include "my_lib.h"
my program.c
#include "my_lib.h"
#include "my_extended_lib.h"
January 2016
9 / 40
Include Guards
January 2016
10 / 40
Conditional Compilation
#ifdef and #ifndef are also used for conditional compilation
Example:
struct my_struct {
int x;
#ifdef VERBOSE
char buffer[1000];
#endif
};
Common uses are:
Debug/test/verbose
Platform-dependent code
To address dependency issues
Ioannis Papagiannis, Pedro Mediano, Feroz Salam, Mark
C andWheelhouse
Data Structures
(Imperial
in Pintos
College London)
January 2016
11 / 40
January 2016
12 / 40
Pointers
January 2016
13 / 40
Declaring pointers
/*
/*
/*
/*
A
A
A
A
pointer
pointer
pointer
pointer
to
to
to
to
a double */
an int */
int a and an int b */
a pointer to an int */
Pointers can have arbitrary levels of indirection i.e. you can have a
pointer to a pointer.
January 2016
14 / 40
Pointer operators
January 2016
15 / 40
0x2b00b1e5:
0x2b0a43e0:
c = t
p = 0x2b00b1e5
0x2b00b1e5:
0x2b0a43e0:
c = u
p = 0x2b00b1e5
*p = u;
January 2016
16 / 40
The stack
Handled entirely by the CPU
Emptied at the end of current scope
Slightly faster access
The heap
Handled mostly by the programmer
Lives forever (or until freed)
Much bigger space
January 2016
17 / 40
Memory allocation
Stack
float v[10];
Heap
float *v;
v = (float *) malloc(10*sizeof(float));
...
free(v) /* Remember to free the memory! */
Other than that, float v[] and float *v can usually be treated
equivalently.
But it can get messy if mixed agree with your teammates.
January 2016
18 / 40
January 2016
19 / 40
Pointer Arithmetic
When adding to pointers, the type of the pointer is important.
struct my_struct {
int a;
int b;
};
struct my_struct s[2];
struct my_struct *sp = &s[0];
int *ip = (int *) sp;
sp++; /* points to the second struct */
ip++; /* points to the second int of the first struct */
January 2016
20 / 40
Pointer tip
Anti-bug tip
Set all your pointers to NULL at initialization!
(And maybe also after freeing them)
That allows you to do things like:
assert( p != NULL );
*p = 1;
if (p) free(p);
That wouldnt necessarily work if p wasnt explicitly set to NULL
beforehand.
January 2016
21 / 40
January 2016
22 / 40
Pointers as arguments
Pass by reference
When you want to modify an argument inside the function, pass a pointer.
void setInt(int *v, int i) { *v = i; }
January 2016
23 / 40
January 2016
24 / 40
Linked lists
13
21
January 2016
25 / 40
13
21
8
Deletion:
13
5
21
January 2016
26 / 40
Motivation
January 2016
27 / 40
/* List head. */
/* List tail. */
January 2016
28 / 40
Lists in Pintos
Its very important that you understand how to use lists in Pintos
The Pintos list implementation in <list.h> contains several useful
functions.
Dont reinvent the wheel use them!
January 2016
29 / 40
Inserting an item
/* e_before is the list_elem of the struct that
you want to insert the item after */
list_insert (&(e_before.next) , &(e.next));
January 2016
30 / 40
January 2016
31 / 40
Function Pointers
Just like you can have a pointer to a variable in C, you can also have a
pointer to a function.
Define Functions
int f1( int x ) { return x; }
int f2( int x ) { return x+1; }
January 2016
32 / 40
January 2016
33 / 40
January 2016
34 / 40
Callbacks
Very useful thing you can do with function pointers.
void fill(int *v, int n, int (*getValue)(void)) {
for (int i = 0; i < n; i++) v[i] = getValue();
}
int getRandomValue(void) { return rand(); }
int main(void) {
int myarray[10];
fill(myarray, 10, getRandomValue);
return 0;
}
Watch out with the * and & operators!
Ioannis Papagiannis, Pedro Mediano, Feroz Salam, Mark
C andWheelhouse
Data Structures
(Imperial
in Pintos
College London)
January 2016
35 / 40
January 2016
36 / 40
Booleans
stdbool.h defines type bool
true expands to 1
false expands to 0
Examples of use in code same as in any other language, really
January 2016
37 / 40
Coding Standards
January 2016
38 / 40
January 2016
39 / 40
The End
Any questions?
Remember, the discussion forum on Piazza is at your disposal!
Useful books
The C Programming Language by Kernighan and Ritchie
Prentice Hall, 2nd edition
C Traps and Pitfalls by Andrew Koenig
Addison Wesley, 1st edition
January 2016
40 / 40