Hacker News new | comments | ask | show | jobs | submit login
Essential C (stanford.edu)
291 points by ingve on Oct 15, 2017 | hide | past | web | favorite | 55 comments



Essential C doesn't mention a standard but it says Copyright 1996-2003. I'm going guess it hasn't been updated for C11.

Modern C [1] covers C11 and was mentioned before. However, it weighs in at 300 pages rather than Essential C's 45.

[1] http://icube-icps.unistra.fr/img_auth.php/d/db/ModernC.pdf

Actually, reading through Essential C, it hasn't really been updated for C99 since it uses C89 declarations:

  C takes the middle road -- variables may be declared
  within the body of a function, but they must follow a
 '{'. More modern languages like Java and C++ allow you
  to declare variables on any line, which is handy.


I don't know if I would count any part of C11 as "essential", particularly given its still-spotty implementation coverage.


A lot of code is still written in C89 for maximum portability, and I regularly do that. The only thing I really miss from C99 is the mixed declarations and code, but you can instead use nested scopes or just move the declarations up to the top.


C99 object literals are also fantastic. I feel very constrained when I have to use strict C89.

Meanwhile, in terms of C11 [update: actually also from C99] I actually wrote a function with a signature like

  void func(int arg[static 3]);
but later removed it because (a) the generated code was the same, and (b) rather than increasing clarity and self-documentation, it caused confusion; even when you're familiar with the feature, it never stops looking like a syntax error.


I do love object literals. The 'static' keyword for array parameters actually dates to the C99 standard.


You're 100% correct, my mistake.


And stdint.h, variadic macros, restrict, inline (admittedly less necessary as compilers become more clever), flexible array members...

I mainly still stick to variable declaration at the beginning of the block out of habit but it would be a pain for me to go back to C89 and forsake all these other nice features.


What portability do you need, specifically, beyond C99?


A lot of compilers for embedded systems are still C89 (with a few architecture-specific extensions).


Which systems, specifically?


Until recently, even MSVC was C89. I believe they only added some C99 features because the C++11 standard required them (in VS2013, I believe), and full C99 support only came with VS2015.


Yep, their focus is on C++ compatibility.

They have changed their view regarding C, but the actual work is customer driven.

https://www.reddit.com/r/cpp/comments/75q5wc/visual_studio_2...


You are partly right about the implementation coverage. For a lot of embedded development where you can't cross compile with a modern compiler it's of course an issue. For major desktop and mobile platforms, I don't see an issue. Clang has excellent support for the mandatory parts of C11, it's even the default setting (well GNU C11). Given that one can now configure Clang as the frontend for Visual Studio on Windows, the backwardness of Visual studio in regards to modern C standards is no longer an issue as well.

For essential features, well if one uses C it's usually to have fine-graded control of memory use and allocation patterns. Then C11 _Alignas, and _Alignof are pretty essential. Yes you can do that with platform/compiler specific macros without C11, but it's nice to be able to avoid that.


Sorry to update you, but Microsoft has dropped that frontend.

They now advise to use clang directly, since its Windows support has been improved.


You might be right. I looked up my favorite modern C feature and it is intermingled declarations and code which is in C99. Others include inline functions, // comments (which were in C++), ...


Oh, memories. I took CS107 in 1996, which was apparently the date this handout was written. Nick was my academic advisor, and his CS108 (which was C++ at the time) was one of my favorite courses of all time. Bunny World...

Maybe I'm just a grumpy old programmer, but I feel like kids these days are missing out on something important by learning to program in a language that doesn't require them to truly grok memory management.


Most often, in general purpose programming, you don't need burden of managing memory manually. Things just go fine with a good runtime.

And that is what I think beginners should be introduced to - how to write code, how to frame algorithms in your mind and convert them into lucid code. Python does all of this wonderfully. It hides all of the internal details and exposes just the part that is needed for sometime writing a computer program for the first time in their life - simple statements which do simple things.

There is no need for a beginner to understand memory management at all. Trying to understand what is code or how algorithms work is more important to build that mental capacity IMO. Pardon me, but it does seem that just because you had to undergo the pain of trying to understand pointers, memory layout and allocations, you want everyone to go through the same experience as well.


Show me a Haskell programmer who doesn't understand memory management. You are grumpy, and I am older, but all memory is managed.

I recently ran into someone that was teaching a Python boot camp and they were forcing the students to use VIM instead of PyCharm, and in their words, "using a text editor requires them to memorize apis".

They didn't know about type inference, rename, extract method or navigate to declaration. I view it as the same bias, the attitude doesn't encourage people to use the best tools for the job because we suffered in the past. How about we go back in time and teach young selves how to write code than actually use 2TB of main memory and 128 cores using a dev environment that can scale to millions of lines of code.


As an undergraduate senior in the CS program at the University of Washington, I can definitely attest to memory management giving the majority of people a really hard time in our required C course. I've only talked to one other person in my cohort that likes programming in C, and unsurprisingly they don't have any trouble with the finer points of it at all.


Most of my classes were taught in Java, but I took care to also learn and do a lot of work in C++. I've also played around with disassembling various binaries (especially code actually written in assembly, like DOS games). Teaching myself to manually track the state of the stack, and see how it was used in function calls, was eye-opening in a way similar to learning manual memory management.


I actually took CS107 in 2012 with Jerry Cain, and we still used this handout as a reference guide.


I recently started a graduate course that originally required C++. My only exposure to C++ basically went through the fundamentals of the C part without getting to any of the ++.

Is there something similar to this for C++? I understand that C++ is a much larger language and I'm definitely not looking for something comprehensive, more of a solid overview of a workable subset of the language. Enough to be productive, produce reasonably modern idiomatic code that can be improved or expanded in the future.

In the end, the graduate course ended up using Python, but I'm still somewhat curious about modern C++.


I'd recommend A Tour of C++, by Bjarne Stroustrup. http://www.stroustrup.com/Tour.html


+1 to this. I took a course by Prof Stroustrup and he strongly newcomers to start with this book


Word of advice. Don't learn any of the OOP stuff in C++, many learned it, but later they had to unlearn it. Search for data oriented design.


Good advice, why learn something that isn't used on STL, Qt, wxWidgets, boost.


This looks like the best resource, https://github.com/dbartolini/data-oriented-design


That’s as bad as saying OOP is the cure for all your problems! Learn all the paradigms and use them where they’re best used, don’t shun any or advise someone against it just because you’ve had a bad experience.


I am frankly getting sick of the notion "use the right tool for your problem", when discussing programming paradigms. No, programming paradigm is not a tool. Programming language is a tool, data structures are tools and algorithms are tools. I don't believe there exists such and such problem, that can only be solved/expressed in OO way and the only true way is to do it in OO way or the best way if you prefer.


In a similar situation, I constructed a crash course using a combination of Accelerated C++, for succinctness & idiomatic C++, and Statistical Computing in C++ and R, for language features relevant to my graduate field.


Advanced C++ Programming Styles and Idioms by James O. Coplien

https://www.amazon.com/Advanced-C-Programming-Styles-Idioms/...


For a beginner, I think it's hard to beat "C++ Primer" by Stanley Lippman.


"Thinking in C++" by Bruce Eckel

"Effective C++" by Scott Myers


Isn't Thinking in C++ a little on the outdated side, by this point?


Great little resource on C programming and data structures. I had a lot of fun going through the problems presented in the Linked List and Binary Tree sections [1].

[1] https://github.com/imwally/cmuck


Does anyone have any recommendations for a document like this that describes how NOT to write C? Like the security issues and tricks to avoid the pitfalls?


This is the book for this particular subject:

https://www.amazon.com/Expert-Programming-Peter-van-Linden/d...

Every C programmer should have this on their bookshelf!



http://www.literateprogramming.com/ctraps.pdf

Also, consider looking into MISRA C guidelines. They contain many related tips.


First mistakes I found are on page 4.

"the compiler "promotes" the smaller type to be the same size as the larger type before combining the values." Values smaller than int are always promoted to int.

"Promotions do not lose information -- they always convert from a type to compatible, larger type to avoid losing information." This isn't true when a signed type is promoted to unsigned.

It seems that the author didn't read the C language specification.


Thanks for this! I've been searching for something like this for a while. So I'll add it to my bookmarks. As I'm currently using Beej's Guide to C to learn and this one looks a bit nicer. Also it's by stanford so that's cool.


The last link to "the great tree-list recursion problem" is an awesome assignment for thinking about pointers. (Though not really in any way representative of useful code.) Still fun to do after 20 years of writing C.


Any interesting ideas to try C out on for an experienced programmer?


If you're looking for something quick, then a Brainfuck interpreter shouldn't take longer than an afternoon, and a simple one will be a couple hundred lines. Optimising it though, can be more difficult and is one of those things you can keep working on for ages.

If you're looking for a challenge, a JSON parser is a more involved project, especially if you implement your own HashTable structure for storing things.

If you want something to be proud of at the end, then you could always try your hand at glitch art. Grab an image file, read it, manipulate it, and output it again.


There's also a very nice Python intro from the same author.



Any additional recommendations for C tutorials?


CS50 [0], if you're just getting started. It's Harvard's entry course to Computer Science, free, and covers most of the knowledge a beginner needs to get started.

[0] https://www.edx.org/course/introduction-computer-science-har...


I'm not sure of any. I do a bunch of embedded C code. I find a lot of C code tutorials are algorithm / datastructure focused. Which is ok to learn. You should definitely feel confident in implementing data structures / algorithms in C. But I'm not sure of any good tutorials which teach you how to engineer C programs. There is no "one true approach" but you definitely need to take "a" approach to constructing C programs. You need to have really good convention about how to do various things and how to compose your software.

Also C unit testing is often rare. I ended up writing my own framework (which I open sourced, but am neglectful with maintenace) with the idea you can run tests on embedded devices. Meaning it only relies on pretty vanilla C and has no memory allocation.

But, definitely incorporate unit testing in your C coding experience. It will help focus you on not falling for the evils of the language


When i was about 13 or 14 years old, i read Brian Kerninghan & Dennis Ritchie's "The C Programming Language". This book (by the language creators) is a classic and does an excellent job of explaining the C language. I learnt C by reading that book and experimenting writing code.

It is a very good book and it should be easily available.


A lot of people love this book, but I kept getting stuck because it seems like half the time it assumes prior programming knowledge. I only made it a few chapters in, but I don't think they do a great job of explaining much of anything to a beginner.

I'm planning on attempting to read it again after I finish Harvard's CS50. Maybe I just need a lot of hand-holding, but this course seems to do a much better job of explaining concepts.


>but I kept getting stuck because it seems like half the time it assumes prior programming knowledge

Yes, to be honest, C is not good as a "first" programming language. If i can give you a suggestion, it would be: Start learning Python, which is a good "first language to learn", and then try this book.

You will find that jumping from Python to C there will be two strong differences:

a) C is a statically typed language, so you will need to declare (specify) the type of each variable you would like to use.

b) In Python, the language manages your usage of the computer's memory. In C, you manage the memory... After some CS courses you'll probably be familiar with concepts like "linked lists", which then you can try implementing in C by using pointers. Thus, you'll realize that in C you are in control of the computer's memory; you will be able to request (allocate, with malloc) blocks of memory and free them afterwards.

c) C syntax can be tricky, compared to Python.


I have had a great success teaching a kid programming using javascript and plain HTML. There are numerous advantages to this approach.


K&R was written for programmers, so it's completely unsurprising you would have trouble reading it while learning to program.

Working your way through it after taking CS50 is actually a fantastic idea.


I don't know C, but I know that (learnXinYminuts . com) have something similar for mane languages




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: