20180821 ******************************************************* Example: Hello, world! // Lines starting with # are processed by preprocessed // No semicolon #include statement // C is case-sensitive #include // int: an integer type int main(){ printf("Hello, world!\n"); // sends the message to STDOUT // \n = newline; \t = tab character \ the escape character return 0; // returns the value to the OS } Java: javac JVM x.java -------> X.class ---------> output Perl/python perl/python x.pl/x.py ---------------> output C: gcc x.c ------------> a.out ------------> output compiled execute GCC Compiler --------------------------------- gcc invokes C compilers, translates C code into an executable Example: gcc helloWorld.c ./a.out Two-stage Compilation ---------------------- 1) pre-process & compile: gcc -c helloWorld.c (Produces hello.o) 2) link: gcc -o hello hello.o Linking several modules example: gcc -c a.c (produces a.o) gcc -c b.c (produces b.o) gcc -o solveWorldHunger a.o b.o Use math library: gcc -o calc calc.c -lm gcc flags: ---------------------- -o file output file for object or executable -Wall display all warnings -c compile single module -g insert debugging code -p insert profiling code -l file library -L dir library path -I dir include path Common errors using gcc: ---------------------- preprocessor: missing include file parser: syntax errors linker: missing libraries & undefined symbols 20180823 ******************************************************* #include void main(){ printf("Go Cougars!\n"); return 0; } gcc cougars.c -o csu c Preprocessor (cpp) ********************************* macro-processor textual changes Preprocessor directives start with # gcc -E shows output of preprocessor #if #else #endif ~~~~~~~~~~~~~~~~~~~~~~ #if expression code segment 1 #else code segment 2 #endif Example: #if OS == linux #include #else #include #endif #ifdef ~~~~~~~~~~~~~~~~~~~~~~ #ifdef name code segment 1 #else code segment 2 #endif #define ~~~~~~~~~~~~~~~~~~~~~~ #define name const-expression #undef name Example: #define MAXVALUE 100 if( i < MAXVALUE){ ... } becomes if( i < 100){ ... } #include ~~~~~~~~~~~~~~~~~~~~~~ #include // looks in the include directories #include "filename.h" // looks first in the current, then in the include directories Include Guards ~~~~~~~~~~~~~~~~~~~~~~ Example: includeGuardsExample/main-noIncludeGuards.c Example: includeGuardsExample/main.c Comments ********************************* 1) Sections (maybe multi-line): /* any text until */ Example: for( int i = 1 /* start at 1 instead of 0 b/c .... */; i < 100; i++){ /* * FunctionName() * Description of function */ 2) Rest of line: // C++ style comment Numeric Data Types ********************************* type bytes range ------ ------ ------------ char 1 -128 to 127 (-2^7 to 2^7) int 4 -2,147,483,648 to 2,147,483,647 (-2^31 to 2^31) long long 8 -2^63 to 2^63 float 4 3.4E+/-38 (7 digits of precision) double 8 1.7E+/-308 (15 digits of precision) Sizes (and therefore ranges) vary slightly per system unsigned versions of whole number types (changes range to be 0 - ...) What's missing? 1. strings (C-style strings) 2. boolean (char or int, 1 and 0) Most Common: ~~~~~~~~~~~~~~~~~~~~~~ char int double 20180828 ******************************************************* Variables (Data objects) --------------------------------- Uninitialized variables have "random" value Always initialize your variables Every variable in C has: 1) a name 2) a data type (size) 3) address in memory (location) 4) visibility (which parts of the program can refer to it) 5) lifetime (period during which it exists) Size of an object [think variable for now] is determined when it's created: 1) global data objects at compile time (data) 2) local data objects at run-time (stack) 3) dynamic data objects by programmer (heap) Scoping ---------------------- Variables declared in a { } block are usable (visible) only within that block Variables declared outside of a { } blocks are global. Use sparingly and with caution Example: variablesExample.c.html Exercise: What will the output be of the following (if any)? int solution; solution++; printf("solution: %d\n", solution); Type Conversion --------------------------------- Explicit Type Conversion: ---------------------- Syntax: (type) Example: int count = 99; double cost = (double) count * 5.34; Example: explicitTypeConversionExample.c.html Implicit: ---------------------- Syntax: Exercise: Discuss with your neighbor what will the output be of the following (if any)? int i = 100000; char c; c = i; printf("i: %d, c: %d\n", i, c); A: i: 100000, c: -96 Exercise: What is the value of the following expressions: int age; A. age = 8 B. -age C. 5 + 8 D. 5 / 8 E. 5 / 8.0 F. float( 7/3 ) G. float( 7 ) / 3 Arrays --------------------------------- Examples: ----------- int vec[100]; // holds 100 elements, indexed 0..99 char str[30]; // holds 30 elements, indexed 0..29 float m[12][31]; // holds 12*31 elements On the stack array[ index ] printf("%d\n", vec[ 999999 ]); sizeof( ) ---------------------- sizeof( data type) returns the number of bytes for a data type Example: ----------- sizeof( int) or sizeof int Example: ----------- int simpleNum = -1; sizeof( simpleNum); // or sizeof simpleNum; int vec[100]; sizeof( vec ); int arraySize = sizeof( vec ); int elementSize = sizeof( vec[0] ); printf( "vec has %d elements\n", arraySize / elementSize )); Exercise: Write code to sum the first 50 elements of an int array named receiptTotals. Pointers --------------------------------- Review ~~~~~~~~~~~~~~~~~~~~~~ int counter = 1; Pointers are a data type A pointer holds a memory address Example: ----------- int* myIntPtr; double* ptrToGradient; pointers: "variables that tell you where to find something else" (Dale & Weems) Analogy: PO Boxes int secretBankAccountNumber = 456789; int* myIntPtr = secretBankAccountNumber; // bad idea & operator ---------------------- & (address-of operator): returns the memory address of the first byte in memory of a variable myIntPtr = &secretBankAccountNumber; Example: int answer = 42; int* answerPtr = &answer; printf("answer's value: %d\n", answer); printf("answerPtr's value (base-10): %ld\n", answerPtr); printf("answerPtr's value (hexadecimal): %p\n", answerPtr); Memory Contents Type Name Address ------------------ ---- ---------- --------- | | +----------------+ | 0x7ffeea7fe2e8 | int* answerPtr 0x7ffeea7fe2e0 +----------------+ | 42 | int answer 0x7ffeea7fe2e8 +----------------+ | | 20180830 ******************************************************* Example: addressOfExample.c (or *.c.html) * (dereference) operator ---------------------- * dereferences a variable (it interprets the contents of that variable as address, of a particular type_) Example: printf("*answerPtr's value: %d\n", *answerPtr); Example: pointerExample.c (or *.c.html) Exercise: Given the following code, determine the data type for each expression: int x; int* ptr; Expression Data type Possible Values ---------- --------- --------------- x int 123456789, -123456789, 23456789, 0, -1 ptr int* 0x0, 0x7fffebcafe34 (addresses) *ptr int &ptr int** (addresses) &x int* (addresses) Example: +------+ | ???? | 0x10 | | +------+ | ???? | 0x14 | | +------+ | ???? | 0x18 | | +------+ int x; // at 0x10 int* p; // at 0x14 int* q; // at 0x18 +------+ | ???? | 0x10 | | int x +------+ | ???? | 0x14 | | int* p +------+ | ???? | 0x18 | | int* q +------+ p = &x; +------+ | ???? | 0x10 | | int x +------+ | 0x10 | 0x14 | | int* p +------+ | ???? | 0x18 | | int* q +------+ *p = 7; +------+ | 7 | 0x10 | | int x +------+ | 0x10 | 0x14 | | int* p +------+ | ???? | 0x18 | | int* q +------+ q = p; +------+ | 7 | 0x10 | | int x +------+ | 0x10 | 0x14 | | int* p +------+ | 0x10 | 0x18 | | int* q +------+ *q = 11; +------+ | 11 | 0x10 | | int x +------+ | 0x10 | 0x14 | | int* p +------+ | 0x10 | 0x18 | | int* q +------+ p = NULL; +------+ | 11 | 0x10 | | int x +------+ | NULL | 0x14 | (0) | int* p +------+ | 0x10 | 0x18 | | int* q +------+ Exercise: Diagram the elements on the stack and write the output of the following (adapted from HERE): #include int main (){ int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for( int n = 0; n < 5; n++){ printf("%d, ", numbers[n]); } return 0; } 20180904 ******************************************************* Exercise: Write code for each of the following and make sure that it compiles: a. Declare ex0 as a pointer to a char b. Declare ex1 as a pointer to a pointer to a char c. Declare ex2 as an array of 10 elements d. Declare ex3 as an array of 10 elements that are pointers to chars e. Declare ex4 as a pointer to an array of 30 char elements f. Declare ex5 as an array of 10 pointers to arrays of 500 char elements g. Declare ex7 as a pointer to const int h. Write a function ex8 that takes a char pointer named pc, increments the address that it points to and returns that value i. Write a function ex9 that takes an int pointer named num, and prints out what num points to and a message saying if what num points to is odd or even C-style Strings ================================= https://i.imgur.com/NwNPU.png (or https://imgur.com/NwNPU) Example: cStyleStrings.c Executing a C program: Command-line arguments ================================= // Function parameters: // argc: number of arguments // argv: array (notice the []) of char *s (which are pointers to strings) int main( int argc, char *argv[] ){ // ... return 0; } Command-line Arguments Example ----------- Syntax: [] Example: a.out 1 23 awesome argc: argv: +---+---+---+---+ | | | | | | | | | | | | | | +-+-+-+-+-+-+-+-+ | | | | | | | v | | v "awesome" | v "23" v "1" "a.out" Libraries --------------------------------- stdio.h I/O string.h character strings ctype.h character types math.h numerical math functions stdlib.h C Standard General Utilities Library (ex atof(), malloc(), NULL, rand(), exit(), etc.) Memory Allocation ********************************* 1) 2) A program's memory footprint: +--------------+ | Headers | +--------------+ | | | Heap | dynamically allocated memory | | +--------------+ | | grows down | | v | | ^ | | grows up | | +--------------+ | | | Stack | "normal" variables & function calls | | +--------------+ malloc() ~~~~~~~~~~~~~~~~~~~~~~ #include Function prototype: void* malloc( size_t size ); Lifetime of the block is until the memory is freed, with free(). free() ~~~~~~~~~~~~~~~~~~~~~~ #include Function prototype: void free( void *ptr ); Memory leak – Example: memoryAllocationExample.c (or memoryAllocationExample.c.html) Other function prototypes in stdlib.h: void* calloc( size_t n, size elementSize); // allocates memory and initializes it to 0 void* realloc( void* ptr, size_t size); // Returns pointer to larger or smaller memory block of size bytes 20180906 ******************************************************* Exercise: Add code as directed by the comments to pointersExercise.c and execute to see values update: pointersExercise-02.c Control structures --------------------------------- grouping: {...} Same as Java if statements ---------------------- Same as Java Syntax: if( condition1 ){ statements1 } else if( condition2 ){ statements2 } else if( condition3 ){ statements3 }else{ statementsN } Be careful when omitting { }s: Example: ifExample.c (or ifExample.c.html) #include int main(){ int x = 7, y = 42; if( x > 0 ) printf("x > 0!\n"); if( y > 0 ) printf("x and y > 0!"); return 0; } switch Statements ---------------------- Syntax: switch( expression ){ case const1: statements1; break; case const2: statements2; break; ... default: statementsN; // optional } Loops ---------------------- while( condition ){ ... } Loop body executes 0 or more times, while condition is != 0 do{ ... } while( condition ); Loop body executes 1 or more times, while condition is != 0 for( init; condition; update){ ... } init is executed once Loop body executes 0 or more times, while condition is != 0 update is executed after every loop body Beware: int n = 0; if( n = 42 ){ printf("Something is very, very wrong\n"); } Structured data objects ********************************* structs ~~~~~~~~~~~~~~~~~~~~~~ A developer-defined collection of other data types Access members of struct using the member of operator "." Syntax: structVarible.field Example: structsExample1.c (or structsExample1.c.html) Example: structsExample2.c (or structsExample2.c.html) Example: structsExample3.c (or structsExample3.c.html) Example with pointers: structsAndPointersExample.c (or structsAndPointersExample.c.html) Functions ********************************* Function Prototypes ~~~~~~~~~~~~~~~~~~~~~~ A function prototype specifies the return type, name and argument list A prototype is needed if a call to the function appears before the definition of the function Often found in header (.h) files We can pass arguments to functions 1) By value (e.g., int, double) 2) By reference (e.g., int*, double*) We can return values from functions 1) By value (e.g., int, double) 2) By reference (e.g., int*, double*) const arguments ----------- Indicates argument can't be changed Meaningful with pointers Example: void exFunc( const char* str, const int x) { printf("x = %d\n", x); str[5] = "!"; // error: read-only variable is not assignable } Note: C does NOT support overloading functions (although C++ does) Example: overloadedFunctions.c Programs with multiple files ~~~~~~~~~~~~~~~~~~~~~~ main.c solutions.h solutions.c I/O ================================= Formatted strings: Example: printf("%d", age); c - character d - integer f - floating-point number (float) s - C-style string p - pointer (hexadecimal) ld - long int lf - long floating-point number (double) printf() - display to stdout (defaults to the terminal) scanf() - read from stdin (defaults to the keyboard) Example: ----------- madlibs-main.c madlibs.h madlibs.c 20180911 ******************************************************* Other library functions: ----------- sscanf() - scans a C-style string (instead of stdin) asprintf() - formats a string (and allocates just enough memory for it) File I/O ================================= The stdio library (stdio.h) has types and functions for file streams File stream type: FILE* Input files: fopen() fgets() of fscanf() or getline() fclose() Output files: fopen() fprintf() fclose() Example: fileIOExample.c scanf Example: processStockData.c