4.4 Computer Fundamentals & C/C++ Programming

Key Takeaways

  • Von Neumann architecture integrates CPU (ALU + Control Unit), Memory, and I/O connected via System Bus (Data, Address, Control lines).
  • Two's complement representation encodes signed n-bit integers in range [-2^{n-1}, 2^{n-1}-1], simplifying subtraction into addition A - B = A + (\sim B + 1).
  • Pointers store memory addresses; dereferencing operator * accesses pointed values, while address-of operator & retrieves variables' locations.
  • Bitwise operators (&, |, ^, ~, <<, >>) manipulate individual binary bits for register control, masking, and hardware driver interfacing.
  • Dynamic memory allocation using malloc() / free() in C and new / delete in C++ allocates heap memory requiring strict pointer cleanup to prevent memory leaks.
Last updated: July 2026

4.4 Computer Fundamentals & C/C++ Programming

1. Computer Organization & Data Representation

Computer fundamentals, machine architecture, and low-level programming form an essential component of the GEAS subject area in the PRC ECE Licensure Examination.

Von Neumann Computer Architecture

A traditional computer architecture comprises five core hardware functional units:

  1. Control Unit (CU): Fetches instructions from memory, decodes them, and directs data flow throughout the processor.
  2. Arithmetic Logic Unit (ALU): Performs arithmetic operations (addition, subtraction, multiplication) and logical operations (AND, OR, XOR, NOT).
  3. Main Memory (RAM): Stores volatile instructions and data currently in execution by the CPU.
  4. Input / Output (I/O) Interfaces: Manages communication with external hardware peripherals such as keyboards, displays, and sensors.
  5. System Bus: Interconnects functional components using three distinct signal buses:
    • Data Bus (Bidirectional): Carries actual data words between CPU, memory, and I/O devices.
    • Address Bus (Unidirectional): Carries memory address locations generated by the CPU to select specific memory cells.
    • Control Bus: Carries read/write enable signals, system clock pulses, reset lines, and hardware interrupt requests (IRQ).

Number Systems & Two's Complement Arithmetic

  • Hexadecimal to Binary Conversion: Each hexadecimal digit maps directly to 4 binary bits (a nibble).
    • Example: 0x3F = 0011 1111_2 = $63_{10}$.
  • Signed Two's Complement: To represent a negative integer $-N$ in an $n$-bit binary system:
    1. Write the $n$-bit binary representation of positive integer $N$.
    2. Invert all bits (One's Complement: ~N).
    3. Add 1 to the result (Two's Complement = ~N + 1).
  • Range for an $n$-bit signed two's complement integer: $-2^{n-1}$ to $+2^{n-1} - 1$. For an 8-bit integer, the range is $-128$ to $+127$.
Number SystemBaseDigits / SymbolsExample
BinaryBase 20, 110110101_2
OctalBase 80, 1, 2, 3, 4, 5, 6, 7265_8
DecimalBase 100, 1, 2, 3, 4, 5, 6, 7, 8, 9181_10
HexadecimalBase 160-9, A, B, C, D, E, F0xB5

2. Fundamental C/C++ Data Types & Control Structures

Primitive Data Types in C/C++ (Standard 32-bit/64-bit Architecture)

  • char: 1 byte (8 bits), signed range $-128$ to $+127$ or unsigned range $0$ to $255$.
  • short int: 2 bytes (16 bits), signed range $-32,768$ to $+32,767$.
  • int: 4 bytes (32 bits), signed range $-2,147,483,648$ to $+2,147,483,647$.
  • float: 4 bytes (32-bit IEEE 754 single precision float, ~7 decimal digits of precision).
  • double: 8 bytes (64-bit IEEE 754 double precision float, ~15 decimal digits of precision).

Control Structures & Conditional Execution

C/C++ provides standard decision-making and iteration constructs used extensively in engineering algorithms:

/* Example: Conditional branching and loop execution */
#include <stdio.h>

int main() {
    int sum = 0;
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            sum += i;
        }
    }
    printf("Sum of evens = %d\n", sum);
    return 0;
}

3. Pointers, Arrays & Dynamic Memory Allocation

Pointer Fundamentals

A pointer is a variable whose value is the physical memory address of another variable.

  • Address-of operator &: Retrieves the memory address location of a variable.
  • Dereference operator *: Accesses or modifies the value stored at the target memory address.
int var = 42;
int *ptr = &var;   /* ptr holds memory address of var */
*ptr = 99;         /* modifies var directly to 99 */

Array-Pointer Relationship & Indexing Mechanics

An array name acts as a constant pointer to its first element (arr == &arr[0]). Pointer arithmetic scales automatically by the byte size of the underlying data type:

Address of arr[i]=Base Address+i×sizeof(datatype)\text{Address of } \text{arr}[i] = \text{Base Address} + i \times \text{sizeof}(\text{datatype})

Dynamic Memory Allocation (Heap vs. Stack)

  • Stack Memory: Automatically managed local function scope memory. Fast access, limited capacity, freed upon function exit.
  • Heap Memory: Dynamically allocated during runtime using system calls for variable-size data structures:
    • C Functions: malloc(bytes), calloc(num, size), realloc(ptr, new_size), free(ptr).
    • C++ Operators: new and delete / delete[].
    • Memory Leak: Occurs when heap memory is allocated but never released via free() or delete prior to losing the pointer reference, leading to progressive exhaustion of system RAM.

4. Struct Alignment, Memory Padding & Packed Data Structures

In 32-bit and 64-bit microprocessors, memory access is optimized when multi-byte data types are aligned on memory addresses that are multiples of their size. Compilers automatically insert padding bytes inside structure definitions to ensure natural alignment.

Memory Alignment Mechanics

  • A 2-byte short is aligned on even addresses (multiples of 2).
  • A 4-byte int or float is aligned on addresses that are multiples of 4.
  • An 8-byte double or 64-bit pointer is aligned on addresses that are multiples of 8.
/* Unpacked structure example */
struct SensorData {
    char status;    /* 1 byte */
    /* 3 padding bytes inserted here by compiler */
    int value;      /* 4 bytes */
    char unit;      /* 1 byte */
    /* 3 padding bytes inserted here to align overall struct size to 12 bytes */
};  /* Total size = 12 bytes, even though payload is only 6 bytes */

Explicit Struct Packing in Embedded Communication

When transmitting binary telemetry frames over SPI, I2C, CAN bus, or Ethernet socket interfaces, byte alignment must match the network protocol specification exactly. Developers use compiler directives to eliminate padding bytes:

/* Packed structure for network frame header */
#pragma pack(push, 1)
struct TelemetryFrame {
    char header;    /* 1 byte */
    int  sensorId;  /* 4 bytes */
    short payload;  /* 2 bytes */
};  /* Total size = exactly 7 bytes with zero padding */
#pragma pack(pop)

5. Functions, Recursion, Stack Frames & Calling Conventions

Functions modularize C/C++ code. When a function is called, the runtime system constructs a stack frame (activation record) on top of the call stack.

Call Stack Mechanics

Each stack frame contains:

  1. Function Parameters: Passed by value (copy) or by reference (address pointer).
  2. Return Address: Memory address of the instruction immediately following the call instruction.
  3. Saved Frame Pointer: Previous frame pointer register value (such as EBP or RBP).
  4. Local Variables: Variables declared within the function scope.

Recursion vs. Iteration in Microcontrollers

A recursive function calls itself until reaching a base condition. In embedded systems with small RAM footprints (e.g., 2 KB to 32 KB SRAM), deep recursion poses a high risk of stack overflow, where the call stack expands downward into heap or global static memory, causing system crashes or unpredictable behavior.

/* Recursive factorial implementation */
long factorial(int n) {
    if (n <= 1) return 1; /* Base case */
    return n * factorial(n - 1); /* Recursive call creates new stack frame */
}

6. Hardware Interfacing, Bitwise Operations & Interrupt Handlers

In embedded microcontrollers (such as PIC, AVR, ARM Cortex-M), bitwise operators directly manipulate peripheral control registers mapped into the memory space.

Bitwise Operators in C/C++

  • & (Bitwise AND): Evaluates to 1 if both corresponding bits are 1.
  • | (Bitwise OR): Evaluates to 1 if either corresponding bit is 1.
  • ^ (Bitwise XOR): Evaluates to 1 if corresponding bits differ.
  • ~ (Bitwise NOT / One's Complement): Inverts all bits.
  • << (Left Shift): Shifts bits left by $N$ positions (equivalent to multiplying by $2^N$).
  • >> (Right Shift): Shifts bits right by $N$ positions (equivalent to dividing by $2^N$).

Common Register Manipulation Idioms

  1. Setting Bit $n$ (Set bit to 1):
    REG |= (1 << n);
    
  2. Clearing Bit $n$ (Clear bit to 0):
    REG &= ~(1 << n);
    
  3. Toggling Bit $n$ (Invert bit state):
    REG ^= (1 << n);
    
  4. Testing Bit $n$ (Check if bit is set):
    if (REG & (1 << n)) { /* Bit n is high */ }
    

The volatile Qualifier in Embedded C

The volatile keyword informs the C compiler that a variable's value may change at any time outside the immediate control of the executing code thread—such as by a hardware register updated asynchronously by an Analog-to-Digital Converter (ADC), a hardware timer interrupt, or a DMA channel.

Declaring a variable as volatile prevents the compiler from optimizing out repeated memory reads or caching the variable in a CPU register:

/* Hardware status register variable updated by ISR */
volatile unsigned char rxFlag = 0;

void UART_ISR(void) {
    rxFlag = 1; /* Set asynchronously by hardware interrupt */
}

void processIncomingData(void) {
    while (!rxFlag) {
        /* Wait for flag; without 'volatile', compiler might optimize into infinite loop */
    }
}
Loading diagram...
Computer Memory Hierarchy and Address Pointer Dereferencing Mechanics
Memory Access Latency Across the Hierarchy (Nanoseconds)
Test Your Knowledge

What is the 8-bit signed two's complement binary representation of the decimal integer -43?

A
B
C
D
Test Your Knowledge

Consider the following C snippet: int arr[] = {10, 20, 30, 40}; int *p = arr + 2; printf('%d', *p + 5); What is printed?

A
B
C
D
Test Your Knowledge

In microcontroller programming, which C expression correctly clears (sets to 0) bit position 3 of an 8-bit register variable named PORTB without modifying other bits?

A
B
C
D