[-> Notes 02/26](02-26.md) --- # Large Programs - When programs are long - Need to split the file into several files - Need to compile them together - Example: - We have files: main.c, list.c, file.c - To compile: `gcc -o proj main.c list.c file.c` - Sharing global variables - Define types in a `.h` file - Declare global variables (do not initialize!) - extern in a .h file - Declare and initialize global variables - in one of the .c file (e.g., the main one) - Include the .h file in all the .c files which use any of the global variables: `#include "proj.h"` - Example: - in `link.h`, declare (do not initialize!) global variables - `extern NODE *head;` - In main.c, include link.h, and declare and initialize global variables ``` #include "link.h" NODE *head = (NODE *)NULL; ``` - In all the other .c files, just include link.h - `#include "link.h"` - Use `makefile` to automate the compilation process - Create a "makefile" file with instructions - Command `make` will parse the makefile file and execute the appropraite command - ` make proj1` - Example 1: ``` proj1: main1.c list1.c io1.c gcc -o proj1 main1.c list1.c io1.c ./proj1 filename ``` - Example 2: ``` proj2: main2.c list2.c thr2.c gcc -o proj2 main2.c list2.c thr2.c -lpthread ./proj2 filename1 filename2 ``` - The tab is important! (its the syntax) ## Development Tools - Unix/Linux - Environment and commands - Tools - learn to use these!! - vi - grep - gdb - makefile - shell script - Libraries - Math - String - Memory - Threads --- # Special Operators ## Condtional Operator - The conditional operator `?:` takes three operands - c ? r1 : r2 - The value of the expression using the conditional operator is the value of either its second or third operand, depending on the value of the first operand - Shorthand for: ``` if(c){ //result value is r1 } else{ //result value is r2 } ``` - Examples - In assignment: `x = (a < b) ? a : b;` - x will be assigned the smallest value between a and b - Very useful for macros - Examples: - `#define MAX(a,b) (((a) > (b)) ? (a) : (b))` - returns the max between the paramaters assigned to a and b - `define ISLETTER(c) (((c) >= 'A' && (c) <= 'z') ? 1 : 0)` - returns 1 if the value of assigned to c is a letter and returns 0 if not ## Sequential Evaluation - The comma operator - Evaluates its two operands in sequence, yeilding the value of the second operand as the value of the expression - The value of the first is discarded - Example: - In assignments: `x = (i += 2, a[i]);` -> `i += 2; x = a[i];` - Parenthesis are important because precedence ## Bitwise Operators - Positive integers are represented in the computer by standard binary numbers - Examples: ``` short n = 13; //in memory - 0000 0000 0000 1101 //2^0 + 2^2 + 2^3 = 13 char c = 5; //in memory - 0000 0101 //2^0 + 2^2 = 5 ``` - Bitwise operators - take operands of any integer type - char, short, int, long - but treat an operand as a collection of bits rather than a single number ### Bitwise Negation - Bitwise negation - Operand: `~` - Application of `~` to an integer produces a value in which each bit of the operand has been replaced by its negation - 0 -> 1 - 1 -> 0 - Example: - ` n = 0000 0000 0000 1101` - `~n = 1111 1111 1111 0010` ### Bitwise Shift - Shift operators - shift left: `<<` - shift right: `>>` - Take two integers operands - The value on the left is the number to be shifted - Viewed as a collection of bits that can move - To avoid implementation problems, avoid negative numbers when shifting right - The value on the right is a nonnegative number telling how far to move the bits - Operand - `<<` shifts bits left - `>>` shifts bits right - The bits that "fall off the end" are lost - The "emptied" positions are filled with zeros - Examples: ``` int n; // n is 0000 0000 0000 1101 n << 1 //now n is 0000 0000 0001 1010 n << 4 //now n is 0000 0000 1101 0000 n >> 3 //now n is 0000 0000 0000 0001 ``` - Compound assignment operators `<<=` and `>>=` - cause the value resulting from the shift to be stored in the variable supplied as the left operand ### Bitwise AND, XOR, and OR - The bitwise operators `&` (and), `^` (xor), and `|` (or) - Take two operands that are viewed as strings of bits - The operator determines each bit of the result by considering corresponding bits of each operand - For each bit: - `r = n & m` -> 1 when both n and m are 1 - `r = n | m` -> 1 when n and/or m is 1 - `r = n ^ m` -> 1 when n and m do not match - Example: ``` n = 0000 0000 0000 1101 m = 0000 0000 0011 1100 m & n = 0000 0000 0000 1100 n = 0000 0000 0000 1101 m = 0000 0000 0011 1100 m | n = 0000 0000 0011 1101 n = 0000 0000 0000 1101 m = 0000 0000 0011 1100 m ^ n = 0000 0000 0011 0001 ``` - Compound assignment operators `&=`, `|=`, `^=` - cause the resulting value to be stored in the variable supplied as the left operand --- - Notes on shifting - `<<` by 1 is the same as multiplying by 2 - `>>` by 1 is the same as dividing by 2 - Notes on `~` and `!` - `~` and `!` are different operators - `~` is a bitwise operator - each bit is reversed - `!` is a logical complement or negation - `!nonzero` -> false (zero) - `!zero` -> true (one) - Notes on AND - `x & 0` is always 0 - `x & 1` is always x - Notes on OR - `x | 1` is always 1 - `x | 0` is always x - Masks -- Used to change specific bits in an integer - To set specific bits - Use OR with a mask in which only the bits to be set have 1: ``` short c = 0000 0101 short mask = 0000 0010 c | mask = 0000 0111 ``` - To zero specific bits - Use AND with a mask in which only the bits to be zeroed have 0 ``` short c = 0000 0101 short mask = 1111 1110 c & mask = 0000 0100 ``` - To verify specific bit - Use AND with a mask in which only the bit to be verified is 1 - Result == 0 implied that bit == 0 - Result != 0 implies that bit == 1 ``` short c = 0000 0101 short mask = 0000 0100 c & mask = 0000 0100 //not zero ==> bit is not zero ``` - Notes on XOR - x ^ 0 is always x - x ^ 1 is always ~x - x ^ x is always 0 - x ^ ~x is always 1 - x ^ y == z, then - x == z ^ y and y == z ^ x