The C Programming Language

Author: Brian W. Kernighan, Dennis M. Ritchie
All Stack Overflow 79
This Year Reddit 70
This Month Stack Overflow 1

The C Programming Language


Review Date:


by anonymous   2019-01-13
  • Everything before standardization is generally called "K&R C", after the famous book, with Dennis Ritchie, the inventor of the C language, as one of the authors. This was "the C language" from 1972-1989.

  • The first C standard was released 1989 nationally in USA, by their national standard institute ANSI. This release is called C89 or ANSI-C. From 1989-1990 this was "the C language".

  • The year after, the American standard was accepted internationally and published by ISO (ISO 9899:1990). This release is called C90. Technically, it is the same standard as C89/ANSI-C. Formally, it replaced C89/ANSI-C, making them obsolete. From 1990-1999, C90 was "the C language".

    Please note that since 1989, ANSI haven't had anything to do with the C language. Programmers still speaking about "ANSI C" generally haven't got a clue about what it means. ISO "owns" the C language, through the standard ISO 9899.

  • In 1999, the C standard was revised, lots of things changed (ISO 9899:1999). This version of the standard is called C99. From 1999-2011, this was "the C language".

  • In 2011, the C standard was changed again (ISO 9899:2011). This version is called C11. Various new features like _Generic, _Static_assert and thread support were added to the language. The update had a lot of focus on multi-core, multi-processing and expression sequencing. From 2011-2017, this was "the C language".

  • In 2017, C11 was revised and various defect reports were solved. This standard in informally called C17 and was released as ISO 9899:2018. It contains no new features, just corrections. It is the current version of the C language.

"C99 strict" likely refers to a compiler setting forcing a compiler to follow the standard by the letter. There is a term conforming implementation in the C standard. Essentially it means: "this compiler actually implements the C language correctly". Programs that implement the C language correctly are formally called strictly conforming programs.

"GNU C" can mean two things. Either the C compiler itself that comes as part of the GNU Compiler Collection (GCC). Or it can mean the non-standard default setup that the GCC C compiler uses. If you compile with gcc program.c then you don't compile according to the C standard, but rather a non-standard GNU setup, which may be referred to as "GNU C". For example, the whole Linux kernel is made in non-standard GNU C, and not in standard C.

If you want to compile your programs according to the C standard, you should type gcc -std=c99 -pedantic-errors. Replace c99 with c11 if your GCC version supports it.

by anonymous   2019-01-13

Let me start off by saying something a little off topic:

  • I don't think this is a very good book. I think it confuses some topics to make them seem harder than they really are. For a better advanced C book, I would recommend Deep C Secrets by Peter van der Linden, and for a beginner's book, I'd recommend the original K & R

Anyway, it looks like you're looking at the extra credit exercises from this chapter.

  • Another aside- I don't think this is an especially sensible exercise for learning (another answer pointed out the question isn't formed to make sense), so this discussion is going to get a little complex. I would instead recommend the exercises from Chapter 5 of K & R.

First we need to understand that pointers are not the same as arrays. I've expanded on this in another answer here, and I'm going to borrow the same diagram from the C FAQ. Here's what's happening in memory when we declare an array or a pointer:

 char a[] = "hello";  // array

a: | h | e | l | l | o |\0 |

 char *p = "world"; // pointer

   +-----+     +---+---+---+---+---+---+
p: |  *======> | w | o | r | l | d |\0 |
   +-----+     +---+---+---+---+---+---+

So, in the code from the book, when we say:

int ages[] = {23, 43, 12, 89, 2};

We get:

ages: | 23 | 43 | 12 | 89 | 2 |

I'm going to use an illegal statement for the purpose of explanation - if we could have said:

int *ages = {23, 43, 12, 89, 2}; // The C grammar prohibits initialised array
                                 // declarations being assigned to pointers, 
                                 // but I'll get to that

It would have resulted in:

      +---+     +----+----+----+----+---+
ages: | *=====> | 23 | 43 | 12 | 89 | 2 |
      +---+     +----+----+----+----+---+

Both of these can be accessed the same way later on - the first element "23" can be accessed by ages[0], regardless of whether it's an array or a pointer. So far so good.

However, when we want to get the count we run in to problems. C doesn't know how big arrays are - it only knows how big (in bytes) the variables it knows about are. This means, with the array, you can work out the size by saying:

int count = sizeof(ages) / sizeof(int);

or, more safely:

int count = sizeof(ages) / sizeof(ages[0]);

In the array case, this says:

int count = the number of bytes in (an array of 6 integers) / 
                 the number of bytes in (an integer)

which correctly gives the length of the array. However, for the pointer case, it will read:

int count = the number of bytes in (**a pointer**) /
                 the number of bytes in (an integer)

which is almost certainly not the same as the length of the array. Where pointers to arrays are used, we need to use another method to work out how long the array is. In C, it is normal to either:

  • Remember how many elements there were:

    int *ages = {23, 43, 12, 89, 2}; // Remember you can't actually
                                     // assign like this, see below
    int ages_length = 5;
    for (i = 0 ; i < ages_length; i++) {
  • or, keep a sentinel value (that will never occur as an actual value in the array) to indicate the end of the array:

    int *ages = {23, 43, 12, 89, 2, -1}; // Remember you can't actually
                                         // assign like this, see below
    for (i = 0; ages[i] != -1; i++) {

    (this is how strings work, using the special NUL value '\0' to indicate the end of a string)

Now, remember that I said you can't actually write:

    int *ages = {23, 43, 12, 89, 2, -1}; // Illegal

This is because the compiler won't let you assign an implicit array to a pointer. If you REALLY want to, you can write:

    int *ages = (int *) (int []) {23, 43, 12, 89, 2, -1}; // Horrible style 

But don't, because it is extremely unpleasant to read. For the purposes of this exercise, I would probably write:

    int ages_array[] = {23, 43, 12, 89, 2, -1};
    int *ages_pointer = ages_array;

Note that the compiler is "decaying" the array name to a pointer to it's first element there - it's as if you had written:

    int ages_array[] = {23, 43, 12, 89, 2, -1};
    int *ages_pointer = &(ages_array[0]);

However - you can also dynamically allocate the arrays. For this example code, it will become quite wordy, but we can do it as a learning exercise. Instead of writing:

int ages[] = {23, 43, 12, 89, 2};

We could allocate the memory using malloc:

int *ages = malloc(sizeof(int) * 5); // create enough space for 5 integers
if (ages == NULL) { 
   /* we're out of memory, print an error and exit */ 
ages[0] = 23;
ages[1] = 43;
ages[2] = 12;
ages[3] = 89;
ages[4] = 2;

Note that we then need to free ages when we're done with the memory:


Note also that there are a few ways to write the malloc call:

 int *ages = malloc(sizeof(int) * 5);

This is clearer to read for a beginner, but generally considered bad style because there are two places you need to change if you change the type of ages. Instead, you can write either of:

 int *ages = malloc(sizeof(ages[0]) * 5);
 int *ages = malloc(sizeof(*ages) * 5);

These statements are equivalent - which you choose is a matter of personal style. I prefer the first one.

One final thing - if we're changing the code over to use arrays, you might look at changing this:

int main(int argc, char *argv[]) {

But, you don't need to. The reason why is a little subtle. First, this declaration:

char *argv[]

says "there is an array of pointers-to-char called argv". However, the compiler treats arrays in function arguments as a pointer to the first element of the array, so if you write:

int main(int argc, char *argv[]) {

The compiler will actually see:

int main(int argc, char **argv)

This is also the reason that you can omit the length of the first dimension of a multidimensional array used as a function argument - the compiler won't see it.

by anonymous   2019-01-13

K&R and Stroustrup are classics, and eventually you should get them, but I don't think they are good introduction for C++ beginners. Thinking in modern C++ is thinking in classes, templates, exceptions, and streams, none of which available in C language.

I would recommend a college-level textbook on C++ like Deitel and Deitel. alt text

After playing around, you should focus on learning to write a class that behaves like a built-in class. That means providing a copy constructor, operator=, operator==, operator<<, etc.. Along the way you'll meet various concepts embedded in the language of C++. I would agree with others on Effective C++ is a must read once you are comfortable with the basics.

by Bizkitgto   2019-01-13

I'd start with Harvard's CS50 on edx, it's the best course you'll find anywhere bar none. The instructor, Dave Malan is world class. Check out CS50, and the sub r/cs50 has a lot of like minded people like you. (Note: this course is free)

Stackoverflow is your friend where you can ask any question you have or bounce ideas off of others.

Learn Java OOP (here is an excellent course): Java MOOC

Free Code Camp for web development

Build your own operating system: NAND2TETRIS

Cave of Programming : All kinds of programming

Open Source Society University: This is a solid path for those of you who want to complete a Computer Science course on your own time, for free, with courses from the best universities in the World.

r/arduino for some embedded programming fun!

.....and of course for anything under the sun: &

For BSD:

For Linux:

For x86 assembly: [How far down the rabbit hole do you want to go?]

Edit: Wow, my first Reddit Gold!! Thank-you so much kind people!!

Edit2: Colt Steele has a good web dev course and is highly recommended to do in parallel with freecodecamp

Edit3: The MIT Challenge is Scott Young's blog on how he completed the entire 4 year MIT Computer Science curriculum in 12 months

Edit 4: The Rails Tutorial by Michael Hartl is the Bible for learning Ruby on Rails

Edit 5: For deeper knowledge of OOP check out Sandi Metz’s POODR

Edit 4: The Bible for C Programming: K&R

by mocacola15   2019-01-13

if you wanna get a jump start on the material now then go for it. The book they're gonna make you buy is "The C programming language" by Kernighan and Ritchie. It's widely known as one of the best programming books ever written and It's actually very useful for the class, so you are going to have to buy it eventually. I wouldn't bother with anything other than that and the other books they might make you buy though



by create_a_new-account   2019-01-13

> The C programming language

he's saying to get this book

also good is this course

sign up for the free version -- its the same teacher, lectures and projects used in the Harvard classroom

its half in C and the rest in python and web programming

if you've got one dollar you can still get the basic Humble Bundle which includes "Head First C" which is pretty good
just go to that site and scroll down

by kevindong   2018-11-12
AbeBooks is a great place to buy the non-US versions of textbooks (which are almost always identical to the US version, but in grayscale rather than in color).

For instance, on Amazon, the K&R C Programming book goes for $28.52 used, $61.74 new, or $28.70 for a one semester rental [0]. For a book that hasn't changed since 1988, these prices are absurd.

While as on AbeBooks, the international edition goes for $10-11 [1].



by exoticmatter   2018-11-10

Well, assuming str is the name of an array of char allocated somehow, you only need scanf("%s",str) - no ampersand.

As for documentation, .

by CSMastermind   2018-11-10

Senior Level Software Engineer Reading List

Read This First

  1. Mastery: The Keys to Success and Long-Term Fulfillment


  1. Patterns of Enterprise Application Architecture
  2. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions
  3. Enterprise Patterns and MDA: Building Better Software with Archetype Patterns and UML
  4. Systemantics: How Systems Work and Especially How They Fail
  5. Rework
  6. Writing Secure Code
  7. Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries

Development Theory

  1. Growing Object-Oriented Software, Guided by Tests
  2. Object-Oriented Analysis and Design with Applications
  3. Introduction to Functional Programming
  4. Design Concepts in Programming Languages
  5. Code Reading: The Open Source Perspective
  6. Modern Operating Systems
  7. Extreme Programming Explained: Embrace Change
  8. The Elements of Computing Systems: Building a Modern Computer from First Principles
  9. Code: The Hidden Language of Computer Hardware and Software

Philosophy of Programming

  1. Making Software: What Really Works, and Why We Believe It
  2. Beautiful Code: Leading Programmers Explain How They Think
  3. The Elements of Programming Style
  4. A Discipline of Programming
  5. The Practice of Programming
  6. Computer Systems: A Programmer's Perspective
  7. Object Thinking
  8. How to Solve It by Computer
  9. 97 Things Every Programmer Should Know: Collective Wisdom from the Experts


  1. Hackers and Painters: Big Ideas from the Computer Age
  2. The Intentional Stance
  3. Things That Make Us Smart: Defending Human Attributes In The Age Of The Machine
  4. The Back of the Napkin: Solving Problems and Selling Ideas with Pictures
  5. The Timeless Way of Building
  6. The Soul Of A New Machine
  8. YOUTH
  9. Understanding Comics: The Invisible Art

Software Engineering Skill Sets

  1. Software Tools
  2. UML Distilled: A Brief Guide to the Standard Object Modeling Language
  3. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development
  4. Practical Parallel Programming
  5. Past, Present, Parallel: A Survey of Available Parallel Computer Systems
  6. Mastering Regular Expressions
  7. Compilers: Principles, Techniques, and Tools
  8. Computer Graphics: Principles and Practice in C
  9. Michael Abrash's Graphics Programming Black Book
  10. The Art of Deception: Controlling the Human Element of Security
  11. SOA in Practice: The Art of Distributed System Design
  12. Data Mining: Practical Machine Learning Tools and Techniques
  13. Data Crunching: Solve Everyday Problems Using Java, Python, and more.


  1. The Psychology Of Everyday Things
  2. About Face 3: The Essentials of Interaction Design
  3. Design for Hackers: Reverse Engineering Beauty
  4. The Non-Designer's Design Book


  1. Micro-ISV: From Vision to Reality
  2. Death March
  3. Showstopper! the Breakneck Race to Create Windows NT and the Next Generation at Microsoft
  4. The PayPal Wars: Battles with eBay, the Media, the Mafia, and the Rest of Planet Earth
  5. The Business of Software: What Every Manager, Programmer, and Entrepreneur Must Know to Thrive and Survive in Good Times and Bad
  6. In the Beginning...was the Command Line

Specialist Skills

  1. The Art of UNIX Programming
  2. Advanced Programming in the UNIX Environment
  3. Programming Windows
  4. Cocoa Programming for Mac OS X
  5. Starting Forth: An Introduction to the Forth Language and Operating System for Beginners and Professionals
  6. lex & yacc
  7. The TCP/IP Guide: A Comprehensive, Illustrated Internet Protocols Reference
  8. C Programming Language
  9. No Bugs!: Delivering Error Free Code in C and C++
  10. Modern C++ Design: Generic Programming and Design Patterns Applied
  11. Agile Principles, Patterns, and Practices in C#
  12. Pragmatic Unit Testing in C# with NUnit

DevOps Reading List

  1. Time Management for System Administrators: Stop Working Late and Start Working Smart
  2. The Practice of Cloud System Administration: DevOps and SRE Practices for Web Services
  3. The Practice of System and Network Administration: DevOps and other Best Practices for Enterprise IT
  4. Effective DevOps: Building a Culture of Collaboration, Affinity, and Tooling at Scale
  5. DevOps: A Software Architect's Perspective
  6. The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations
  7. Site Reliability Engineering: How Google Runs Production Systems
  8. Cloud Native Java: Designing Resilient Systems with Spring Boot, Spring Cloud, and Cloud Foundry
  9. Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation
  10. Migrating Large-Scale Services to the Cloud
by Mansaber   2018-11-10

If you're new to C, read K&R .

Once you've done that (or if you already know C) then read THE book on Unix programming