CISC-2000-E01 Midterm Review

  1. Binary numbers.
    1. Binary and hexadecimal.
      1. 2025 = 0x07E9
      2. A memory address is conventionally writen in hexadecimal on our machine storm.cis.fordham.edu. address.C.
        The value of i is 10
        The address of i is 0x7fff2757276c
        The number of bytes in i is 4
        
      3. HTML rgb (red/green/blue) color codes can be written as three hexadecimal numbers.
        red is FF 00 00
        orange is FF 80 00 (a mixture of red and some green)
        yellow is FF FF 00 (a mixture of red and lots of green)
        green is 00 FF 00
        blue is 00 00 FF
      4. Use hexadecimal for the ASCII code numbers for characters (uppercase vs. lowercase).
        The code number for the character 'A' is hexadecimal 41.
        The code number for the character 'B' is hexadecimal 42.
        The code number for the character 'C' is hexadecimal 43.
        The code number for the character 'a' is hexadecimal 61.
    2. Binary operators: turn individual bits on and off.
      1. | (“bitwise or”): turn on a selected bit.
        tolower.C.
          0101
        | 0011
          0111
        
        	int i {0x5};    //00000000000000000000000000000101
        	int j {0x3};    //00000000000000000000000000000011
        	int k {i | j};  //00000000000000000000000000000111
        
      2. & (“bitwise and”): turn off a selected bit.
        toupper.C, binary.C also uses right shift >>.
          0101
        & 0011
          0001
        
        	int i {0x5};    //00000000000000000000000000000101
        	int j {0x3};    //00000000000000000000000000000011
        	int k {i & j};  //00000000000000000000000000000001
        
      3. ^ (“bitwise exclusive or”): see if two bits are different.
        logical.C increments a three-bit integer; see the simple machine on page 11.
          0101
        ^ 0011
          0110
        
        	int i {0x5};    //00000000000000000000000000000101
        	int j {0x3};    //00000000000000000000000000000011
        	int k {i ^ j};  //00000000000000000000000000000110
        
  2. Pointers.
    1. Store the address of a variable into a certain type of pointer variable. pointerint.C, pointerdouble.C.
    2. Use the * (star) operator to dereference a pointer. dereferenceint.C, dereferencedouble.C.
    3. Use the [ ] (subscript) operator to dereference a pointer to an element in an array. neighborint.C, neighbordouble.C, uniq.C.
    4. Use the -> (arrow) operator to dereference a pointer to a structure or a pointer to an object. struct.C, obj.C. They invented the -> because * has lower precedence than . (the dot operator).
    5. Pointer addition. Assume we have a pointer to an element in an array. When you add an integer to the pointer, the integer is automatically multiplied by the number of bytes in the element that the pointer points t. This gives you the address of another element in the array. pointeraddition.C.
    6. Pointer subtraction. Assume we have two pointers to elements in the same array. Their difference is measured in elements, not in bytes. pointersubtraction.C.
    7. Use a pointer as an argument to a function.
    8. Two ways to make a pointer const.
  3. Throwing and catching exceptions.
    1. Don’t catch the exception. throw1.C
      Exit status 136 = 128 + 8, and the 8 stands for the abort signal SIGABRT.
      Floating point exception (core dumped)
      echo $?
      136
      
    2. Catch the exception in the same function where it was thrown. throw2.C
      Attempted division by zero.
      echo $?
      1
      
    3. Catch the exception in a different function. throw3.C
    4. An exception that gets thrown automatically. You don’t have to say throw. throw4.C
      An exception was thrown, carrying bad news:
      vector::_M_range_check: __n (which is 4) >= this->size() (which is 4)
      echo $?
      1
      
  4. Dynamic memory allocation.
    1. When you don’t know in advance (i.e., when you’re writing the program) how many array elements you will need. new1.C (looping with an int i), new2.C (looping with a pointer q), new3.C (with bad_alloc).
    2. Easier to use an object of class vector<int>. vector.C. Insert capacity to see the down side of this.
    3. When you don’t know in advance (i.e., when you’re writing the program) how many variables you will need, or what order they should die in. single1.C.
    4. Easier to use an object of class list<int>. list.C. Simpler example.

  5. Classes. Most important ideas:
    1. An object has better security than a struct, because
      1. can’t be born holding garbage: a constructor is unavoidably called at the moment of the object’s birth.
      2. Well-defined list of suspect fuctions if garbage later appears in a private data memeber.
    2. Simpler notation for a function that receives as its argument a pointer to an object. That notation is no notation at all: the pointer is invisible.
    3. Static data members: the length data member of class date See the two candidates in jsr1’s height.h, height.C, main.C.
    4. Header file (.h file) for a class and its #preprocessor directives, implementation file (.C file) for the class, other files contain the rest of the program.
    5. Member function vs. friend vs. neither.
      1. A function that uses the private members of one object should be a member function of the class of that object.
      2. A function that uses the private members of two or more objects of the same class should be a friend function of that class.
      3. A function that does not use the private members of a class does not need to be a member function ir friend of that class.
    6. When you have a big object containing smaller objects as its data members, the constructors for the data members are called before the constructor for the big object, and the destructors for the data members are called after the destructor for the big object. This ensures that there is never an instant of time when the big object is hollow (i.e., when the big object does not have fully constructed data members inside of it). The big object comes into existence (i.e., gets constructed) only after its data members have been constructed, and the big object goes out of existance (i.e., gets destructed) before its data members get destructed.
    7. If the constructor for the big object needs to begin by passing arguments to the constructors for the little objects inside of it, do this on the line that starts with a colon. In other words, the data members (i.e., the little objects) should be initialized rather than assigned to.
    8. An object constructed within any pair of {curly baces} (for example, within the {curly baces} of the main function) gets destructed when the computer reaches the closing curly brace. This ensures that objects are destructed in “last hired, first fired” order: the first object to be born will by default be the last to die, like Methuselah in announcer.h, announcer.C, main.C. If you want a different order, each object should be placed in its own block of dynamically allocated memory.