I’m back with another update on my coding adventure through Harvard’s CS50x course! After surviving the introduction to computer science concepts in Week 0, I’ve tackled Week 1 (though interestingly, Harvard starts counting from zero, so it’s the second week – a programmer’s quirk I’m quickly learning to appreciate).
This week marked my first encounter with C programming, a language that brings you back to the fundamental building blocks of modern software development.
Let me describe what I’ve learned, the obstacles I’ve overcome, and how this experience is reshaping my understanding of computer science.

Visual Studio Code Web Experience
One of this week’s highlights was finally diving into Visual Studio Code’s web version. Despite having the desktop application installed on my computer for quite some time, I’d never fully utilized it until now. The web interface has been a revelation.
The online version mirrors the desktop experience with remarkable fidelity. The familiar layout—file explorer on the left, editor in the center, and terminal at the bottom—made the transition seamless. All the essential features—syntax highlighting, code completion, and integrated terminal—work just as smoothly online as they do in the desktop version.
The integration with GitHub makes sharing code and tracking changes straightforward – a perfect tool for teaching version control alongside programming fundamentals. As someone passionate about educational technology, I can immediately see how this has transformed this Harvard course.
Learning C Programming Fundamentals
After setting up my coding environment, it was time to write my first program in C. The classic “Hello, world!” program served as my initiation rite into this new language. While seemingly simple—just a few lines to display text on the screen—it was my first exposure to C’s syntax, compiler requirements, and the famous printf
function.
This deceptively simple program introduced key concepts such as header “include” files declarations and the main function that serves as the program’s entry point
From there, I dove into the fundamental building blocks of programming in C:
Variables
Unlike Scratch’s visual variable blocks, C required me to explicitly declare variable types before using them. Learning about integers (int
), floating-point numbers (float
and double
), characters (char
), and booleans was like organizing different types of data into carefully labeled containers. Each variable type has its own memory requirements and limitations—a concept that becomes critically important in C.
Operators
C’s rich set of operators includes the usual arithmetic suspects (+
, -
, *
, /
), but also introduced me to modulo (%
) for finding remainders, increment/decrement operators (++
, --
), and various assignment operators (+=
, -=
, etc.). Learning how these operators work with different data types revealed surprising behaviors, especially with integer division.
Conditionals
Building decision points into programs using if
, else if
, and else
statements formed the backbone of program logic. The syntax was straightforward, but I found myself carefully tracking curly braces to avoid unexpected bugs.
Loops
Implementing repetition with for
, while
, and do-while
loops was particularly satisfying. Each loop type has its own strengths and use cases:
for
loops excel when I know exactly how many iterations I needwhile
loops shine when the exit condition depends on external factorsdo-while
loops became my go-to for input validation, ensuring code executes at least once before checking conditions
The do-while
loops proved especially valuable in the weekly exercises, as they allowed me to create cleaner input validation routines:
This pattern ensured users would be repeatedly prompted until they provided valid input—a common requirement in interactive programs.
Functions
Creating modular, reusable blocks of code through functions brought structure to my programs. Learning about function declarations, parameters, return types, and scope helped me break down complex problems into manageable pieces—an essential skill for larger projects.
Problem Sets Deep Dive
The CS50x problem sets are where theory transforms into practice, and Week 1’s challenges pushed me to apply my newfound knowledge in increasingly complex scenarios. These weren’t the kind of exercises where you regurgitate examples from class—they required genuine problem-solving creativity.
The Mario Challenge
This problem asked me to create a simple text-based visualization of the pyramids from Super Mario Bros using hash symbols (#). Sounds straightforward, right? It wasn’t.
The easy version required creating a right-aligned pyramid of a user-specified height:
#
##
###
####
#####
My first instinct was to generate a block of hash symbols with equal rows and columns. This worked fine for creating a square of symbols, but creating the pyramid alignment was where I hit my first major roadblock. I needed to understand how to:
- Generate the correct number of spaces before each row of hashes
- Incrementally increase the number of hashes on each line
- Properly handle the relationship between the user’s height input and the loop counters
After considerable experimentation, I arrived at a nested loop solution that handled both the spaces and hashes separately.
Just when I thought I had mastered the challenge, the “hard” version threw me another curveball: creating adjacent pyramids with a gap between them, like this:
# #
## ##
### ###
#### ####
##### #####
The solution wasn’t dramatically more complex, but it required me to break down the problem differently, adding another layer to my nested loops and carefully tracking the spatial relationships.
Cash Problem
The “Cash” problem was a welcome change of pace—a practical application of programming to calculate the minimum number of coins needed to make change. This problem was more algorithmic, requiring me to:
- Get a valid input amount from the user (in dollars)
- Convert it to cents to avoid floating-point imprecision
- Greedily calculate the number of quarters, dimes, nickels, and pennies needed
The do-while
loop proved essential here for ensuring valid user input.
Though not conceptually difficult, this problem taught me a valuable lesson about the practical challenges of financial programming.
Credit Card Validation Challenge
The “Credit” problem represented the week’s pinnacle challenge—implementing Luhn’s algorithm to validate credit card numbers and identify their issuer (Visa, MasterCard, or American Express).
This multi-step process required:
- Checking the card number length
- Validating the starting digits for different card types
- Implementing the checksum algorithm (multiply every other digit by 2, sum all digits, check if divisible by 10)
What seemed straightforward in theory became remarkably complex in implementation. I found myself struggling with how to:
- Extract individual digits from a long number
- Process digits in reverse order
- Handle the different card validation rules
My solution was significantly longer than expected—a sprawling mass of conditionals and calculations that would make any code reviewer wince. But it worked! Every test case passed, and I earned full marks.
Surely, I could have used more loops instead of repetitive conditions, employed mathematical operations more effectively to extract digits, and structured my validation logic more clearly. But this realization itself is part of the learning process—recognizing that working code is just the first step toward good code.
Conclusion
This week’s journey into C programming fundamentals has been challenging and rewarding. I’ve transitioned from the visual blocks of Scratch to the text-based power of C, gaining a deeper appreciation for how computers process our instructions at a more fundamental level.
Key Takeaways
The most valuable lesson I’ve learned isn’t about specific syntax or algorithms—it’s about the problem-solving mindset that programming develops. Breaking down complex challenges into logical steps, identifying patterns, and methodically debugging are skills beyond coding. I’ve also gained a new appreciation for the educational potential of these challenges; they create precisely the kind of productive struggle that fosters genuine learning.
Looking Ahead
As I progress in CS50x, I’ll explore arrays, algorithms, memory management, and data structures more deeply. These concepts will build upon the foundation established in Week 1, gradually expanding my toolkit for solving increasingly complex problems. I’m particularly intrigued by how these low-level concepts in C will eventually connect to the higher-level languages and web technologies introduced later in the course.
I’m also excited to explore how these programming concepts could be adapted and introduced in K-12 education, perhaps finding ways to bring the algorithmic thinking and problem-solving aspects into earlier grades without the syntax barriers.
Join the Conversation
Have you experimented with teaching programming concepts in your classroom or school? What challenges have you encountered when introducing students to text-based programming languages after block-based environments like Scratch? I’d love to hear about your experiences and exchange ideas on integrating computer science concepts across different subject areas.
Bye!