Lecture 2
This lecture is still a work-in-progress. Feel free to preview it, but note that major sections are still incomplete
Introduction to the terminal
The terminal is a text-based interface that allows us to interact with the computer's operating system.
Navigating the terminal at the end of the day is an essential skill for software engineers, which is why we'll be spending some time navigating the terminal and some basic commands.
Terminal apps
You have an array of choices when it comes to terminal emulators.
Some of the most popular options these days are the following:
If you're curious about what I'm using, it's a newer terminal emulator called cmux which
runs libghostty under the hood which is the same core terminal emulation engine that Ghostty uses.
Of course you're also free to just use your stock terminal which should be Terminal on macOS and Powershell in Windows.
Note that if you decide to use Powershell on Windows, you may have a different set of commands that you'll run. I'll do my best to provide the equivalent command, but you may have to use AI or Google to figure it out.
Windows Subsystem for Linux
Another option for Windows users who want an experience closer to UNIX systems is to use WSL (Windows Subsystem for Linux). This allows you to install a Linux distribution on your machine and run the commands that macOS users are using as well.
You can find more details here about this feature. Highly recommend it given how finnicky it can get to work with Windows!
Step-by-step tutorial
We'll approach learning the terminal by creating a directory called mth-4300/ at our home directory
Figuring out where you currently are in the terminal
Suppose that you've opened the terminal, most of the time you'll start at the home directory, but if you find yourself somewhere else, how do you figure out the path to your current directory?
What is in the current directory?
Now that you're in some directory, how do you know what files and directories are nested within your current directory? To get a list of files and directories you can use the following commands
We do have to note though that there are files that are typically hidden when using the above command. These hidden files typically start with a
.such as.gitignoreor.env.localIn order to force these to show up in the terminal, we have to run an alternative set of commands.
Navigating the file system with the terminal
In order to navigate to our home, we can use the following command
However, the
cdcommand is more powerful than that. We can use thecdcommand in order to jump to any directory as long as we know the path to to it.Suppose that we have the following directory structure:
Suppose that I wanted to jump to
textbooks. How would I do that?There are also relative paths we can take. Suppose now that I'm in
~/downloads/textbooksbut now I want to go up to just~/downloads/. To get up there, I would have to enter the following command into the terminalIf you wanted to go up several parent directories, then you'll have to do something like the following
Creating a directory and a file
Now that we're in a directory where we want to create out
mth-4300directory. How do we go about doing that?Now let's
cdinto that newly created directory and create atest.cppfile. To create this file, we'll need to run the following commands after wecdintomth-4300Copying files and directories
Suppose that you want to create a copy (not deleting the source) of a file or a directory. Let's say that we want to create a new file called
test2.cppfrom the content oftest.cppNow suppose that we have a directory called
project-template/and we want to create a new project calledtodo/.Moving/renaming files
Note that
cpduplicates the resource. If we want to make sure that we're moving the resource to a new location then we'll have to use themvcommandDeleting files and directories
To delete a file, we use the
rmcommand. Note that you should generally be careful what you're deleting because this could damage your operating system.For directories, you'll use the infamous
rm -rfcommand
It'll take time to become comfortable with the terminal, but it's a worthy investment!
Types in C++
Types
In Python, types are inferred from the value or are hinted.
For example, this was how we could initialize variable with and without types.
Modern C++ actually works in a similar manner! Except we don't consider typing a variable a hint. Providing the type is actually the default behavior
Note that the auto keyword allows us to infer the type from the right-hand value. These days, it's
considered a best practice to use the auto keyword especially if you're initializing the variable.
Declaration vs initialization
Something that wasn't prevalent in Python is the idea of declarations. In C++, you're allowed to declare a variable without assigning it a value.
Declarations are a way to reserve space for a variable without needing it to have a value right away.
The different ways we learn how to reserve or request space for data in C++ is part of the memory control that we're exposed to with the language. The distinction will become a lot more obvious in the future once we demystify the distinction between stack and heap allocations
Data types in C++
Numbers
When we were in Python, we had two types for numbers: int and float. Complexities around overflows and size of the number
were abstracted away into something that just works.
C++ uncovers this layer of abstraction for us by forcing us to choose the type for our number.
int
You would declare your variable to be an int if you wanted to store whole numbers. However, like I mentioned before, our choice of type is driven by how large of a number we expect to store in this variable.
When you choose to use an int, you are guaranteed that the int is at least 16 bits wide.
Different hardware and compilers can choose a larger size as long as it meets the minimum. You'll see that in practice,
| Platform | sizeof(int) |
|---|---|
| x86-64, ARM64 | 4 bytes (32 bits) |
| Old 16-bit embedded systems | 2 bytes (16 bits) |
| Some historical systems | 8 bytes (64 bits) |
In most cases, this means that int will have a size of 32 bits. So the range of values that fit within an int fall between
We also have something called an unsigned int which has the same size as int, but does not allow for negative numbers.
This means that the range of values it falls within actually doubles on the positive side. Therefore, the range of values
for an unsigned int within a 32-bit system is
long long / long long int
You would use long long if you wanted to store whole numbers that are at least 64 bits wide.
Because we know that it's at least 64 bits wide, then the range of values should fall from
There is also a long type, but because of its cross-platform behavior, it's recommended to use long long if we want
to guarantee at least 64 bits.
- By cross-platform behavior, I meant to say that Windows will have a different size for
longdepending on whether you're using a 32-bit or 64-bit system. MacOS and Linux both treatlongas something that's at least 64 bits wide.
float / double
If you need real numbers, then float and double are the types you'll need.
The difference between the two types is the amount of precision you have with the decimal places.
floathas about ~6-7 significant decimal digitsdoublehas about ~15-16 significant decimal digits
In most cases, you'll want to use double unless memory or performance is a hard constraint.