
Lesson Description
The "Introduction" Lesson is part of the full, C Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Richard Feldman begins the course by looking at the wide range of modern languages and technologies that rely on the C programming language. C was released in 1972 and is still one of today's most commonly used languages.
Transcript from the "Introduction" Lesson
[00:00:00]
>> Richard Feldman: All right, welcome to C Fundamentals. I'm Richard Feldman. Thanks for coming everybody. Yeah, we've got some here to get set up. This is just instructions for the exercises, so don't worry if you don't have that set up right now. You can totally follow along in the slides if you don't have this set up.
[00:00:13]
Hopefully every machine you're on, if you are using a macOS or Windows Subsystem for Linux or actual Linux, you should already have a C compiler on your machine. [LAUGH] So you won't need anything else to be able to do the exercises. So it shouldn't be much of a set up.
[00:00:26]
So, we're gonna go through a couple of different sections here. So the first is we're just gonna have a little introduction section right here. And in this section we're just gonna talk about what is C, why is C still popular today, and why is there no windows version for this course?
[00:00:41]
And finally, just a little bit of a course overview. So I'll start off by just answering the basic question, what is C? So C is one of the top 10 most popular programming languages today, right now in 2025, and this has been true for decades. It is not only a very popular language today, but it has been a very popular language for a very long time.
[00:00:59]
C was originally designed to build UNIX or for building the UNIX operating system. Today, there's a whole lot of spin offs of UNIX. So macOS is based on the BSD flavor of UNIX, as is iOS. Linux is its own flavor of UNIX that's separate from BSD, and actually, later on in the workshop, we're gonna see a relevant distinction between Linux and BSD when it comes to writing C code.
[00:01:21]
Android, also based on UNIX. Windows is not based on UNIX, but it is also written in C. Other things that are not operating systems that are written in C include PostgreSQL, MySQL, redis, probably every database you've ever used there's a very good chance that it was written in C.
[00:01:36]
Python, like programming languages, yeah, php, Ruby. This might surprise you that so many things today are written in C. Considering that it's a language that was originally released in 1972, which is over 50 years ago at this point. So to say that C has had a lot of staying power is really, really an understatement.
[00:01:54]
To put this in perspective, 1972, the year that the C came out, this was Stevie Wonder released the song Superstition, and ABBA, the band [LAUGH] was first initially formed. So this was a long time ago. The world looked very different, and the world of programming especially it looked very different.
[00:02:10]
So when they were building C this was literally the machine they were building it on. This is a PDP-11. Now, this is not quite back in the punch card era, so I actually brought a little prop. If you ever wonder what a punch card was, I bought this on eBay for about a dollar 50 plus shipping.
[00:02:24]
[LAUGH] You can still get these things. So back in the way, back in the day, you would actually physically punch holes in a card and that was your UI. That was your UX, this is your feedback loop. They had a slightly different feedback loop. It was significantly improved over punch cards on this machine here.
[00:02:40]
This is Dennis Ritchie, who created C, and Ken Thompson, who designed UNIX. And actually we were talking a little bit about Go earlier, Ken Thompson, also one of the designers of Golang. And this machine that they're working on is called the PDP-11. So the PDP-11, [COUGH] you might notice, does not have a monitor.
[00:02:57]
And if you look at their eyesight, what are they actually looking at? They're looking down at this thing that's right above the keyboard. So what is that thing? That thing is a teletype. So a teletype, for those who are not familiar, this is a little video of a [LAUGH] teletype in action.
[00:03:13]
A teletype is an old, essentially combination keyboard/typewriter. So a typewriter, you press a key and it immediately puts a character onto a piece of paper, it prints it. Now what they're doing is, at first they're doing that, but then when they press Enter, you might notice that it starts typing without them actually pressing the keys more.
[00:03:32]
So the idea behind a teletype is you can use it as both input and output. So, they are now running a computer program, and the output of that computer program is being physically printed onto the page by the teletype. So if you've ever wondered why computers use the term print for writing to the screen, this is why.
[00:03:49]
Back then it was a very intuitive name cuz it's, well, yeah, you're gonna print now [LAUGH] you're printing characters onto the teletype. And sure enough, as we're gonna see, C uses the term print because literally this was the machine that they were originally doing it on, was a PDP-11 with a teletype.
[00:04:03]
I mentioned this because this context is relevant for a lot of the design decisions and some of the things that maybe today don't feel super ergonomic that we're gonna encounter in this course, such as really short kind of weird variable names and things like that. You can imagine, if you were working on one of these things where you literally have a physical piece of paper constraining the width of the output, having short variable names is kind of an important thing.
[00:04:27]
It's not you have somebody who's really dogmatic about their formatting and saying, you must stick to 80 character width as a matter of our formatting configuration. It's no, no, no, 80 characters is literally all you get, and that's it. The physical printer does not go past 80 characters [LAUGH] so that's all you got to work with.
[00:04:43]
That type of thing. Also, they had a lot of performance constraints. So the PDP-11 had a whopping 256 kilobytes of memory. It had 1-core single CPU. So no multi-core anything, no parallel processing of any kind. It ran at a blistering 125 kilohertz on that 1-core. So not only was it 110 of a megahertz, not even close to a gigahertz.
[00:05:04]
So this is essentially the world that they were living in when they designed and developed C. Despite that they were able to build a language that supported building all of these tools that we still use today. Which then leads to the question, if this was the language that they were building for this kind of hardware, why would people still use it on modern hardware when modern hardware runs so much faster?
[00:05:26]
Well, one of the things you might notice about all of these pieces of software on the screen here is that they're all things that really, really care about performance. They're things where if you can get something to run acceptably fast on this kind of hardware, imagine what you can do with something that has 3264, gigabytes of memory and 16-core CPU and multiple gigahertz.
[00:05:47]
Yeah, you can get something that runs very, very fast on modern hardware. So fundamentally, what people sort of jokingly, kind of half seriously refer to C as is portable assembly. And assembly language is essentially one very thin layer of abstraction on top of hardware machine instructions that the CPU understands.
[00:06:06]
So it's instead of ones and zeros, you have some actual text. So it's a programming language. It's not an actual writing bits and bytes by hand. But the level of abstraction that it adds on top of that is very, very thin. And it's also very machine-specific. So when you're writing assembly, you're writing assembly for a particular CPU architecture.
[00:06:26]
So C is portable in the sense that it's not technically coupled to any one particular CPU architecture, although as we will see later in the course, you do have the option of doing some more sort of targeted things depending on what you're building for. So it's not 100% portable, but it is way more portable than assembly, that's for sure.
[00:06:44]
And the reason that all of these programs are still using C today is fundamentally, it lets you write software that runs really, really fast. And the way that it does this is not because it has some sort of magical optimizer, although they do have very nice optimizers these days, but mainly because C offers you the ability to essentially do zero-overhead programming or very, very close to it.
[00:07:02]
About as close as you can get without a little assembly. And actually, C includes inline assembly in case you wanna drop down and do actual zero-overhead programming in the middle of your C program and just talk directly to the hardware that you're targeting. And this is a very powerful way to get performance.
[00:07:19]
Sometimes it's pretty manual, sometimes it's pretty unsafe. I would say that C is also almost zero-safety programming in addition to being zero-overhead, and this is one of C's major shortcomings. Is that you can really not only shoot yourself in the foot, but really blow your whole foot off with C.
[00:07:32]
And don't worry, in the exercises we're gonna see how to do that. So, [LAUGH], we'll have some fun with that in a kind of constrained non-production environment. Yeah?
>> Speaker 2: So by overhead, do you mean that just translation that it takes to get from the layer above machine code to machine code?
[00:07:47]
>> Richard Feldman: Yeah, great question. So to be more specific about what I mean about zero-overhead, really what I mean is things, I guess, the biggest example of overhead I can think of is garbage collection. So any programming language that has a garbage collector, that's a big convenience and it's a big boost for safety, but it's also a lot of overhead.
[00:08:05]
You have GC pauses now, and also there's just a lot of book keeping. The amount of memory that your program is gonna use is gonna go up significantly if you have a garbage collector. A lot of things are gonna run more slowly. C doesn't have a garbage collector.
[00:08:17]
And you can take that example and apply it to a number of other things. It's really basic stuff like if I'm in Java or JavaScript, and I make an object that's gonna do a heap allocation, there's gonna be some metadata on it at runtime. In C, it's no, there's no metadata, there's no allocation.
[00:08:31]
There's just the bare ones and zeros that are required to store the info, and that's nothing else in memory. And you take that and you apply that to the whole language, and it really starts to add up. The gap gets bigger and bigger between C and languages that have more overhead than C.
[00:08:45]
And also, finally, C is the language that other languages use to talk to each other in the modern day. So pretty much any programming language you can think of today, there is a almost 100% chance that that language has some way of talking to C. Because it's just sort of the lingua franca that's sort of emerged, and in part because of its popularity.
[00:09:04]
So if you want to do, for example, interop between Node.js and other language, Node.js supports C interop. Haskell, which we talked about earlier, has C interop. Rust has C interop. Pretty much every language has some sort of C interop. Really, one of the only exceptions to this, technically, would have been JavaScript in the browser, which, for a long time, had absolutely no way to talk to C, although now through WebAssembly, that is kind of possible.
[00:09:29]
But it's really taken off as this way to have one language talk to another one. If you've got Python embedded in Rust, or something like that. The way that Python and Rust are interacting and talking to each other is using C as an intermediary or at least the C ABI, which is essentially the way that C represents things in memory even if it's not literal.c files.
[00:09:50]
>> Speaker 3: When people say portable assembly or they can see assembly through their C code, do they mean this because they know how the language works internally?
>> Richard Feldman: So when people say portable assembly, the main thing that they're talking about is that C offers you essentially the same benefits as assembly in terms of minimizing overhead.
[00:10:10]
It's not quite true. Assembly does give you a little bit more control over things like CPU registers than C does. But the portability part really refers to the fact that I can write a .c file, I can write my C source code. And then without changing that code at all, compile it for, for example, this MacBook here is an ARM64 processor.
[00:10:30]
My desktop computer at home is an Intel x64 processor. These are different CPU architectures. If I were doing assembly programming for this MacBook versus that desktop Intel that I have at home, those would just be different assembly programs. The source code files would have to be different. In contrast, if I'm writing C, I can write one C program and then just tell the compiler to build one for ARM64 and build one for x64, and the same exact C code will work and give me two different runnable binaries, executables, that I can run one on the MacBook and one on the Intel.
[00:11:05]
So that's the difference. It's portability in terms of being able to write your source code once and then compile it to multiple different target architectures. A lot of other languages will do this by having a virtual machine or something that's like a runtime. So the Java virtual machine is a very popular one.
[00:11:20]
Obviously browsers have JavaScript virtual machines. But that's a much higher overhead version of things. You notice if you actually go to download a browser, you go to download the Java virtual machine, which is just a binary executable. On the download page, they'll say, download this for ARM64 Mac or for Intel Linux or something like that.
[00:11:38]
So that's what they mean by portability is across operating systems and CPU architectures. So first we're gonna talk about strings and numbers. We're gonna get into some file I/O. We're gonna get into building an actual static webserver using that stuff.
[00:11:56]
And then the very end, we're gonna talk a little bit about basically how you would use the things you've learned if you wanted to make a Node.js C addon. For time constraints, we're not actually gonna build the Node.js C addon, but I did wanna mention it at the very end of the course, just if you wanted to take these concepts and apply them in the JavaScript world, this is how you would actually go about doing that.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops