Unix System Interface/Bitwise Operators
Note: All the programs mentioned in this lecture are in:/home/cs352/SUMMER02/lecture20progs/
Unix System Interface - File Descriptors: - While discussing redirection in Unix we briefly talked about file descriptors. - A file descriptor is a nonnegative integer associated with a file. - standard input has file descriptor 0 standard output has file descriptor 1 standard error has file descriptor 2. - There are functions not provided by the standard libraries, but by the system to deal with the files using file desriptors. (Functions provided by the standard library using a pointer to FILE are automatically buffered, but for the ones provided by the system, using a file descriptor may require the user to provide the buffers.) see changecase.c - How to execute commands from within a C program. system(char *s); executes the command inside the string s. Ex: system("date"); causes the command date to execute which prints out the date and time. - Bitwise Operators: Operate on integral expr. as a string of binary digits. - Logical Operators: - (unary) bitwise complement (~) Inverts the bits of its argument, i.e., the 0's become 1's and vice versa. Ex: int a = 70707; The binary representation of a is: 00000000 00000001 00010100 00110011 of ~a is: 11111111 11111110 11101011 11001100 - Two's Complement -Take bit string representation of a, take its complement (i.e. ~a) and add 1 to it, then we get -a (on a two's complement machine, i.e. the integers are represented in two's complement.) -0 in two's complement: all bits 0. -1 in two's complement: all bits 1. Negative numbers have high bit 1. On a two's complement machine subtraction is in fact done through addition, to do a-b the machine does a+(-b), i.e. takes two's complement of b and adds to a. - Bitwise Logical Operators - bitwise and (&), bitwise exclusive or (^), bitwise or ( | ) Each one operates on their arguments bit by bit (hence bitwise operator) Semantics: a b a&b a^b a | b 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1 - Shifts: left shift (<<), right shift (>>) expr1 << expr2 causes the bit representation of expr1 to be shifted to the left by epr2 many bits. The empty bits on the low order-end are filled in with 0's. The type of the expression as a whole is that of its promoted left operand. expr1 >> expr2 similarly causes a right shift in expr1. However the difference is that: For unsigned types 0's are shifted at the high end, for the signed types what gets filled in at the high end is machine dependent. (Some machines shift in 0's some shift in sign bits.) So usually unsigned types are used when using bitwise operators. Ex: See bitwise.c - Masks - A constant or variable that is used to extract desired bits of from another variable or expression. If we want to find the value of a particular bit in an expression, we can use a mask that is 1 in that position and 0 elsewhere. Some useful masks: 1 and 0xff(255, which has lower order byte all 1's) Ex: see mask.c and bitrepr.c - Packing/Unpacking - Using bitwise expressions we can compress data across boundaries. Saves space/time. see pack.c - Multibyte characters : Ex: 'abc' will be packed into a single word. see bitrepr.c - Enumeration Types enum is used to name a set, creates a user-defined type. can aid in program clarity. Ex: enum day {sun, mon, tue, wed, thu, fri, sat}; creates the user-defined type enum day. The identifiers, sun, mon, ... are integer constants. By default the first is 0, the next is one bigger and so on. Now in order to declare variables a and b of this type: enum day a, b; /*Now a and b can only take values of the enum. type*/ see game.h, game.c