High Performance Computing in C and C++ Rita Borgo Computer Science Department, Swansea University
Summary Introduction to C Writing a simple C program Compiling a simple C program Running a simple C program C Compiler C Preprocessor Data Types and Type Conversions Memory Allocations Pointers File I/O
Today Arithmetic Operators Arrays Struct Union Bitfields Control Flows
Operators Mathematical operators in C are identical to those in Java. Arithmetic Operators: +, -, *, /, % (modulus) Note: % only works with integers. / division is type dependent: float x=3/2; / produces x=1 (int /) / float x=3.0/2 / produces x=1.5 (float /) / int x=3.0/2; / produces x=1 (int conversion) /
Operators Mathematical operators in C are identical to those in Java. Arithmetic Operators: +, -, *, /, % (modulus) Relational Operators: <=, >=, ==,!=, <, > Note: The!= represents not equal to. The == equality operator is different from the =, assignment operator. The == operator on float variables is tricky because of finite precision.
Operators Mathematical operators in C are identical to those in Java. Arithmetic Operators: +, -, *, /, % (modulus) Relational Operators: <=, >=, ==,!=, <, > Logical operators &&,,! Note: Short circuit: The evaluation of an expression is discontinued if the value of a conditional expression can be determined early. Be careful of any side effects in the code. Examples: (3==3) ((c=getchar())== y ). The second expression is not evaluated. (0) && ((x=x+1)>0). The second expression is not evaluated.
Short-Circuiting When behaviour is unpredictable: char *p = /* initialize, may or may not be NULL */ if (p (p = (char *) malloc(buf_size)) ) { /* do stuff with p */ free(p); p = NULL; } else { /* handle malloc() error */ return; }
Operators Mathematical operators in C are identical to those in Java. Arithmetic Operators: +, -, *, /, % (modulus) Relational Operators: <=, >=, ==,!=, <, > Logical Operators: &&,,! Bitwise Operators: &,, ^, <<, >>, ~ Note: AND, OR, XOR, left shift, right shift, one s complement AND is true only if both operands are true. OR is true if any operand is true. XOR is true if only one of the operand is true. One s Complement ~ flips every bit. Do not confuse LOGICAL (&&, ) with BITWISE operators (&, ).
Bitwise Operators Shifting: Example x << 2; // shifts the bits in x by 2 places to the left. Advantages: it is equivalent to a multiplication by 2. Note: shifting is much faster than actual multiplication (*) or division (/) by 2. So if you want fast multiplications or division by 2 use shifts.
Operators Mathematical operators in C are identical to those in Java. Arithmetic Operators: +, -, *, /, % (modulus) Relational Operators: <=, >=, ==,!=, <, > Logical Operators: &&,,! Bitwise Operators: &,, ^, <<, >>, ~ ++i, i++, --i, i-- (pre/post-increment/decrement)
Increment and Decrement Increment and decrement are common arithmetic operation. C provides two short cuts for the same operation: Postfix: x++ is a short cut for x=x+1 x-- is a short cut for x=x-1 y=x++ is a short cut for y=x; x=x+1. x is evaluated before it is incremented. y=x-- is a short cut for y=x; x=x-1. x is evaluated before it is decremented. Prefix: ++x is a short cut for x=x+1 x-- is a short cut for x=x-1 y=++x is a short cut for x=x+1; y=x. x is evaluated after it is incremented. y=--x is a short cut for x=x-1; y=x. x is evaluated after it is decremented.
Assignment Operators Another common expression type found while programming in C is of the type: var = var (op) expr x = x + 1; C provides compact assignment operators that can be used instead: x+=1 /*is the same as x=x+1 */ x-=1 /* is the same as x=x 1 */ x*=10 /*is the same as x=x 10 */ x/=2 /* is the same as x=x/2 */ x%=2 /* is the same as x=x%2 */ Note: x *= y + 2 means x = x*(y + 2) and NOT x = x*y + 2.
Order of Operators Order of operations: Use parentheses to override order of evaluation. Operator +,-(sign) Evaluation direction (or Associativity) right-to-left *,/,% left-to-right +,- -left-to-right =,+=,-=,*=,/=,%= right-to-left
Structured data objects Structured data objects are available as object array [] property enumerated, numbered from 0 struct union names and types of fields occupy same space (one of)
Arrays An array is a group of memory locations with the same name and type Arrays are defined by specifying an element type and number of elements int vec[100]; char str[30]; float m[10][10]; For array containing N elements, indexes are 0..N-1 Often similar to pointers
Arrays C does not remember how large arrays are (i.e., no length attribute) int x[10]; x[10] = 5; may work (for a while) In the block where array A is defined: sizeof A gives the number of bytes in array can compute length via sizeof A /sizeof A[0] When an array is passed as a parameter to a function the size information is not available inside the function array size is typically passed as an additional parameter PrintArray(A, VECSIZE); or as part of a struct (best, object-like) or globally #define VECSIZE 10
Arrays Array elements are accessed using the same syntax as in Java: array[index] Example (iteration over array): int i, sum = 0;... for (i = 0; i < VECSIZE; i++) sum += vec[i]; C does not check whether array index values are sensible (i.e., no bounds checking) vec[-1] or vec[10000] will not generate a compiler warning! if you re lucky, the program crashes with Segmentation fault (core dumped)
Arrays C references arrays by the address of their first element array is equivalent to &array[0] can iterate through arrays using pointers as well as indexes: int *v, *last; int sum = 0; last = &vec[vecsize-1]; for (v = vec; v <= last; v++) sum += *v;
2-D arrays 2-dimensional array int weekends[52][2]; [0][0] [0][1] [1][0] [1][1] [2][0] [2][1] [3][0].... weekends weekends[2][1] is same as *(weekends+2*2+1) NOT *weekends+2*2+1 :this is an int!
Arrays - example #include <stdio.h> void main(void) { int number[12]; /* 12 cells, one cell per student */ int index, sum = 0; /* Always initialize array before use */ for (index = 0; index < 12; index++) { number[index] = index; } /* now, number[index]=index; will cause error:why?*/ } for (index = 0; index < 12; index = index + 1) { sum += number[index]; /* sum array elements */ } return;
structs Similar to fields in Java object/class definitions components can be any type (but not recursive) accessed using the same syntax struct.field Example: struct {int x; char y; float z;} rec;... r.x = 3; r.y = a ; r.z= 3.1415;
structs Record types can be defined using a tag associated with the struct definition wrapping the struct definition inside a typedef Examples: struct complex {double real; double imag;}; struct point {double x; double y;} corner; typedef struct {double real; double imag;} Complex; struct complex a, b; Complex c,d; a and b have the same size, structure and type a and c have the same size and structure, but different types
structs Overall size is sum of elements, plus padding for alignment (i.e., how many bytes are allocated) but, it depends on the size and order of content (e.g., ints need to be aligned on word boundaries, since size of char is 1 and size of int is 4): struct { char x; int y; char z; } s1; sizeof(s1) =? struct { char x, z; int y; } s2; sizeof(s2) =?
structs - example struct person { char name[41]; int age; float height; struct { /* embedded structure */ int month; int day; int year; } birth; }; struct person me; me.birth.year=1977; struct person class[60]; /* array of info about everyone in class */ class[0].name= Gun ; class[0].birth.year=1971;
structs Often used to model real memory layout, e.g., typedef struct { unsigned int version:2; unsigned int p:1; unsigned int cc:4; unsigned int m:1; unsigned int pt:7; u_int16 seq; u_int32 ts; } rtp_hdr_t;
Dereferencing pointers to struct elements pointers to structs are common especially useful with functions (as arguments to functions or as function type) two notations for accessing elements (*sp).element = 42; y = (*sp).element; Note: *sp.element doesn t work Abbreviated alternative: sp->element = 42; y = sp->element;
Unions Like structs: union u_tag { } u; int ival; float fval; char *sval; but occupy same memory space can hold different types at different times overall size is largest of elements
Bit fields Allows aligning struct with real memory data, e.g., in protocols or device drivers Order can differ between little/big-endian systems Alignment restrictions on modern processors natural alignment Sometimes clearer than (x & 0x8000) >> 31
Bitfields Definition: A bit-field is a set of adjacent bits within a single word. Example: struct flag { }; unsigned int is_color :1; unsigned int has_sound :1 ; unsigned int is_ntsc :1; the number after the colons specifies the width in bits. each variables should be declared as unsigned int.
Bitfields and Masks Bit fields vs. masks Example: struct flag { }; unsigned int is _color :1; unsigned int has_sound :1 ; unsigned int is _ntsc :1; CLR=0x1,SND=0x2,NTSC=0x4; struct flag f; x = CLR; x =SND; x =NTSC x&= ~CLR; x&=~snd; if (x & CLR x& NTSC) f.has_sound=1;f.is_color=1 f.has_sound=0;f.is_color=0; if(f.is_color f.has_sound)
Control structures Same as Java sequencing: ; grouping: {...} selection: if, switch iteration: for, while
Sequencing and grouping statement1 ; statement2; statement n; executes each of the statements in turn a semicolon after every statement not required after a {...} block { statements} {declarations statements} treat the sequence of statements as a single operation (block) data objects may be defined at beginning of block
The if statement Same as Java if (condition 1 ) {statements 1 } else if (condition 2 ) {statements 2 } else if (condition n-1 ) {statements n-1 } else {statements n } evaluates statements until find one with nonzero result executes corresponding statements
The if statement Can omit {}, but careful if (x > 0) printf( x > 0! ); if (y > 0) printf( x and y > 0! );
The switch statement Allows choice based on a single value switch(expression) { } case const1: statements1; break; case const2: statements2; break; default: statementsn; Effect: evaluates integer expression looks for case with matching value executes corresponding statements (or defaults)
The switch statement Weather w; switch(w) { case rain: printf( bring umbrella ); case snow: printf( wear jacket ); break; case sun: printf( wear sunscreen ); break; default: printf( strange weather ); }
Repetition C has several control structures for repetition Statement while(c) {} do {...} while(c) for (start; cond; upd) repeats an action... zero or more times, while condition is 0 one or more times, while condition is 0 zero or more times, with initialization and update
The break statement break allows early exit from one loop level for (init; condition; next) { } statements1; if (condition2) break; statements2;
The continue statement continue skips to next iteration, ignoring rest of loop body does execute next statement for (init; condition1; next) { } statement2; if (condition2) continue; statement2; often better written as if with block