← Back to Course
# C Programming Review ## CS 315 Computer Architecture --- ## Learning Objectives - Configure SSH key-based, passwordless access to course machines - Explain the difference between compiled (C) and interpreted (Python) languages - Compile and run a C program with `gcc` - Identify C's four core constructs: functions, data, statements, expressions - Use control-flow statements: `if`, `for`, `while`, `switch` - Explain static typing and list primitive C types with their sizes - Understand that strings are NUL-terminated `char` arrays --- ## Course Infrastructure | When | Where | Purpose | |------|-------|---------| | 10:00 – 10:30 am | CS Labs | Setup help | | 1:40 – 2:30 pm | HR 412A | Office hours | Two machines you will use: - **Stargate** — department gateway, reachable from the public internet - **BeagleV** — RISC-V boards where you compile and run code (reached *through* Stargate)
Lab 01 deadline extended to
Wednesday
. Autograder live by Tuesday.
--- ## SSH Key-Based Login SSH key pairs provide **passwordless** authentication: - **Private key** (`~/.ssh/id_ed25519`) — stays on your laptop, never shared - **Public key** (`~/.ssh/id_ed25519.pub`) — copied to the server's `authorized_keys`
flowchart LR subgraph Laptop["Laptop (~/.ssh)"] PRIV["id_ed25519 (private)"] PUB["id_ed25519.pub (public)"] end subgraph Stargate["Stargate (~/.ssh)"] AUTH["authorized_keys"] end PUB -- "scp / ssh-copy-id" --> AUTH PRIV -. "proves identity" .-> AUTH
--- ## Generating and Installing a Key ```bash # 1. Generate key pair on your laptop ssh-keygen -t ed25519 -C "you@dons.usfca.edu" # 2. Copy public key to Stargate ssh-copy-id you@stargate.cs.usfca.edu # Manual alternative: scp ~/.ssh/id_ed25519.pub you@stargate.cs.usfca.edu:~/ ssh you@stargate.cs.usfca.edu 'cat id_ed25519.pub >> ~/.ssh/authorized_keys' ```
SSH silently falls back to a password if permissions are too open — set them correctly!
--- ## SSH Permissions Matter ```bash chmod 700 ~/.ssh # directory: owner only chmod 600 ~/.ssh/id_ed25519 # private key: owner read/write chmod 644 ~/.ssh/id_ed25519.pub # public key: world-readable is fine chmod 600 ~/.ssh/authorized_keys # on the server side ``` --- ## SSH Config File `~/.ssh/config` gives short names to hosts and jumps through Stargate automatically: ```text Host stargate HostName stargate.cs.usfca.edu User you IdentityFile ~/.ssh/id_ed25519 Host beagle HostName beagle1.cs.usfca.edu User you IdentityFile ~/.ssh/id_ed25519 ProxyJump stargate # hop through Stargate in one step ForwardAgent yes # forward key so GitHub works on the board ``` Now `ssh beagle` connects in one step. --- ## C Is a Compiled Language Python: source is **interpreted** at run time. C: source is **compiled** ahead of time into a machine-code executable.
flowchart LR SRC["hello.c (source)"] -->|"gcc -o hello hello.c"| EXE["hello (executable)"] EXE -->|"./hello"| OUT["program output"]
```bash gcc -o hello hello.c ./hello ```
./
is required — the current directory is
not
on
PATH
by default.
--- ## Hello, World ```c #include
int main(void) { printf("Hello, World!\n"); return 0; } ``` - `#include
` — pulls in standard I/O declarations (preprocessor) - `int main(void)` — program entry point - `printf(...)` — print to stdout; `\n` is a newline - `return 0;` — reports success to the shell --- ## C's Four Core Constructs
flowchart TD C["C Constructs"] C --> F["Functions (code)"] C --> D["Data / Variables"] C --> S["Statements"] C --> E["Expressions"] D --> G["globals"] D --> ST["stack (local vars)"] D --> H["heap (malloc/free)"]
**All code lives inside functions** — no top-level statements like Python. --- ## Data: Three Storage Regions | Region | What lives there | Lifetime | |--------|-----------------|----------| | **Globals** | Variables declared outside functions | Whole program | | **Stack** | Local variables, parameters | While function is active | | **Heap** | `malloc`/`free` | Until you free it | ```text High addresses +---------------------+ | Stack | ← locals, grows downward | ↓ | | ↑ | | Heap | ← malloc/free +---------------------+ | Globals / Data | +---------------------+ | Code | +---------------------+ Low addresses ```
In this course we use globals and the stack. The heap (malloc/free) is not used.
--- ## Statements vs. Expressions - **Statement** — complete unit of execution, ends in `;` or `{ }` - **Expression** — evaluates to a value; usually part of a statement ```c x = 3; // statement (ends in ;) // "x = 3" is an expression that evaluates to 3 ``` Chained assignments work because assignment is an expression: ```c a = b = 0; // b=0 evaluates to 0, then a=0 ``` --- ## Control Flow: if and for ```c if (x > 0) { x = x - 1; } ``` ```c for (i = 0; i < 10; i++) { printf("i = %d\n", i); } ``` The `for` header: **init** `;` **condition** `;` **update** - `i = 0` — runs once before the loop - `i < 10` — tested before each iteration - `i++` — runs after each iteration --- ## Control Flow: while and switch ```c while (condition) { // repeat while condition is non-zero } ``` ```c switch (value) { case 1: /* ... */ break; // ← don't forget break! case 2: /* ... */ break; default: break; } ```
In C, any non-zero value is "true";
0
is "false".
--- ## Functions ```c int add_2(int x) { return x + 2; } ``` A function has three parts: | Part | Example | Role | |------|---------|------| | Return type | `int` | Type of the value returned | | Parameters | `int x` | Typed inputs, local to the body | | Body | `{ return x + 2; }` | Statements that execute | `void` functions return nothing and need no `return` statement. --- ## Calling a Function ```c #include
int add_2(int x) { return x + 2; } int main(void) { int result = add_2(40); // result == 42 printf("result = %d\n", result); return 0; } ``` --- ## Worked Example: Summing an Array ```c int sum(int a[], int n) { int total = 0; for (int i = 0; i < n; i++) { total = total + a[i]; } return total; } int main(void) { int nums[5] = {1, 2, 3, 4, 5}; printf("sum = %d\n", sum(nums, 5)); // 15 return 0; } ```
C does
not
store an array's length — you must pass
n
explicitly.
--- ## Static vs. Dynamic Typing **C is statically typed. Python is dynamically typed.** ```c int x = 3; x = "hello"; // compile error: incompatible types ``` ```python x = 3 x = "hello" # fine — type follows the value at run time ``` | | C (static) | Python (dynamic) | |--|-----------|-----------------| | Type checking | Compile time | Run time | | Type of `x` | Fixed forever | Can change |
Type determines
how many bytes
a variable occupies and
how those bytes are interpreted
.
--- ## Primitive Types | Type | Size | Holds | Example | |------|------|-------|---------| | `int` | 4 bytes | whole numbers | `-2, 0, 42` | | `char` | 1 byte | character / small integer | `'a'` | | `float` | 4 bytes | single-precision real | `3.14f` | | `double` | 8 bytes | double-precision real | `3.14` | ```c printf("int = %zu bytes\n", sizeof(int)); // 4 printf("char = %zu bytes\n", sizeof(char)); // 1 printf("float = %zu bytes\n", sizeof(float)); // 4 printf("double = %zu bytes\n", sizeof(double)); // 8 ``` Use `double` unless you have a specific reason for `float`. --- ## Arrays A fixed-size, contiguous block of elements of the **same type**: ```c int nums[5] = {1, 2, 3, 4, 5}; // indices 0..4 nums[0] = 10; // first element // nums[5] is out of bounds — undefined behavior! ``` - Size is **not** stored with the array - You are responsible for tracking it --- ## Strings Are Character Arrays
C has
no built-in string type
. A string is a
char
array terminated by a NUL byte (
'\0'
, value 0).
```c char str[] = "hello"; // compiler adds '\0' automatically ``` ```text index: 0 1 2 3 4 5 +----+----+----+----+----+----+ str: | h | e | l | l | o | \0 | +----+----+----+----+----+----+ ↑ NUL terminator (6 bytes total) ``` `strlen(str)` returns **5** — counts characters, not the NUL. --- ## Working with Strings ```c #include
#include
int main(void) { char str[] = "hello"; printf("%s\n", str); // hello printf("length = %zu\n", strlen(str)); // 5 printf("size = %zu\n", sizeof(str)); // 6 return 0; } ``` - `%s` — print until NUL - `strlen` — from `
`, counts characters (not NUL) - `sizeof` — total bytes including NUL
Forgetting the NUL, or writing past it, is a classic C bug studied later in this course.
--- ## Looking Ahead: Structs Groups several named fields of different types into one value: ```c struct point { int x; int y; }; struct point p = {3, 4}; printf("(%d, %d)\n", p.x, p.y); // (3, 4) ``` Structs let you model records and are essential for understanding memory layout. --- ## Looking Ahead: Pointers Variables that hold the **address** of another value: ```c int x = 42; int *p = &x; // p holds the address of x printf("%d\n", *p); // dereference: prints 42 *p = 7; // writes through the pointer printf("%d\n", x); // x is now 7 ``` Pointers are how C refers to memory directly — fundamental for the stack, heap, and assembly topics ahead. --- ## Key Concepts Reference | Concept | Key Point | |---------|-----------| | Compiled language | `gcc` → executable; run with `./` | | Four constructs | Functions, data, statements, expressions | | Storage regions | Globals, stack (locals), heap (malloc) | | Static typing | Types fixed at compile time | | `int` / `char` | 4 bytes / 1 byte | | String | NUL-terminated `char[]`; no built-in type | | SSH key pair | Private (laptop) + public (server) | --- ## Summary 1. **SSH key-based login** — private key on laptop, public key in `authorized_keys`; permissions must be correct 2. **C is compiled** — `gcc -o hello hello.c` then `./hello`; `./` needed because `.` is not on `PATH` 3. **Four C constructs** — functions, data/variables, statements, expressions 4. **Three data regions** — globals, stack (locals/params), heap (not used in this class) 5. **Static typing** — types fixed at compile time; type determines size and interpretation 6. **Primitive sizes** — `char` 1, `int` 4, `float` 4, `double` 8 bytes 7. **Strings** — NUL-terminated `char[]`; `"hello"` is 6 bytes, `strlen` returns 5 8. **Coming next** — structs and pointers, connecting C to RISC-V architecture