Getting started with C
not.cafe
not.cafe
Its super optimistic approach is more about the language K&R wanted C to be than the real thing.
C Programming: a Modern Approach teaches C89 and C99, pointing out the differences in features when appropriate. Having used it myself this year, I found it much more helpful than K&R
———
It's a great read, even if you don't plan on programming in C.
* Legacy code
* Embedded (including drivers, bare metal etc.)
* Portability, FFI, etc.
Performance used to be another major reason, but in $CURRENT_YEAR, if that's your goal, C++ and Rust are just as performant and there's very little reason not to opt into them.
The other major reason to learn C is that it's a great "hardcore introductory" language that will expose you to foundational concepts like pointers and memory management (it's really hard to understand what problems Rust is trying to solve if you're not familiar with malloc and free, for instance), but if you're already programming that's less of an issue.
But for the most part, yes it is about "foundational concepts". A lot of the time when you learn system level programming people will refer to certain quirks or terms from the C world.
(Is there anyone who learns Rust who isn't already a proficient but frustrated C++ programmer?)
Parent was suggesting they are already a programmer, so I assumed they already had at least a grasp of how pointers and manual memory management work. If one happens to lack such knowledge, I agree learning C is an excellent first step.
I think what made RAII seem like a good idea was seeing a large C code base at a major company which had a consistent approach to cleanup and error handling. It's very possible to write good code that way, but it takes manual effort, discipline, consistency. At that point I understood that RAII was about letting the compiler handle what I was already doing in C.
Yes, I learnt Rust as a JavaScript/PHP/Python programmer who needed better performance for a project, and I'd thoroughly recommend it as a first low-level language. I found it much easier to learn than C++. There were a few new concepts to learn, but:
- There were far fewer than C++.
- The Rust Book provided a free and very approachable resource for learning them.
- The Rust compiler gave me immediate feedback if I was doing something wrong (no unexpected bugs in production)
- Most of my JS skills translated pretty straightforwardly
- /r/rust has a very helpful community which filled in any gaps that weren't covered elsewhere.
C is simple when you're working with toy examples, but as soon as you try to do anything moderately complex the complexity quickly jumps. e.g. If I wan't to use something as basic as a HashMap this is a trivial import in Rust or C++, but a non-trivial task in C. You either have to build/import a library (which is not that easy in C), or write one yourself! Same for string operations!
We have a lot of people who come from ruby/python/js, and/or haskell/ocaml/scala. They find Rust an easier foray into systems languages than C++.
And even some C veterans who never got on board the C++ train.
I have never used C professionally, so I never worked with a large, complex code base. But I think getting the foundational concepts from it as a first language has helped a lot along the way picking up and switching between languages.
C is a fine language, but it is from the 60s and 70s and feels like it. Rust is very nice, although poor for half-assed prototyping (which is actually maybe a good thing). Both are fine choices for systems-level programming.
That, and lighting fast compile times, where programming feels like (oh, the heresy) a _drastically reduced C++_.
If you have some programming experience you can probably jump straight to the Problem Sets.
It is actually in C++, but the goal was to cover C features first as the foundation, before going into objects, strings, and similar more advanced concepts. (It still uses C++ I/O from the very beginning, since it's was a C++ course.)
Win32 examples would have been peak hilarity.
More seriously, I see where the author is coming from, but even historically, GUI code has always been a massive pain in C.
ExAmples
GTK is good, but the programming model is exactly that. Especially in C.
If bare C is giving beginners a knife to play with, GTK is telling them to put electrical wiring together and "have fun". Oh but the lamp socket looks like a banana and wires look like ropes and vice versa. Good luck!
Beginners will probably be a bit lost, because the article doesn't go into any depth about event loop, retained mode GUI, GTK signals/handlers, nor does it link to GTK+ docs that would explain each part of the code, etc., etc.
You also have to know what's not in the head of an absolute beginner. Then you need to fill the gaps with background material. Not too much or your audience will tune out. Not too little or you'll lose your audience in a puff of confusion. There needs to be just enough instant gratification to keep the reader with you.
Many concepts you've mastered are tangled together in your head, and you'll realize this the minute you start trying to write about them. Before you started writing, you never noticed what a hairball of concepts you'd mastered, and if you don't expend some serious effort and energy unpacking it all, your absolute beginner guide will read more like a dissertation. You'll need to untangle each and every concept for the beginner audience. That means getting creative with how information is presented. With what information you reveal, and what information you simplify - but not too much. You should start thinking about ways to convey ideas graphically, which could excite you as much as it horrifies you. A good image can take as much effort as 2,000 edited words.
You start off thinking that it will be easy. And then you realize you've vastly underestimated how much material there will be to get where you wanted to be. If you haven't given up in complete frustration at the size of the undertaking in front of you, scale back your vision for the guide and repeat. It may take a few iterations before you know what you're doing.
Some guides get someone to "the end", but they don't scaffold an understanding of the underlying principles, and the student feels even more confused at the end than at the beginning.
I always go to great lengths to show the mistakes that I make all the time, and to show how much of a given domain I don't know.
For example, in a Make an OSS contribution walk-through I did, I mention over and over how myself or the senior dev I was pairing with didn't understand something. [0] Most of the job of a modern software developer seems to be surfing across an ocean of complexity, avoiding everything except the _one specific issue_ we're working on.
To persons unfamiliar with the field, they might think that we actually understand everything to any degree of depth. They would be deeply mistaken.
[0]: https://intermediateruby.com/matt-swanson-jekyll-bug-p2
The reason so much documentation is garbage.
Couldn't agree more.
I've spent probably a year incrementally revising a "getting started with Ruby" resource for a local software development program. [0]
I ended up with a 45 minute (!!!) walk-through of how to run a test file of string manipulation exercises. [1] I treasure each of the ~500 views it's got.
I spent probably 25 hours making, editing, and writing about that video.
I think this video is the single most impactful thing I've ever made, in the last 10 years I've spent making things. I treasure the DMs I've gotten in Slack, from students who have found the video extremely helpful, encouraging, etc.
[0]: https://github.com/turingschool/ruby-exercises [1]: https://www.youtube.com/watch?v=aeAkLxr5diE&feature=youtu.be
The tone at the start really does seem to be aimed at "absolute beginners" ("[...] programs must be written in a very strict way. Miss a comma and the program will stop working"), but then it quickly gets into the weeds without much explanation.
I'm trying to imagine an beginner reading this: The first thing we're told to do is "Installation", that makes sense. Then the first line says "The Apple provided C compiler is the LLVM clang compiler". But what's a compiler? How does that help me learn C? The tutorial hasn't even indicated that C is a compiled language, or what a compiler does at this point, and it doesn't elaborate on this throughout.
We go on to a hello world example, and we're told to type in some code ("Remember: programming languages are very strict, so type it exactly"), and then we're given an explanation of what it's doing: Great! I can't wait to learn what this means. But the explanation uses terms that a beginner would not be familiar with: The very first line of the explanation is "the first line loads the stdio.h function library, which provides the printf() function, used to write a message on the terminal". What's a function? What's a library? Obviously these things are trivial to anyone with programming experience, but for an absolute beginner, these terms don't yet have an intuitive meaning, and they're never fully explained in the article.
We compile that program (again, never being told what compilation is or why it's necessary), and then we're suddenly thrust into writing a GTK+ program. We haven't covered the absolute basics like types, pointers, etc, and yet we're given a huge chunk of (reasonably complex) code with no explanation, and just told to "read the code bottom to top" as an "additional hint".
I think a much better title for this would be "getting started with C tooling", but even then, the article does a very poor job of explaining why such tooling is even necessary.
absolutely same, me too. and, there was no good websites / videos on the web back then.
Whether the full function is there or linked later is a matter of implementation (some headers have full functions, typically trivial "inline" functions).
I can't remember what the standard says via the stdlib, but in general a library you load later on may not have all/some of those functions, but as long as you didn't use them you'll be fine (just as with a redundant forward declaration you yourself did).
And finally the whole "linking" part of C is mostly just a widespread convention, not something that the standard really dictates. See section 6.2.2 [1] for the brief words on it mainly to do with "static"/"extern". But the whole "compile" -> "link" (to some existing .so/.a) -> "program" is all implementation defined.
1. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
1. Aim for newbies. Vastly under estimate the amount of explaining that must entail
2. Peter out somewhere between the first and second real code example
I don't understand the bloat of introdocing gtk, meson and ninja, more deps means more code, more code means more bugs, more steps and more difficult to compile, I'm sure a lot of people will fail to compile this, which is very frustration for beginners who're not familiar with error messages. You might think meson and ninja makes it easy for building, but that's wrong, that might be true for engineers who build 1000 times a day, not for one off beginner situations like this. Abstractions is for people who understand why the abstraction is needed.
The author assumes the reader doesn't know what a terminal is, and goes from a "hello world" to a cross-platform graphical "hello world" using GTK-3 without explanation.
"Trust me, I don't have time to explain!"
Step 2: draw the rest of the fucking owl?!
I also like the overall format of the website and the radio feature is a nice touch. I'll visit it again in the future, out of curiosity.
A follow-up article may extend it with collaboration (git) or may delve in either Unix-like (e.g. with the GNU utils etc) or Windows, or both. But the author should first address the highlighted shortcomings...
If by any chance you reading this and want to learn C, do obtain and read The C Programming Language 2nd edition instead.
Good intro, and props to the author for introducing it on three major desktop platforms, using modern build tools.
This is the "getting started with coding" guide that I give to people who ask me about these kind of things. This is a defense mechanism - I tell them that I'll help them get started with a career in coding if they return me their completed text editor. So far nobody has, so maybe it's not the best beginner tutorial?
I still thought it was a great tutorial.
If I had read this lightning fast guide, I would be a bit lost. After displaying "Hello, world" on the terminal, do I really want to learn how to display "Hello, World" in a GTK window?
What set me on this path to enlightenement was an e-mail article from Dan Abramov (https://github.com/HackYourFutureBelgium/just-javascript/tre...) - here's an excerpt:
"We will learn about the JavaScript world for what it is — without thinking about how it’s implemented. This is similar to how physicists can talk about properties of stars without answering the question whether the physical world is real. It doesn’t matter! We can still describe it on its own terms.
Our mental model does not attempt to answer questions like “How is a value represented in the computer memory?” The answer changes all the time! In fact, the answer to this question changes even while your program is running. If you heard of a simple explanation about how JavaScript “really” represents numbers, strings, or objects in memory, it is most likely wrong.
To me, each string is a value. Not a “pointer” or a “memory address” — but a value. In my universe, a value is good enough. Don’t allow “memory cells” and other low-level metaphors to distract you from building an accurate high-level mental model of JavaScript. It’s turtles all the way down anyway!
If you’re coming from a lower-level language, set aside your intuitions about “passing by reference”, “allocating on stack”, “copying on write”, and so on. These models of how a computer works often make it harder to be confident what can or cannot happen in a JavaScript program. We’ll look at some of the lower level details, but only where it really matters. They can serve as an addition to our mental model, rather than its foundation.
...
As for these strange visions, I don’t pay as much thought to them anymore. I have wires to point, questions to ask, and functions to call. I better get to it! The stars are bright when I look at them.
Are they still there when I blink? I shrug.
Just compile all code with "cc -o file file.c", except for the math library, where you need to add "-lm".
Use whatever editor you like. Nano, nvi, emacs, whatever.
If nano is popular what are its pros and cons?
Nano seems to have a shallow learning curve for new users in comparison to vi, vim emacs as it works similar to other simple text processors.
It isn't as powerful as other editors and can't be configured as much but for some, especially beginners, that's a benefit.
If I ssh into a machine to change a config value I prefer it to vim/vi.
I'm not going to write anything using it, but for quick edits it's perfect.
To test my theory, I asked the OpenAI API to complete the following sentence:
This tutorial will guide you through writing the "Hello World" program in the C programming language.
And here's the result: This tutorial will guide you through writing the "Hello World" program in the C programming language.
Hello World Program Structure
The "Hello World" program is a very simple program. It consists of two parts: the main function and the printf function. The main function is the first function called when your program starts running. It is responsible for starting all other functions and initializing everything that needs to be initialized before your program starts doing anything useful. The printf function is responsible for printing text to the screen. In this case, it prints "Hello World!" to the screen.
The main Function
The main function must have one argument which is an integer that represents how many arguments were passed into it from the command line (if any). The following code shows a simple main function:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello World!n");
return 0;
}
This code will print "Hello World!" to the screen when executed.
Let's go over each line of this code:
#include <stdio.h>
This line tells the compiler to include stdio.h in our program so we can use its functions (like printf ).
int main(int argc, char *argv[])
This declares a new variable called main . It has two arguments: argc and argv . These are special variables that are used by C programs to pass information into their functions from their command line arguments (if any). We'll talk more about them later on in this tutorial when we cover how to use command line arguments with your programs. For now, just know that they're there so we can use them later on if we need them! ;-)
printf("Hello World!n");
This line calls our friend printf . It tells it to print "Hello World!" followed by a newline character (the n at the end).
return 0;
This line returns 0 back into our calling environment (in this case, it's our shell). If you don't know what returning values means or why you would want to do it, don't worry about it for now; just know that every C program must return a value back into its calling environment when it finishes running (we'll talk more about this later on in this tutorial).
Pretty good, eh? (I just formatted the text for clarity.)quite impressive. now ask it to solve the K&R exercises ;)
Always use the constant symbols.