Description
C is a general-purpose imperative programming language widely used for embedded systems development.
Table of Contents:
- From Around the Web
- Tools
- Advanced Techniques
- Exceptions
- Objects in C
- Information Hiding in C
- Polymorphism and Inheritance in C
- From Embedded Artistry
- Recommended C Libraries
From Around the Web
Beginners
The classic introductory recommendation for programming in C is Brian W. Kernighan and Dennis M. Ritchie’s The C Programming Language.
If you prefer more of a course-based approach, Learn Code the Hard Way has a Learn C the Hard Waycourse. We recommend this course because it provides hands-on demos and examples.
An excellent C crash course can be found on Embedded.fm in the Embedded Wednedsays series:
- Programming C Without Knowing Assembly
- A Crash Course in C – Part 1 – Integers
- A Crash Course in C – Part 2 – Floating Point
- A Crash Course in C – Part 3 – Characters
- A Crash Course in C – Part 4 – Booleans
- A Crash Course in C – Part 5 – Arrays
- A Crash Course in C – Part 6 – The Basic Structure of C Code
- A Crash Course in C – Part 7 – Flow Control Statements
- A Crash Course in C – Part 8 – Introduction to Functions
- A Crash Course in C – Part 9 – Functions, part 2
- Logic in C – Part 1
- Logic in C – Part II, bit manipulation
- How big is an enum?
- Shortcutting Conditionals
- Scope I
- Scope II
- The Case for the Default Case – On the importance of specifying the default switch case.
The following Embedded.fm articles can be used to build upon your new C knowledge:
- Explaining the C Keyword
volatile
- Shifty Acceleration discusses shifting bits, as well as how it can be used to solve a problem with an accelerometer
- Number Representation discusses ASCII/numeric conversions
- New To Me – Range specifiers in switch statements.
- Ranges in Array Initializers – Ranges again, but this time in initializers.
- Exceptional code – an investigation into null pointers and GCC code generation
The Atoms of Confusion website provides information on making confusing code constructs more understandable. Review these common C confusion points to improve your programming abilities. Avoid unclear constructs whenever you’re able to.
For an in-depth test of your C knowledge, try figuring out the Bad C Analysis interview question.
Standard Library
The C standard library is commonly called libc, and occasionally stdlib
or cstdlib
.
For more information and relevant links, see the dedicated glossary entry.
Articles related to standard library evolution:
- Implementing #embed for C and C++ by JeanHeyd Menade
Pointers
Pointers are the foundation of C, yet many developers are intimidated by them. These resources will help you better understand pointers.
- The Basics and Pitfalls of Pointers in C
- When 4 + 1 Equals 8: An Advanced Take on Pointers in C
- How to Create Jump Tables via Function Pointer Arrays in C and C++
- How to Use C’s
offsetof()
Macro
Variadic Functions
- Stack Overflow: Forward Declaration of a Variadic Function in C
- C FAQ: Passing Around Variadic Arguments
Volatile
Embedded developers will defend their beloved volatile
keyword to the death. Make sure you understand what the keyword actually does under the hood!
If in doubt, do not declare a variable volatile
. Instead, cast it to volatile
in the particular spot where you want to suppress optimizations.
- Embedded.fm: Explaining the C Keyword
volatile
- The Trouble with Volatile explains common misconceptions about how volatile works
- Is volatile useful with threads? – the answer may suprise you
Security & Safety
MITRE outlines common weaknesses found in software written in C. Familiarize yourself with these common security flaws to improve your programming abilities.
No, strncpy()
is not a “safer” strcpy()
points out the weaknesses with strncpy()
.
Secure Coding in C and C++ (2nd Edition) (SEI Series in Software Engineering)
Microsoft is working on Checked C, a language extension project that adds static and dynamic (runtime) checking for common errors such as buffer overruns, out-of-bounds memory accesses, and incorrect type casts.
For C coding standards with a focus on safety and security, see:
Undefined Behavior
Undefined behavior abounds in the C programming language, and programmers easily trip over it. Here are some resources to improve your knowledge on undefined behavior:
- How Much memory does malloc(0) allocate? is a lightweight introduction to the topic, showing that we can’t really rely on a consistent result with
malloc(0)
- Shafik Yaghmour’s Twitter Thread demonstrates a undefined behavior examples
- John Regehr has a series of articles on Undefined Behavior in C and C++:
C11
- C11: The New C Standard summarizes the changes between C99 and C11
- Stackoverflow: Multi-threading Support in C11 provides interesting discussion about new threading support
References
- CppReference: C reference – the best C++ reference website contains a detailed reference on C as well
- GNU C Reference Manual documents C99 and the widely-used GNU C extensions
Tools
- Cscope is used to browse, search, and refactor a C project’s complete source tree
- cdecl can be used to figure out tricky declarations such as function pointers
Advanced Techniques
The following advanced techniques are reviewed below:
Bitwise Operations
The best resource for bit manipulation routines is Bit Twiddling Hacks. This code is in the public domain and is used in a variety of projects I’ve worked on.
Exceptions
You can implement exception-like behavior in C with libraries. Our favorite is CException, written by the Throw the Switch team.
Objects in C
For information on how to use “objects” in C, please see this Field Atlas entry.
Information Hiding in C
We can take the previous approach to objects in C further by applying information hiding and encapsulation using opaque pointers.
For a practical example that uses this technique, see Creating a Circular Buffer in C and C++.
Polymorphism and Inheritance in C
For information on how to use polymorphism and inheritance in C, please see this Field Atlas entry.
From Embedded Artistry
Recommended C Libraries
The C Programming Language (often referred to as K&R), the seminal book on C | |
Paradigm | Imperative (procedural), structured |
---|---|
Designed by | Dennis Ritchie |
Developer | Dennis Ritchie & Bell Labs (creators); ANSI X3J11 (ANSI C); ISO/IEC JTC1/SC22/WG14 (ISO C) |
First appeared | 1972 |
Stable release | C18
/ June 2018 |
Typing discipline | Static, weak, manifest, nominal |
OS | Cross-platform |
Filename extensions | .c, .h |
Major implementations | |
K&R, GCC, Clang, Intel C, Microsoft Visual C++, Watcom C | |
Dialects | |
Cyclone, Unified Parallel C, Split-C, Cilk, C* | |
Influenced by | |
B (BCPL, CPL), ALGOL 68, Assembly, PL/I, FORTRAN | |
Influenced | |
Numerous: AMPL, AWK, csh, C++, C--, C#, Objective-C, D, Go, Java, JavaScript, Julia, Limbo, LPC, Perl, PHP, Pike, Processing, Python, Ring, Rust, Seed7, Vala, Verilog (HDL), Nim | |
|
C (/siː/, as in the letter c) is a general-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, while a static type system prevents unintended operations. By design, C provides constructs that map efficiently to typical machine instructions and has found lasting use in applications previously coded in assembly language. Such applications include operating systems and various application software for computers, from supercomputers to embedded systems.
C was originally developed at Bell Labs by Dennis Ritchie between 1972 and 1973 to make utilities running on Unix. Later, it was applied to re-implementing the kernel of the Unix operating system. During the 1980s, C gradually gained popularity. Nowadays, it is one of the most widely used programming languages, with C compilers from various vendors available for the majority of existing computer architectures and operating systems. C has been standardized by the ANSI since 1989 (see ANSI C) and by the International Organization for Standardization.
C is an imperative procedural language. It was designed to be compiled using a relatively straightforward compiler to provide low-level access to memory and language constructs that map efficiently to machine instructions, all with minimal runtime support. Despite its low-level capabilities, the language was designed to encourage cross-platform programming. A standards-compliant C program written with portability in mind can be compiled for a wide variety of computer platforms and operating systems with few changes to its source code. The language is available on various platforms, from embedded microcontrollers to supercomputers.
« Back to Glossary Index