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
xtwo positions left.Mathematical Equivalent: Multiplying by 4.
Example:
x << 2;
Right Shift (>>):
Shift bits of
xthree 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
xto be positiveB) 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:
Take the magnitude of the number.
Invert all bits (one's-complement).
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
11010110expressed 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