I always have the itch to learn C, juts because it was such an influental language and when you are digging around a lot in GNU/linux you will have contact with it one way or another.
What is the way you would suggest learning C in 2023? I am already familiar with other languages (rust..) but would like to have an introduction to the C basics and program some hands-on projects in C, so I can learn the pecularities of the language.
If you have lots of time: https://hal.inria.fr/hal-02383654
If you can't be bothered reading a whole book: https://matt.sh/howto-c
Exercises: https://www.codestepbystep.com/problem/list/c and https://exercism.org/tracks/c
Once you have syntax and basic algorithms down well, watch this, the only 2 hour YouTube video I'll ever recommend: https://m.youtube.com/watch?v=443UNeGrFoM
Both r/cprogramming and r/C_programming are active, also full of lazy students trying to get people to do their homework. If you come by, describe your problem well with code. Say you're learning for yourself, not for school.
Together C & C++ is a good Discord if you prefer live chat: https://discord.gg/tccpp
Since you are already familiar with other languages, you obviously don't need to know the basics of C. The basics are the same everywhere. Instead, you'd likely want to build that mindset on how to build good software with C.
I suggest you read other people's code and try to deep dive into the whys.
I heard Redis is a well-written software.
git clone https://github.com/redis/redis.git
git log –reverse
git checkout ed9b544e...
We can now see the very first commit made by Salvatore Sanfilippo. From here, we can start exploring. By looking at the commit diffs and git log messages, you'll be able to understand the motivation behind the changes.When you read a book, the most interesting parts are usually after all the theory is explained at the beginning. Somewhere in the middle of the book they start showing you code samples and that's when things become really interesting.
What I like about the reverse git-log approach is that it immediately throws you into the middle section of the book. This approach is both fun and eye opening.
Good luck!
I say "C considered as a language", because in my opinion and experience the real challenge in learning C is C considered as a platform, that is, learning how to build C projects, how to actually pull in dependencies, how to resolve them when they blow up, how to build cross-platform, understanding the several toolsets used by real projects to accomplish these tasks (raw make, autotools, cmake, etc.), dealing with library conflicts, etc. C is a nice little language, too simple for 2022 and something I wish people would really stop using, but it is at least simple. The C platform is a clusterfuck nightmare disaster zone, if not multiple independent clusterfuck nightmare disaster zones.
I can say with a straight face I "know C", inasmuch as I know the language and have even done some non-trivial work in it. (Not much, but some.) I have never in my career learned C as a platform. This is a choice, and I still think it was even a good choice, but what I'm really highlighting in this post is that this is certainly something that is noticeable, that the fact that I "know C" has actually been of almost no utility whatsoever when I encounter problems and have to fix them because the problems are almost always in the platform. I have made do with a very cobbled-together understanding of the situation and a high degree of "google-fu" on this topic (beyond just "pop the error message in verbatim and hope for the best") and I've chosen not to pursue this any further.
So I would recommend to you that you consider your goals here; do you want to "know C" as a language or a platform? Both are fine options but they lead to different solutions.
https://www.youtube.com/watch?v=QpAhX-gsHMs
I think the best thing you can do is go find a unit testing library you like the look of, maybe some tools for address/leak sanitization, and spend a good amount of time learning CMake and creating a build/project workflow you're happy with. Coming from Rust you've got great tooling and good guardrails in place to keep you on the happy path, I think getting into that groove early in C where you can run experiments and break things in a sane environment is important.
Likewise, if you're using any other language and you want to use a general library, you'll need to know enough C so that you can successfully encapsulate concepts like pointers; and copy your program's data into data structures that C can consume.
It's all much, much easier if you have some C experience.
In my case, I haven't done much C in 20 years. What really helped me "keep up" was occasionally doing Mac programming in Objective C. Because it's really easy to drop into C, it helped refresh me on a lot of the concepts. Even if you're doing Swift, you can mix in an class written in Objective C that's mostly straight C in the methods.
In my opinion it’s a perfect project because:
- it is a good size. You can be done in 10-20 hours, or longer if that’s your pace (have fun!)
- a lot of examples and community support.
- you have a whole project without any overwhelming complexities: you’re just taking inputs, reading some data, running it through a switch statement, writing data, writing to a screen, then repeating.
- you have lots of “test code” aka games.
- it mostly lacks tedium: you’re not repeating ideas too often
- it’s fun!
__asm__ ( "addl %%ebx, %%eax;" : "=a" (c) : "a" (a) , "b" (b) );
Then you could just continue in C as if nothing had happened, and a printf("%d",c) would give you the right result. When I worked as a quant, I saw such code snippets quite frequently. Those days (late 90s early 2k), individual programmers had a certain amount of freedom that is completely missing today. You would have a cohesive team with a C programmer, java programmer, a sysadmin, an R guy, a kdb/q quant - no issues. The front end was all java awt widgets, and you would jni to do the hard bits. jni would pull in the C code, which was peppered with little bits of __asm__ to speed things up. Everytime you needed to interact with the outer ecosystem, C would do an fwrite to the file system, then R would pick up the file, do its montecarlo simulations & write back to the filesystem, the algotrading bits would be in q, and even the sysadmin had his share of awk/sed to massage all the back & forth data. It was smooth & nice & pulled 100x its weight. Best of all, the individual programmers had respect for each other's skills & would learn from each other. These days, some asshole CIO would fire the whole bunch & replace them with 10 pythonistas & insist everything should be coded in one true language - and as one of those pythonistas, while I am happy I still have a job in this recession, it is kinda sad, those languages were so much more fun & it was exciting to watch the interplay of different languages bearing their own strengths, whereas python otoh is so terribly boring & everyday is same verbose torch.autograd.Function crap oh well back to the coal mines.
https://www.oreilly.com/library/view/c-in-a/9781491924174/
As far as code examples, I find there's a lot of simple C graphics programs using the SDL2 library discussed on Youtube. Also simple ncurses programs are worth looking at. For example here's a video on making a tic-tac-toe game with pure C linked to github source code, just a few files:
https://www.youtube.com/watch?v=gCVMkKgs3uQ
https://github.com/tsoding/profun/tree/master/procedural
For practice, CodeWars has a lot of nice simple C challenges to work on.
I would also suggest to enable all warnings your compiler allow for and sanitizers if possible. You will also want to learn to use a debugger that works on your operating system.
There are tons of useful/fun things you could do with C. Write some desktop apps with GTK, a web server with Mongoose (https://mongoose.ws), etc.
Also look at C programs. I study old, small unix programs like "more".
I must also say that I see people asking about learning C on sites like Stack Overflow and getting discouraged saying that it's outdated and all. These people are doing a great disservice.
Currently I am trying to learn how to test C correctly, seems there are lots of approaches.
It began when I decided to learn low level development a few months ago. I completed my Chip 8 emulator. Next I bought Arduino a month ago and I was playing around with it. Now I am reading AVR Programming book so I decided to learn C properly. On the side I already made a small keyboard with a microcontroller with QMK firmware. Soldering and stuffs.
Next what I’m trying to learn is some electronics knowledge just enough to make stuffs.
This is way more fun than my web development job!
Currently the resources I use: - Learn C The Hard Way - BeeJ’s guide to C - random video tutorials from the internet - Make: Arduino - Make: AVR programming
Haven't used it professionally in over a decade now, I'd be interested in learning Rust, but don't really have a need to do anything low(ish) level these days.
"Secure Coding in C and C++"
https://www.oreilly.com/library/view/secure-coding-in/978013...
"The CERT C Secure Coding Standard"
https://www.oreilly.com/library/view/the-cert-c/978032160319...
MISRA-C
Frama-C
Also have a look at the static analysis and warnings available across all major C compilers.
I really enjoyed it and think the teacher is great. I don't think all of it is necessary if you are already a developer, but I didn't have a traditional education so it filled in a few gaps for me too.
https://learning.edx.org/course/course-v1:HarvardX+CS50+X/bl...
As some other commenters, I really recommend Modern C by Jens Gustedt.
If you’re on Linux you can use man pages for most or all of the c stdlib, it’s a really convenient way to check up on stuff directly from the terminal, less tempting to rabbit hole into something else while in a browser.
I started contributing to a really small open source project, it was less daunting than a large well written, well formatted project and you get to run into “accidents”, figure them out, fixing them, learning from the experience. I realise this is a matter of personal preference, for me it’s a nice learning experience.
Also having (or making) friends who knows c is really helpful.
Good luck!
There's also man pages for all the libc stuff. Try `man 2 listen` or `man 3 printf`.
The VSCode plugin for C is pretty decent as well, the Microsoft one called 'C/C++'.
I'd also recommend doing a readthrough of the GNU Make docs. They are succinct and full of useful stuff: https://www.gnu.org/software/make/manual/make.html
Do you like videos? Find videos on YouTube and watch them.
Do you like books? Go on Amazon and search for "C programming".
Do you like reading code? Go on GitHub and start reading the source for any project.
Or just find any online resource and use that.
The most important thing is to write code to do something you're interested in. If you're interested in solving puzzles, solve some puzzles. If you want to write a game, write a game.
Above all, you shouldn't waste time concerning yourself initially with what the "right" thing to do is. Do NOT let the perfect be the enemy of the good. It's OK to ignore the advice of anyone who tells you you need to be concerned with how to set up your project the right way, or tells you to avoid certain "dangerous" functions in the standard library. Just avoid all dogma.
Since you're learning, thinking about these things now is a huge waste of time. It's much better to write code that actually does things. If you thoroughly engage with this process, you will figure this stuff out on your own naturally. Or you won't, and then someone will correct you later, at which point you will be in a better position to appreciate their advice.
Biggest time-waster: reading this thread. These threads are mainly a venue for people with minimal experience to regurgitate things they have read elsewhere.
In general, the reason to use C is because you are doing something that interfaces with the OS. But the problem with software at this level is that because the abstractions are so low level unless you understand something about the design/architecture of the software the code is really hard to understand.
So I would pick some project that is interesting to you and that you have some familiarity with already and try to implement a simple version of that in C. It is actually not too hard to write a WebSocket or HTTP server in C, so if you are familiar with web programming, writing one of those might be a fun project.
Good resources:
- #c on libera.chat *
Good books:
- C Programming: A Modern Approach - K. N. King
- K&R2 with the errata at hand and the guidance of someone experienced when doing all the exercises
Good advice:
- Don't write a single line for which you are not sure that the behaviour is either well defined by the standard or by your particular implementation (and if the latter is the case, ensure you are well aware of the implications and document them appropriately).
- C is not a "try it and see" language, trying it will lead to undefined behavior and buggy code which you might not even become aware of until you have "learned" the language.
- Lots of C out there is littered with poor practices or heavily specialised to the task/target set of architectures/situation and is therefore not a good example for learning. Feel free to read lots of C once you have the fundamentals down, not before.
Things to avoid:
- Every online tutorial (no I haven't seen them all but none of the popular ones seem to instill the right discipline and are usually full of errors, one of the ones linked from this thread has a bug in the hello world program in the first exercise).
- Most books on the matter.
- Writing C.
* disclaimer: I am one of the founders of this channel.
If you are learning for practical reasons, like you have a project in mind, then it will be dependent on that project. C patterns and idioms vary a lot per project and time period. For a newer, more practical book I liked C Programming: A Modern Approach. Just don't go into it not expecting it to be too modern. The subject matter is still still C. After that you'll still probably have a lot to learn for whatever project you have in mind. C has a lot of quirks, peculiarities and shortcomings. There is no standard way of dealing with them so each project has their own best practices or set of helper APIs/tools with some minimal overlap.
I would have never been bothered to build something in C in an environment where I can reach for any higher level language.
With that in mind, I would suggest picking a piece of hardware you want to learn more about, and using C programming to see what makes it tick.
https://www.amazon.com/21st-Century-Tips-New-School/dp/14919...
1. You study the wonderful Kerninghan & Richie book. It's a great work of art.
2. C's architecture is just raw computing. Try building a toy interpreter or compiler and you will know most of CS in bargain too!
Good luck my friend.
Here's an idea: pick a project that interests you and start. For any question or issue you run into, there will be 1000 Youtube videos to choose from, and 10000 online tutorials. There will be an associated sub reddit to ask questions.
Rust is like a modern rifle, unloaded, with six safeties and three locked triggers in a gun safe. The ammunition will harmlessly self-destruct if you don’t focus properly before firing.
C is sort of like Rust except the rifle is on the couch, loaded, one in the chamber, all the safeties are off, the numerous open triggers are held by RNGs, and the business end is pointed right at your most prized possession.
It is fun, in a way. Use it in an environment that you don’t care too much about.