Welcome & Scratch Recap
- Scratch concepts (sprites, blocks) map directly to C constructs:
- Functions → reusable blocks of logic.
- Variables → named pieces of memory.
- Conditionals → decision-making (if/else).
- Loops → repetition (for/while).
- Computers ultimately interpret only machine code – patterns of 0 and 1.
- A compiler translates human-readable source code (e.g., C) into machine code.
Visual Studio Code (VS Code / cs50.dev)
- Cloud-hosted IDE pre-configured with:
- C compiler (Clang via make wrapper).
- CS50 Library & command-line tools.
- Three main UI regions:
- Explorer – browse files.
- Editor – write code.
- Terminal / CLI – run shell commands.
- Frequent shell commands:
- cd – change directory.
- ls – list files.
- cp, mv, rm, mkdir, rmdir – manipulate files/folders.
- Use cs50.dev for all coursework to avoid local setup headaches.
Hello World Workflow
- Write code:
code hello.c ➜ opens editor. - Compile:
make hello ➜ produces executable hello. - Run:
./hello ➜ outputs hello, world. - Minimal C program anatomy:
// A program that says hello to the world
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
}
#include <stdio.h> imports Standard I/O library so printf is known.\n is an escape character creating a newline.
\n – newline.\r – carriage return.\" – literal double quote.\' – literal single quote.\\ – literal backslash.
- Header file
<stdio.h> brings in declarations for I/O functions. - CS50’s training-wheels header
<cs50.h> adds helpers:get_char, get_double, get_float, get_int, get_long, get_string.
- Documentation: https://manual.cs50.io.
- Use cs50.h + placeholders:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string answer = get_string("What's your name? ");
printf("hello, %s\n", answer);
}
%s – format code for a string.answer is a variable; its type is string.
- Common primitives & their printf specifiers:
bool – %i (prints 0/1).char – %c.int – %i.long – %li.float / double – %f.string – %s.
Conditionals
if (x < y)
{
...
}
else
{
...
}
- Three-way branch with
else if chain – final else captures “everything else”.
Operators
- Arithmetic:
+, -, *, /, % (modulo). - Relational:
==, !=, <, <=, >, >=. - Logical:
&& (and), || (or), ! (not).
Variables & Shorthand
- Declaration + assignment:
int counter = 0;. - Increment patterns:
counter = counter + 1;counter += 1;counter++; (post-increment)
- Decrement:
counter--;.
Example compare.c – Integer Comparison
int x = get_int("What's x? ");
int y = get_int("What's y? ");
if (x < y)
printf("x is less than y\n");
else if (x > y)
printf("x is greater than y\n");
else
printf("x is equal to y\n");
- Demonstrates variables, input, conditionals, and relational operators.
Example agree.c – Char & Logical Operators
- Raw version checks
'y' or 'Y', 'n' or 'N' individually – verbose. - Optimised version uses logical OR:
if (c == 'Y' || c == 'y')
printf("Agreed.\n");
else if (c == 'N' || c == 'n')
printf("Not agreed.\n");
Loops (meow.c)
- Repetition without copy-paste:
- while loop counting down:
c
int i = 3;
while (i > 0)
{
printf("meow\n");
i--;
}
- while counting up from 0 (CS mindset counts from 0).
- for loop in one line:
c
for (int i = 0; i < 3; i++)
printf("meow\n");
- Infinite loop:
while (true) { ... } – abort with Ctrl-C.
Functions & Abstraction
- Declare prototype, define body, call inside
main. - No return, no parameters:
void meow(void);
...
void meow(void)
{
printf("meow\n");
}
void meow(int n);
...
void meow(int n)
{
for (int i = 0; i < n; i++)
printf("meow\n");
}
- Returning values (input validation):
int get_positive_int(void)
{
int n;
do
n = get_int("Number: ");
while (n < 1);
return n;
}
- check50 – automated correctness.
- design50 – evaluates design/structure.
- style50 – enforces style guide (indentation, naming, comments).
Mario Problem – Nested Loops & Constants
- Horizontal row of 4
? blocks: single for-loop. - Vertical column of 3 blocks: loop with newline each iteration.
- 3×3 grid: nested loops (row loop outer, column loop inner).
const int n = 3; – compile-time constant.- Helper function abstraction:
void print_row(int width) { ... }
- Begin with
//; explain intent, not just literal code. - Mandatory in CS50 submissions for readability & maintainability.
Calculator & Operator Nuances
int x = get_int("x: ");
int y = get_int("y: ");
printf("%i\n", x + y);
- Doubling money demo exposed integer overflow.
Data Type Limits
- Size constrained by bits allocated:
int (32-bit on CS50 sandbox): range 0 \text{ to } 2^{32}-1 = 4\,294\,967\,295 for unsigned, half signed.
- Overflow wraps around silently – can cause real-world failures.
- Use larger types (
long) when expecting bigger numbers.
Using long to Avoid Overflow
long dollars = 1;
while (true)
{
char c = get_char("Here's $%li. Double it? ", dollars);
if (c == 'y')
dollars *= 2;
else
break;
}
printf("Here's $%li.\n", dollars);
Truncation & Floating-Point Precision
- Dividing ints truncates fractional part:
7 / 4 → 1.- Use
float/double for real division.
- Example:
float x = get_float("x: ");
float y = get_float("y: ");
printf("%.50f\n", x / y);
- Even floats are imprecise (binary can’t exactly store some decimals); errors accumulate.
Summary of Key Takeaways
- Core building blocks from Scratch carry into C: variables, conditionals, loops, functions.
- Use VS Code (cs50.dev) → write (code), compile (make), run (
./prog). - Libraries extend functionality; header files & manual pages are your reference.
- Choose correct type to avoid overflow or truncation; know associated printf format codes.
- Always consider correctness, design, and style; leverage CS50’s automated tools.
- Comment liberally; abstract repeatedly; test rigorously.
- These principles underpin all future CS50 problem sets and real-world software engineering.