CS 212 - Computer Science III

CS 212 - Computer Science III Notes

Course Information

  • Institution: University of Oregon

  • Date: October 14, 2025

  • Course Code: CS 212 - Computer Science III

Announcements

  • Quiz 6: Due Tuesday @ 10 AM

  • Project 2B: Due Friday

  • Project 2C: Due Monday

Outline of Topics

  • Negative Numbers

  • More Pointers

  • Scope

Pointers

  • Definition and Analogy:

    • Pointers can be compared to a feeling of falling asleep, where one imagines walking and suddenly jolts awake, which is metaphorically similar to experiencing a segmentation fault (segfault).

    • Segfault Advice: "Double-check your damn pointers!"

Bitwise Operators

  • Definitions of Bitwise Operators:

    • & : Bitwise AND

    • | : Bitwise OR

    • ^ : Bitwise XOR

    • << : Left Shift

    • >> : Right Shift

    • ~ : One's complement (unary)

Review of Boolean Logic

A

B

~A

A & B

A

B

A ^ B

0

0

1

0

0

0

0

0

1

0

0

0

1

1

1

0

0

0

1

0

1

1

1

0

1

1

1

0

AND Operator

  • Functionality: Turns bits off (masking).

  • Example Usage:

    • Given: n = n & 0x7F;

    • Explanation: This operation retains the last seven bits and turns off all others; bitwise AND results in true only if both compared bits are true (1).

Generate a Mask

  • Example Code:

    • ```
      bittoturnoff = 0x20; // 0010 0000 mask = ~bittoturnoff; // 1101 1111
      n = n & mask;

- **Explanation:** A bitwise negation operator is used to create a mask that allows disabling specific bits.  

## OR Operator
- **Functionality:** Used to turn bits ON.  
- **Example Usage:**  
  - ```
  flag_read = 0x04; // 0100  
  flag_write = 0x02; // 0010  
  flag_execute = 0x01; // 0001  
  perms1 = perms1 | flag_write;  
  perms2 = flag_read | flag_execute;  

Bit Shifting

  • Left Shift (<<):

    • Shift bits of x two positions left.

    • Mathematical Equivalent: Multiplying by 4.

    • Example: x << 2;

  • Right Shift (>>):

    • Shift bits of x three positions right.

    • Mathematical Equivalent: Dividing by 8.

    • Right Shift Behavior:

    • Left shift fills with 0 bits.

    • Right shift of unsigned variable fills with 0 bits.

    • Right shift of signed variable fills with the sign bit.

Bit Manipulation Example

  • Question: What does the following do?

    • x = ((x >> 2) << 2);

    • A) Changes x to be positive

    • B) Sets the least significant two bits to 0

    • C) Sets the most significant two bits to 0

    • D) Gives an integer underflow error

    • E) I don't know.

Internal Data Representation

  • Logical Storage in Binary:

    • Example: Assuming a 32-bit word, unsigned values are represented as follows:

    • 00000000 00000000 00000000 00000000 = 0

    • 00000000 00000000 00000000 00000001 = 1

    • 11111111 11111111 11111111 11111111 = $2^{32} - 1$

Negative Numbers Representation

  • Storage Method: Typically using two's-complement:

    1. Take the magnitude of the number.

    2. Invert all bits (one's-complement).

    3. Add 1 (two's-complement).

  • Conversion Back: Uses the same operations.

  • Most Significant Bit (MSB): Indicates the sign (1 = negative).

Signed Numbers in Two's Complement

  • Example Binary Values:

    • 10000000 00000000 00000000 00000000 = -2^{31}

    • 10000000 00000000 00000000 00000001 = -2^{31} + 1

    • 00000000 00000000 00000000 00000000 = 0

    • 01111111 11111111 11111111 11111111 = 2^{31} - 1

Conversion Example

  • Question: Assuming 8-bit two's complement numbers, what is the value of 11010110 expressed in base 10?

    • Options:

    • A) -40

    • B) -41

    • C) -42

    • D) 214

    • E) I don't know

Function Definition

  • Function Characteristics:

    • Similar structure to Java.

    • Exist from mention to EOF.

    • Implicit declaration; use function prototypes.

    • Parameter names are not required.

    • No Parameters Indicator: Use void.

    • Declaration Location: Declare prototypes at top of the file or in a header file.

Header Files

  • Naming Convention: Typically named with a '.h' extension (e.g., stdio.h, limits.h, stdint.h).

  • Content Restrictions: Should contain no executable code.

  • Common Elements:

    • Function prototypes

    • Extern declarations

    • Typedef keywords

    • Inclusion Guards: Prevent multiple inclusion.

Example Header File: foobar.h

#ifndef FOOBAR_H
#define FOOBAR_H
int sample_func(int a, int b);
double other_func(double);
void no_ret_no_params(void);
#endif

Preprocessor Commands

  • Syntax Examples:

    • #define forever for(;;)

    • #define max(A,B) ((A)>(B)?(A):(B))

    • #define square(x) x * x

    • #define square(x) (x)*(x)

    • Conditional Compiling: #if, #else, #elif, #endif.

Macro Example

  • Example Code:

    • ```c
      #define max(A,B) ((A)>(B)?(A):(B))
      int x=5, y=4, z;
      z = max(x++, y);

- **Question:** What is the value of `x`, `y`, `z` after execution?  
  - A) x=5, y=4, z=5  
  - B) x=5, y=4, z=4  
  - C) x=6, y=4, z=5  
  - D) x=7, y=4, z=6  
  - E) I don't know  

## Built-In Macros
- **Definitions:**  
  - `__LINE__` - Line number of the source  
  - `__FILE__` - Current file name  
  - `__func__` - Function name (C99 standard)  
  - `__DATE__` - Compilation date  
  - `__TIME__` - Compilation time  

## Sample Debug Macros  
- **Debug Print Macro:**  
  - ```c
  #define dprint(expr) printf("**DEBUG: " #expr " = %d\n", expr);
  • Error Print Macro:

    • ```c
      #define derror printf("Internal error in %s: file %s, line %d\n", func, FILE, LINE);

## Memory Management Types
- **Stack:**  
  - Writable; Not executable.  
- **Dynamic Data (Heap):**  
  - Writable; Not executable.  
  - Managed automatically by the compiler.  
- **Static Data:**  
  - Writable; Not executable; initialized when the process starts.  
- **Literals:**  
  - Read-only; Not executable; initialized when the process starts.  
- **Instructions:**  
  - Read-only; Executable; initialized when the process starts.  

## Pointer Examples
- **Example Code:  

c
int x=1, y=2;
int z[10];
int *iptr;

iptr = &x; // Now have two ways to refer to this int
int y = *iptr; // Can get value using the pointer
*iptr = 0; // Can change the value it refers to
iptr = &z[0]; // iptr can point to any integer!
*iptr = *iptr + 10; // Increment
*iptr += 10;

y = *iptr + 2; // Value manipulation

## Pointer Type Examples
- **Code Snippet:**  

c
int *bptr;
bptr = iptr;
// vs.
*bptr || *iptr;

## Pointer Type Consideration
- **Pointer Types:**  
  - Pointers must correspond to a specific variable type.  
  - **Void Pointers:**  
    - Can hold any type but cannot be dereferenced directly.  
    - **Warning:** No type checking done on void assignments can lead to errors.  

## Call By Value vs. Call By Reference
- **Call by Value Example:**  

c
void swap(int a, int b) {
int tmp;
tmp = a;
a = b;
b = tmp;
}

- **Call by Reference Example:**  

c
void swap(int *a, int *b) {
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}

## Arrays and Pointers
- **Interaction Example:**  

c
int a[10];
int *ptr;
ptr = &a[0];
ptr = a; // Just fine!
a = ptr; // Invalid!

## Pointer Behavior Example
- **Question:** What is printed by the following code?  

c
int x = 5;
void foo(int *p) { p = &x; }
int main(void) {
int z = 3;
int *p = &z;
foo(p);
*p = 0;
printf("%d\n", z);
}

- **Options:**  
  - A) 0  
  - B) 3  
  - C) 5  
  - D) Undefined behavior  
  - E) Implementation-defined behavior 

## Pointer Arithmetic and Memory Positioning
- **Example Code:**  

c
int *iptr;
iptr = 0x10;
iptr = iptr + 2;
```

  • Snippet Explanation:

    • Logical Interpretation: Increments pointer by 2.

    • Actual Behavior: Moves 2 data type units ahead, based on the type size.

  • Example Behavior:

    • &a[0] equals &a[7] when applying pointer arithmetic.

    • a[3] is the same as *(ptr + 3);

    • a[0] is the same as *(ptr + 0).

Final Reminders

  • Quiz 6: Due Tuesday @ 10 AM

  • Project 2B: Due Friday

  • Project 2C: Due Monday