CSc 352: Lecture-20

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