Programming in C - Part 2 CPSC 457 Mohammad Reza Zakerinasab May 11, 2016 These slides are forked from slides created by Mike Clark
Where to find these slides and related source code? http://goo.gl/k1qixb http://pages.cpsc.ucalgary.ca/~mrzakeri/s2016/tut2- source-code.zip I will set up a web page for the tutorial sessions this weekend.
Programming in C - Part 1 - Review Why programming in C? The structure of a simple C program Preprocessor directives & header files Data types Operators Control structures Data Structures Compilation & linking
Hello World Example #include <stdio.h> int main() { /* my first program in C */ printf("hello, World! \n"); return 0;
Structured Data Types: Arrays Arrays - Can be a static or dynamic allocation Static (Declaration, and allocation) Dynamic (Declaration) (Allocation) Can be accessed using an index. Ex. (Deallocation)
Structured Data Types: Structures Composed of primitives and other user-defined types (structs). Commonly, you will want to use typedef to alias the typename to something shorter. Accessing struct fields is done with the dot character:
Structured Data Types: Unions Unions - Similar to a structure, but the fields overlap each other. - The size needed to allocate a union is determined by the largest size of the fields. - Each field can be addressed, the value accessed will be determined by the type of the field Example
Control Structures Conditional Examples if, else if, else switch Looping do while for
Compiling and linking Makefile Used to build things. Building C (compiling & linking) is a common thing, but Makefiles are good for other automated build tasks. - variables: compiler (gcc) and compiler flags (CFLAGS). - Wall=warnings (display) all - default target (all) - To build the file (target), we need file (dependencies) - macro replace.flags. - macro replace for target. macro replace for dependencies - clean target. remove binaries (and intermediaries if they exist). Commands:
Exercise 3: Loops.c Write a program that takes in a single, positive integer as a command line argument,and then writes the numbers 0 through to that number on stdout. #include <stdio.h> #include<stdlib.h> int main() { int number; number = atoi(argv[1]); int i = 0; /* do - while */ do { printf("%d\n", i); i++; while (i <= number); i = 0; /* while */ while (i <= number) printf("%d\n", i++); /* for */ for(i = 0; i <= number; i++) printf("%d\n", i); return 0;
Exercises for home Add error handling to the Fibonacci.c program so that when the user passes a nonnegative integer in the command line, the program terminates with an exit status of 1. Modify Fibonacci.c to Fibonacci2.c such that the program prints all the numbers of Fibonacci series toward the given number. Write a non-recursive version of the Fibonacci2.c program.
Programming in C - Part 2 Pointers Typecasting
Pointers A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. - same width as long primitive type - 4 bytes wide (32 bit arch). - 8 bytes wide (64 bit arch) - some esoteric architectures have other widths (don t worry about them) Declaration Pointers can point to other pointer types (ad infinitum)
Pointers - Basic Usage Assignment You can modify the value of the pointer (the address it s holding) like a normal variable. Referencing Retrieves the address of a variable. (reverse operation as dereferencing) Dereferencing Dereferencing a pointer retrieves the value stored at the memory address held by that pointer.
Pointers - Indexing Indexing - notation for indexing. - when operating on pointers, the square brackets dereference the pointer and then indexes into the memory referenced - each index advances the same number of bytes as the size of the pointer type Example
Pointers - Example 1 - pointers.c #include <stdio.h> int main () { int var = 20; /* actual variable declaration */ int *ip; /* pointer variable declaration */ ip = &var; /* store address of var in pointer variable*/ printf("address of var variable: %p\n", (void *) &var ); printf("address stored in ip variable: %p\n", (void *) ip ); printf("value of *ip variable: %d\n", *ip ); return 0;
Pointers - Multiple Dereferencing Multiple Dereferencing You can stack dereference operators to obtain the value of nested pointers. Although you can stack the dereference operator, you CANNOT stack the reference operator Example
Null Pointers The NULL pointer is a constant with a value of zero defined in several standard libraries. It is always a good practice to assign a NULL value to a pointer variable if you do not have an exact address to be assigned yet. //nullpointer.c #include <stdio.h> int main () { int *ptr = NULL; printf("the value of ptr is : %p\n", (void *) ptr ); return 0; To check for a null pointer, you can use an 'if' statement as follows:
Passing a Pointer to a Function C does not support pass by reference. But you can use pointers to change the value of a parameter inside a function. //pointer-param.c #include <stdio.h> void f(int *j) { (*j)++; int main() { int i = 20; f(&i); printf("i = %d\n", i); int *p = &i; f(p); printf("i = %d\n", i); return 0;
Pointer Arithmetic Incrementing a Pointer: ++ In dynamic arrays, we use a pointer to point to the beginning of the array. Incrementing the pointer to array moves to the next item in the array. #include <stdio.h> const int MAX = 3; int main () { int var[] = {10, 100, 200; int i, *ptr; /* let us have array address in pointer */ ptr = var; for ( i = 0; i < MAX; i++) { printf("address of var[%d] = %p\n", i, (void *) ptr ); printf("value of var[%d] = %d\n", i, *ptr ); /* move to the next location */ ptr++; return 0;
Pointer Arithmetic Decrementing a Pointer: -- Decrementing the pointer to array moves to the previous item in the array. #include <stdio.h> const int MAX = 3; int main () { int var[] = {10, 100, 200; int i, *ptr; /* let us have array address in pointer */ ptr = &var[max-1]; for ( i = MAX; i > 0; i--) { printf("address of var[%d] = %p\n", i, (void *) ptr ); printf("value of var[%d] = %d\n", i, *ptr ); /* move to the previous location */ ptr--; return 0;
Pointers to structs Struct Pointers
Function Pointers Function pointers need more information than just the address of the function, they need the signature of the function (ret value, parameters) so the compiler can emit the correct assembly instructions. Declaration Usage
Initializing a Function Pointer //func-pointer.c #include <stdio.h> void my_int_func(int x) { printf( "%d\n", x ); int main() { void (*foo)(int); /* the ampersand is actually optional */ foo = &my_int_func; foo(2); return 0;
Using a Function Pointer //funcp-use.c #include <stdio.h> void my_int_func(int x) { printf( "%d\n", x ); int main() { void (*foo)(int); foo = &my_int_func; /* call my_int_func (note that you do not need to write (*foo)(2) ) */ foo( 2 ); /* but if you want to, you may */ (*foo)( 2 ); return 0;
Passing a Function Pointer //funcp-pass.c #include <stdio.h> void my_int_func(int x) { printf( "%d\n", x ); void run_my_func(void (*myfunc)(int), int param) { myfunc(param); int main() { void (*foo)(int); foo = &my_int_func; /* pass my_int_func to run_my_func */ run_my_func(foo, 2); return 0;
Typecasting Typecasting allows us to tell the compiler how we want it to interpret the data. - type information implies how to read, write and manipulate that type of data - dictates the effect of operations on the data Examples - char and int pointers increment at different rates - signedness 0x70 + 0x70 = 0xD0 = 208 (signed char) 0x70 + 0x70 = 0xD0 = -32 (unsigned char) - casting to smaller size data type truncates result. - casting to larger size data type pads the remaining bytes depending on the data type. (preserve the value of the data) - Unsigned pad the higher bits with zeros. - Signed: sign extend (pad with zeros or 1s depending on MSb of data type being expanded )
Typecasting Padding & Truncation Unsigned Effect of casting between different sized types on memory
Typecasting Padding & Truncation Signed (A) Effect of casting between different sized types on memory
Typecasting Padding & Truncation Signed (B) Effect of casting between different sized types on memory
Typecasting - Pointers Pointers - can typecast pointers as well. - commonly needed for allocation routines which return type Example -
Further Reading Interactive C programming exercises (highly recommended) http://www.learn-c.org/en/ C Programming Language http://www.amazon.ca/c-programming-language-2nd-edition/dp/0131103628 (I m sure you can find a pdf of this online for free)