Learn C Programming with Open-Source Books
ossblog.org
ossblog.org
One warning on the Python chapter, though. It is Python 2. But, it was a nice intro and got me reading the Python3 C API docs to see what changed.
Just a FYI for anyone looking to get it - make sure you get the latest edition (currently 2nd edition) as the first had a lot of issues which they fixed in the 2nd edition thanks to good feedback.
As a JavaScript dev, learning C has always had a certain appeal. However, anytime I start to dive in, there's this nagging voice in the back of my head telling me that I'm wasting my time as I will never use what I'm learning.
To any devs coming from higher level languages, have you found learning C useful in any practical sense? Or has your exploration of C been more "for fun"?
So any suggestions?
As for suggestions, all of the following are guesses because of my own n00b status with C. That said:
The runtime of the higher-level language of your choice. If you already know Python well, looking under the hood and seeing the C code that actually implements all the convenient and useful bits may well be instructive.
Rsync. I was able to get some small understanding of how it worked by browsing the source even though I knew hardly any C at the time.
Postfix. I don't think is a small project, but I have heard it spoken well of from a security standpoint -- in part because it is actually several small programs/modules that specialize in one task. Those individual binaries/modules might be comprehensible on their own.
http://aosabook.org/en/index.html
("Architecture of open source applications") and siblings.
I'd say reading the section on "git" there, and then having a look at the git source - or "nginx" and looking at the source - etc - might be one place to start.
Other than that, off the top of my head (suggestions from a hobbist): sqlite, the samba lightning db lmdb, the new openbsd daemons like httpd, opensmtpd, and the NaCl crypto library.
Hopefully more battle-hardened c-programmers can comment/add to the list.
[ed: and seeing rsync mentioned below, I recalled spiped along with a handful of other utilities by Colin Percival (former FreeBSD Security Officer, founder of tarsnap and active hn-er) http://www.tarsnap.com/spiped.html ]
But spiped is just 6500 lines of code, of which 4300 is segregated library code; a novice C programmer should be able to start by treating those as black boxes and read through the rest of the code to get a clear sense of how the entire program works -- something which is almost impossible for a program as large as even OpenBSD's minimalist httpd.
And reading spiped will expose you to a lot of the concepts which experienced C developers take for granted -- non-blocking network I/O and callbacks, threads, "extending" the language by creating more sophisticated data structures, workarounds for non-POSIX platforms, etc.
Who are these Kernighan and Ritchie guys? They obviously just don't understand "good code", terrible book!
(And I say this as someone who likes K&R.)
enum { NAME, PARENS, BRACKETS };
void dcl(void);
void dirdcl(void);
int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN]; /* data type = char, int, etc. */
char out[1000];
main() /* convert declaration to words */
{
while (gettoken() != EOF) { /* 1st token on line */
strcpy(datatype, token); /* is the datatype */
out[0] = '\0';
dcl(); /* parse rest of line */
if (tokentype != '\n')
printf("syntax error\n");
printf("%s: %s %s\n", name, out, datatype);
}
return 0;
}"[T]he programs are intended to be illustrative, not bullet-proof, there are significant restrictions on dcl."
In context this code illustrates the points they're trying to convey about complicated declarations quite well and is a precursor to understanding typedef later in the book.
Also, you left the nice inline comments off the variable declaration block.
(I'm very fond of the book as a historical artifact, btw)
The O'reily cow book covers C99 and is a good companion.
K&R was written in a different time, where computing had stricter (but not really different) constraints, but it's still arguably the clearest expositions of the language around.
considering computing hasn't changed that much since K&R was written, it's unlikely your idea of good code differs much from what was done 40 years ago. for example, functional programming, which is the popular dogma today, was invented around that time.
take the good (it's not hard to find in a book like K&R), discard the (perceived) bad, and move on with your life.
Also all of these are open source submissions.
A pointer to a collection of objects of unknown number. These functions
should use the VLA notation:
void func(size_t n, double a[n]);
I had no idea this was possible. Do compilers actually do anything with this
information or is it just informative?EDIT: I didn't get a warning out of gcc
#include <stddef.h>
int last(size_t n, int a[n]) {
return a[n-1];
}
int main() {
int a[] = {0, 1, 2, 3, 4};
size_t siz = sizeof(a) / sizeof(a[0]);
return last(siz+1, a);
}
Compile: $ cc --version
cc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cc -Wall -Wextra -std=c11 staticarr.c -o staticarr && ./staticarr ; echo $?
254
clang 3.8 warns about differing things: $ clang-3.8 -Weverything -std=c11 staticarr.c -o staticarr && ./staticarr ; echo $?
staticarr.c:3:25: warning: variable length array used [-Wvla]
int last(size_t n, int a[n]) {
^
staticarr.c:3:5: warning: no previous prototype for function 'last' [-Wmissing-prototypes]
int last(size_t n, int a[n]) {
^
2 warnings generated.
Still, it's a neat idea from a documentation point of view, and GNU-like
compilers seem to accept it.A bit before is more explanation of on the arr[static ?] notation. I was aware of this and usually prefer to use (Clang/GCC) function annotations to indicate NULL-ness of pointers and such, but I see the advantage in some situations. I don't agree with everything in the document, but it contains a lot of cool things.
The only special case is `int a[static n]`, which does tell the compiler that `a` has at-least `n` entries. But `a` is still just a pointer in this instance, so `sizeof(a)` still gives the size of a pointer.
Personally, I'd recommend avoiding the syntax purely because of the `sizeof` issue, but its up to you.
From the article though: http://icube-icps.unistra.fr/img_auth.php/d/db/ModernC.pdf
- 5 best open source board games to play online.
- 9 ASCII games you'll want to play again.
- 3 open source python shells.
So basically just a blog that creates lists. We see this a bit too often on YouTube. I am not sure we need more boingboing/BuzzFeed style of blog spam..