DEV Community

Emilie Ma
Emilie Ma

Posted on • Edited on • Originally published at kewbish.github.io

CS50 Week 2 - Arrays in C

This post is edited from my original blog post. Find it, and other posts by me on kewbish.github.io/blog.

Introduction

And now, our third week of CS50! This week, we went over arrays, but also spent a lot of time on CLI / terminal tooling, and the various debugging tools used by CS50. I'm starting to get more familiar with the CS50 system, and how I can do problem sets and debug on my local system, instead of the cloud IDE, which I don't really like. This was our introduction to proper command line arguments, and how to use function arguments in main too.

Skip to my thoughts.

Notes

  • The lecture itself spends a bunch of time going through CLI information
    • check50, debug50, style50 - the whole CS50 family
    • set up check50 and style50 on my local system already through pip, easy install
    • don't think I've ever used help50. Stack Overflow is more useful, I find.
  • How does C work? Four-step process
    • first, preprocessed to pull in headers
    • compiled to assembly code
    • then assembly transformed to binary
    • linked to final executable file
    • all happens when you run clang or the processor
  • data fits into types
    • each has a finite set amount of memory, except strings
    • bool -> 1 byte
    • char -> 1
    • int or float -> 4
    • double or long -> 8
    • string -> ?, because the number of chars in the string varies, and therefore can change the amount of memory assigned
    • each variable is labelled in memory with an address
  • when you define with a const, its value never changes
  • string -> represented as an array of characters
    • ends with a null term byte -> \0
    • escaped with the \
    • is this why you use < strlen instead of <= strlen, so you don't catch the ending byte?
    • string memory used = (# of char) * 1 byte + 1 byte for null terminating byte
  • ASCII chars can be subtracted and added from each other
    • their # code and their character equivalent can be used interchangeably
    • kind of unintuitive to subtract chars, I prefer numbers
  • ctype.h has useful functions
    • checks for alphabetic, digits, and most other useful types
    • equivalent of typeof in Python, helps verify what form the data is in
  • Use *argv when using strlen to make the actual 'string' array
    • Otherwise, can't use strlen, and there's a segfault
  • For encryption problem sets, I prefer using # codes
    • unfamiliar but more intuitive to do 'distance-from' work and modulo math
    • most of the psets involve finding a distance from 'a' or 'A', adding a key in some way, and looping back at times
    • to loop back from an alphabet, use modmath! (% 26)
    • try to use pseudocode values in subtraction equation
  • Return codes exist, why they have int main
    • returns either 0, 1, etc.
    • 1 -> indicate error
    • 0 -> everything's fine
  • argc -> make sure that the array count is greater than a certain amount
    • if you try to access something that doesn't exist in memory yet, it will throw a dreaded Segmentation Fault
  • generally, structure validation functions above the main function
    • otherwise, define the prototype function, and put it below the main function

Problem Sets

Last week, I mentioned how I prefer doing both of the 'more and less' problems in the problem set for a week, noting that the 'more' usually builds off the 'less'. This week was a great example of that.

Readability is required for both variations, but Caesar and Substitution were both super fun. Caesar is, what you might think, a caesar cipher implementation. As well, Substitution implements a simple substitution cipher. While working through Caesar, I researched and found a bunch of information about character codes and validating command line arguments, as well as working with aforementioned character codes and CLI arguments. For example, I was super confused about a Segmentation Fault that was thrown while attempting Caesar (because I'd forgotten to check that the argument actually existed), and didn't run into the same issue with Substitution. As well, I learned that you could :gasp: subtract characters, instead of just using the character code. These two morsels of information were super helpful in solving Substitution. Both ciphers deal with some sort of 'distance from a and then add key' algorithm, and I found that figuring Caesar out let me work through Substitution so much more quickly.

Setting up CS50 locally

I've finally finished setting up CS50's development tools on my own system with WSL - since last week, I've been trying to tweak a couple commands and things to make everything just work.

Here's a small checklist of things that I'd recommend setting up, and some caveats.

  • install CS50.h from their site. I wouldn't recommend trying to curl things, just install from source. It's easier, especially if you're on WSL.
    • No need to set up environment variables - more on that later in the bash bit.
    • if you don't want to bother adding it to your C source folder, you can just put it somewhere convenient to relative path, and use #include "../cs50.h", for example
  • set up check50 through pip
    • It's literally just pip install check50.
  • do the same with submit50 and style50.
    • their installations are equally simple - pip install submit50 and pip install style50.
    • As they remind, do this through WSL. Having to switch between WSL and non-WSL command prompts is annoying, even in VSCode.
  • in the WSL .bashrc, add a function that has the following command:
cs50make() { clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow  "$1".c  -lcrypt -lcs50 -lm -o "$1"
} 
export -f cs50make
Enter fullscreen mode Exit fullscreen mode

which will let you run cs50make in terminal and run the equivalent make command, after you've sourced the file

See - it's not that hard. Even easier on Linux, probably. And now, you can CS50 in VSCode, and have beautiful syntax highlighting and snippets.

Conclusion

This week was a very nice introduction to more data types, and I'm starting to sense it getting a little more challenging. Hopefully, next week will be as interesting!

What are your thoughts on CS50 and C in general?

Top comments (0)