1. Buy K&R.
2. Read it. Maybe 2 or 3 times during the process of reading it, I would go write a program to try what I had just learned. This was was around 1980, so trying a program meant walking across campus to a terminal. I could either head to the computing center and use a public terminal, or to the high energy physics building (where I had just started a work-study job programming and it required C). The former would mean competing for a free terminal--and annoying people if I was spending my time at the terminal mostly reading K&R instead of typing. The later meant sitting at a terminal next to a noisy minicomputer in a cold room.
When I got to the end of K&R, I was a C programmer in theory.
3. Start doing real work, using K&R as a reference.
Very quickly theory became aligned with reality, and I was then a C programmer in practice.
Nowadays, most programming books I find assume that I'm sitting eagerly at a computer as I read, and that I want to stop every three paragraphs and type in some code and run it, and then the book discusses what that code did with the author writing under the assumption that I have the output of the code on my screen.
I like the K&R way better.
By contrast, I did Perl work for years, and went to script something in it recently. Quickly decided it would be easier to learn Python from scratch than to get my Perl chops back.
A decade ago I thought the book "C Programming : A Modern Approach" by K.N. King was a good starter text--I don't know if there's a better recommendation that's more recent.
In terms of after the fact reading, if you like the terse style of K&R you might pick up something but if you got bored I suspect that means you don't like the style. I suspect the time might be better spent reading some code instead.
K&R is simply a brilliant programming text. It might just be the right learning model for me, and maybe others can learn as well from other books, but I'd read a dozen C programming books (all much thicker than K&R, but much less valuable) before K&R, and it never really took until K&R.
I did not write much of interest using Amiga E, and that booklet was nowhere near as useful as K&R.
I think it's primary reason for popularity was that it was so easy to use the Amiga GUI elements and other special features of the Amiga OS and hardware. I always had a hard time making stuff work in C, but could build a UI in no time in E.
Read it. Maybe couple of times (say only chapters 1-3) in the beginning. Understand the basic mechanism first rather than try out a program copied from somewhere else.
Start testing out simple things.
I'm lucky to not have fallen for all the blog posts/tutorials on openGL where they spit out a C file and say to compile and run it.
Machines that I had at the time were a Trash80 something or other mostly running basic and an AT&T machine running some for of Unix...oh yeah.
But, I fought my way through K&R, multiple c compilers, assembler, etc. to actually learn something on these machines.
An interesting comment from an earlier discussion mentioned "this code (in C) is much cleaner than any C++ I have seen!". The truth is, if you know C, have a good style and discipline, you pretty much can produce more readable/reusable code than your normal c++ person.
"I know C thoroughly, though I barely ever use it these days. I used it for so long and during such a formative period of my overall programming career that I can read/write C code with virtually no spin-up time even though I find myself touching C code very rarely. Oh, and btw, when I find myself coding C on a nix box, I am still amused at how I have muscle memory for all those old emacs commands I also haven't used regularly in about a decade though I wouldn't be able to tell you what they are without doing some keyboard mime exercises."
Yeah, well, I guess that is a bit too long to be a poll entry.
Tolerance of, nay, encouragement of dissent (not insubstantiated rants) is the hallmark of a healthy community.
Btw, if you choose to downvote this, please explain why and what I am missing. Thank you.
Some people think that if you have social skills you can't be a 'real' hacker, but often sales skills and good presentation are a force multiplier for a contractor with good technical skills.
Except for the fact the code was almost as old as I am (born in 1976) it turned out that the security check that the code was supposed to perform didn't actually execute.
Yepp, that's right, the code had been running for 30+ years doing nothing.
A friend of mine ended up doing the actual work so I don't know how the story ended but it's a good reminder to never assume _anything_ when you look for bugs.
bool operator<(.., ..)
{
return operator<(.., ..);
}
He ran the code and it worked. I was confused.Another student saw the teacher pass him and copied his implementation. His code didn't work. It gave the stack overflow error that I was expecting.
It turned out that the reason the guy had his code work in the first place was because it was never included in the program. He had put the code in his C++ file, but forgot to include it in his header. When the program compiled, it never knew his code existed.
For(i=1 to 10) {then print i; } Today my friend is working as a techie ....senior mgr at his new company!
C just happens to be the right choice for most of my projects today (I half seriously proposed FORTH for one before my cow-orkers threatened me with a dunking).
Let's make a distinction between Management as an HR function (writing reviews, dealing with org issues, fighting for equipment and office supplies) and Senior Geek Nirvana (design work, heavy lifting in code and debugging / shipping a product). I tried Management for a while, and it stunk.
Right now I'm in a great position as a senior technical guy (I hesitate to say "Architect" because most of the people I know with that title are self-appointed blowhards) who gets to decide how to do stuff. I lean on managers ("we need some chairs, and an oscilloscope") and project management (for setting up meetings, tracking bugs, etc.), and I get to write a ton of docs and code. It's terrific fun.
I'm living proof that you can be writing in C and not be a sour, dried-up dinosaur in the back corner of a lab somewhere.
Already around '95 or so Perl was widely used, GUIs could be done in things like Tcl/Tk, basic apps were starting to move onto the web, desktop stuff was mostly in C++.
You learned C when you wanted to work on things like kernels or databases or high-performance daemons and whatnot. That's still mostly the case. Java has eaten into that a little bit, but that's not even a new phenomenon.
The things that people used C for 15 years ago are still the same things that it's used for today, and similarly, you didn't have to write stuff in C 15 years ago if you just wanted to bang out some little utility or "CGI script". I expect things to stay that way until there's some language which could reasonably replace C in its niche. Thusfar one has not emerged.
Today, I regularly use an email client written mostly in JS, message boards written entirely in Python, a chat client written in Python, a high-performance file transfer program written in Python, a music player written in C#, system monitoring tools (iotop, htop, dstat) written in Python, a version-control system written in Python, and so on. In 1995, I used an email client written in C, a newsreader written in C talking to a netnews server written in C (although early netnews servers had been partly written in sh, they were rewritten in C for performance), an IRC client written in C, file-transfer programs written in C, music players implemented in hardware, "top" written in C, version-control systems written in C (although, again, the first version of CVS was a shell script), and so on.
I don't think it's true that "basic apps were starting to move onto the web" in 1995. Web sites that were really programs with HTML user interfaces didn't really start to take off until around 1997, by my recollection. I joined eBay's AuctionWeb in 1996, but it was quite unusual (and it was promptly rewritten in, I assume, C++, as eBayISAPI.dll).
GUIs could be done in Tk, or for that matter PowerBuilder or Visual Basic, but that was thought to be "for amateurs". It became technically possible to do this kind of stuff in high-level languages then, but it took a few years for people to notice that.
My point, though, is that much of C's 1995 or 1996 niche is now occupied by "scripting languages", and in 1995 or 1996, that niche was occupied by C.
That being said, I'm an "average age" HNer that has worked with (and loved working with) C. I'm looking for excuses to work with it more, although it doesn't really intersect with my type of work (statistics).
Maybe I should contribute to Redis or other OSS...any suggestions?
The core of R is written in C, I think. Might be worth a look?
I need to go back to dabbling with my little Spartan3E board though.
I mention this just to say why I think "modern" very-high-level language hackers still end up learning C; the base layer is all written in it, and eventually you've either got to fix something or write something fast.
(I'm 28)
Anyway I hope for your sake looking at the Python interpreter did more than reinforce your knowledge. It's no stroke of genius, but it's much better written than PHP.
I already hated the interpreter before I dug into it, and my expectations were reinforced. I was a college intern, I didn't choose PHP!
I can add the option if this doesn't make sense in your case.
It's similar to offering 3 options for Marital Status: Single, Married or Divorced. It's impossible to interpret the results in any meaningful way (Divorced and single? Divorced and remarried? Is it important that I've ever been divorced? Or do you just want to know if I'm currently married or not?). It's better to separate these questions.
What if I added a phrase to option two: "Or I learned C extensively at one point, remember most of it, but don't use it regularly anymore" and to option three: "Or I learned C extensively at one point, but have forgotten most of it and don't use it anymore?"
I am not a pollster but by combining different facts into single options you are restricting the information you can gain from your poll or polls.
I taught C to engineering students at a university, I know it thoroughly, I haven't written a line of it in 12 years - the only option I can logically choose is the final option.
A third range might be how much you like C, regardless of how good you are at it or how often you use it.
You would think this would qualify me as someone who, if not enjoys, is at least is competent at C.
You would be wrong.
I absolutely despise C, and never would have become a computer programmer if I had to do most of my programming in C.
The horrible syntax, retarded pre-processor, and absolutely brain-damaged memory model (addressing modes? segments? virtual memory? reified stack? fuck that, let's just pretend everything is a pdp-11!) make it into this zombie that can't quite decide whether it's a shitty assembler or a shitty Algol clone.
I don't consider myself a competent C programmer, and I have no desire to become one.
Trying to write a compiler for C (https://github.com/vsedach/vacietis) has only cemented my dislike for the language.
I don't blame Dennis Ritchie for it. He probably thought it was a dumb joke too. I blame all the retards in the 1980s that thought it was the bee's knees and made it a "standard."
"Vacietis aims to be a C99 to Common Lisp compiler that produces efficient programs that easily interoperate with Lisp functions, and in addition to offer the introspection, debugging and type-safety features of Common Lisp to C programmers."
When writing C, I have to spend time thinking about the syntax and memory management.
Although I have spent much less time using Python, when writing Python I am only thinking about the problem domain and algorithms.
That said, answer #3 or #4 makes sense.
BTW, const correctness is in C99, and memory management is usually done by writing constructors and destructors like C++ (except that they're real functions, often named stuff like <prefix>_init and _destroy or <prefix>_new and _free) and calling them manually. It's not as elegant as RAII, but if you write short functions with clear logic, you can usually ensure you cover all code paths. Remember that you don't have exceptions to screw up control flow in C.
For type-safe containers, I just use void* containers with a comment indicating the intended type, but perhaps more experienced C programmers have a better system. Remember that Java didn't have type-safe containers until Java5, and honestly ClassCastException was a fairly rare error.
I have made the experience that a good C++ developer also automatically knows everything about C.
I have never met a competent C++ programmer that does not have at least some exposure to C as well. But I'd dare to guess, that such character would not understand the C preprocessor in any but the most trivial level.
[edit] I originally used the phrase "C with classes" crowd, in a rather derogatory way, to describe the people who never get to learn any of the languages well, and end up writing some sort of sanitized, structured-programming, algol derivative in (a subset of) C++ syntax.
While reading the rest of the comments, I remembered that "C, with classes" can also apply to C hackers that just use C++ to structure their C-styled code, and may take advantage of a few features of the language. I have edited the comment to clarify what I meant.
Not even close in my experience. In college, we used C++ in our intro course. The addition of pass by reference, classes (with constructors and destructors), and the standard library (e.g. std:string) hides a lot of the common paradigms of C, and that's not even mentioning boost.
In my experience, people coming from C++ tend to write really bad C. Many of them have a poor understanding of the concept of pointers.
Once you get familiar with some good C design patterns, it's pretty easy to write clear, modular C. Knowing C++ is not a very effective measure of ability to use C.
Rogerian LISP?
CPAN grew on me later - roughly as CPAN was growing. It was garbage collection that was my deciding factor.
If you play with languages that use prototype-based OO like Lua and JavaScript, you can see pretty clearly how to implement such things. Implementing your own OO system in Lua is an experience I'd recommend for anyone who uses OO; it's easy, and you'll almost certainly learn something you can apply elsewhere.
That's probably a really big one in terms of reliability.
Also, the weird C++ behavior of calling copy constructors in the most unexpected places can have a very detrimental effect on performance.
Personally, I think the nature of C++ class definition leads people down the primrose path of trying to provide all potentially useful methods, of which only a tiny fraction get used. Tons of dead code appears in most C++ projects.
Also, you may be giving up a lot of niceties in your IDE that way.
Plus, if there's some feature of C++ I do like, I can bring it in.
Ug, now it sounds like PHP.
<3 Python
(Edited the first line a bit)
I think my primary use for knowing some C would be writing C extensions for Ruby or looking at some source code of classic C libraries.
I think how "knowing C" is defined is key in this question, yes I can write my fair share of C, but I still don't think I could class myself as a C programmer.
From my perspective using Linux is one reason i know some C, but the greater reason is because my formal education included embedded C programming with microcontrollers. Programmers going through pure software engineering courses seem to focus much more on computer science and web development concepts, rather than systems design and programming. That said, i'm sure my experience is not typical, and other universities probably use C in some part of their courses.
In terms of actual programming, i haven't yet found a project which required the use of C, and in the cases where i have used it i've often stumbled more with the bulky IDE and build configurations than the language itself. My particular trouble is around external references and including code not in the standard library, and then the further dependency hell.
Searching around i haven't really found any C tutorial that really covers this sort of stuff really well, most tutorials focus on the language itself (which i don't really have an issue with). Does anyone know any good resources on how to set up an optimal and easy to manage C development environment?
One thing I've noticed is how focused you have to be when working with C vs for example python/php - everything is very error prone mostly due to manual memory management. You also need good visualization and some basic math skills.
I haven't really used C in years, but I can start programming in C anytime and get operative, robust (I'm a freak about error handling and knowing where lie the exceptions) code quickly and cleanly.
These days I dabble in Javascript, higher order perl, and am trying to grok Haskell, but I think in C. To my simultaneous benefit and detriment.
The vast bulk of code I was paid to write was /bin/sh - thousands of lines of clean, robust, cross-platform installation and configuration routines, with pipes to awk and sed as required. But I thought in C.
Other than deliberately obfuscated code and kernel programming, I've never met a C program I couldn't grok.
But I don't use C, haven't in years, and don't know it thoroughly. I am not a C guru, nor even close to being a wizard. But I would call C the lingua franca of the computer world, the cleanest, most elegant tool out there.
C wasn't the first language I learned, but it was the first that blew my mind. After years of hacking on various BASICs, then FORTRAN, and Pascal, I encountered C (I have a BSc in Physics; I didn't hit C until after I decided to experiment with CS for a while).
After years of forcing my thinking into the little boxes these other languages insisted on living within, BAM, here was a language that allowed me to escape any box, build better boxes, nest boxes, hide boxes, thermonuclearly destroy anything within 6 gigs of my box, etc., etc., etc.
The sad side note: Scoping was never really an issue with the other languages, they had pretty hard and fast rules. Scoping wasn't all that much different with C, but all of a sudden it became really, really important to understand it, to be able to unwind pointers mentally and really appreciate what was going on.
So for me, C scope was computer scope, all scope was C scope. One of the biggest mental hurdles for me in learning higher order perl was abandoning C scope and automatic dereferencing without global variables.
It took me a while to get my head around how the difference in scope management made class and object variables and memoization so much easier in perl - and in many other languages - than in C.
So I think in C. And sometimes that's good, but other times it is a handicap.
I didn't feel like "I learned some C" applied. That could be my awesome sentence parsing skills at work, though. :P
I wonder if I could get back into the swing of things easily. I should give it a shot.
I have had to learn JS, but I don't like it.
but i know objective-c pretty well.
It is a great little language for sure, still destined to outlive some of the languages that are hip today.
The only time I use it these days is when I go into random open source projects to fix bugs or occasionally add a feature.
Unfortunately, those years were mostly in the 80's and I've barely touched it since, so I really have no idea if I can still call myself a C-programmer. I used to be good at it though. At least that's how I remember it...
One good thing that I figured out is to learn concepts from high level languages and use them in C. I guess lot of people are doing the same.
(I also picked up Steele's C: A Reference Manual, 4th Ed. for a buck at the same place.)