C Programming tutorials, labs & MCQs.
A two-part C curriculum. Part I — Proper C Programming — is a complete C foundation with no hardware prerequisite: how a program is built and run, values and representation, expressions, control flow, functions and the call stack, arrays and strings, pointers, object lifetime and dynamic memory, structures and unions, multi-file builds and linking, the standard library, and the undefined-behaviour and debugging discipline that separates working C from code that merely compiles. Part II — C for SoC Verification, VLSI Engineers & DPI-C — builds on Part I without repeating it: fixed-width types and layout as a hardware data format, bit masks and field extraction, memory-mapped registers and read-modify-write, what volatile does and does not guarantee, where C sits around a verification environment, and DPI-C end to end — the SystemVerilog/C boundary, type mapping, open arrays, calling C from SystemVerilog and back, C reference models and scoreboards, and debugging a DPI integration when it fails.
Tutorials
Learn C Programming from beginner to advanced through structured tutorials.
Labs
Practice C Programming using progressively challenging hands-on labs.
MCQs
No MCQ papers for C Programming yet.
What C Programming is
C is a small language defined by a written standard — ISO/IEC 9899 — that says what a program must do and leaves an implementation free to achieve it however it likes. It is not a readable notation for machine instructions, and it is not a subset of C++. What makes it the language systems and semiconductor engineers keep returning to is that it exposes the machine's model of storage without pretending to be the machine: an object has an address, a size, a representation and a lifetime, and the language gives you all four directly. That is why firmware, device drivers, bootloaders, operating-system kernels and the reference models inside a verification environment are written in it. In a chip project C appears twice — once as the software that will eventually run on the silicon, and once as the model, checker or stimulus generator that a simulation calls while the silicon is still being designed.
Why it exists
Every layer below a hardware abstraction has to be written in something that can name an address and a width without apologising. A language that hides storage cannot describe a memory-mapped register, and a language that hides lifetime cannot tell you why a pointer returned from a function is worthless. C is where that control stops being an escape hatch and becomes the normal way to write. The second reason is interoperability: C's calling convention and data layout are the de facto ABI that other languages cross into, which is why SystemVerilog's foreign-function interface is called DPI-C and not DPI-anything-else. A verification engineer who can write C can put an independent reference model beside the design, exercise it over its whole input space outside the simulator, and then call the same code from the testbench — which is a different and stronger position than describing the intended behaviour twice.
The part engineers get wrong
The hardest thing about C is not pointer syntax; it is that the standard describes four different kinds of behaviour and only one of them is a promise. Defined behaviour is guaranteed. Implementation-defined behaviour has an answer your compiler must document — the signedness of plain char, for instance. Unspecified behaviour has several allowed answers and no obligation to choose consistently. Undefined behaviour has no answer at all: the standard imposes no requirement, so the compiler may assume it never happens and optimise on that assumption. A program with undefined behaviour that produces the expected output today has not been shown to work; it has been shown to have no diagnosis. This is why the curriculum classifies every claim it makes, measures the cases it can measure, and refuses to publish an output read through a dangling pointer — the number would be meaningless, and quoting it would teach the wrong lesson about what a correct program is.
Before you start
- Comfort running a command in a terminal and editing a text file
- No prior programming experience is assumed — Part I begins before the first line of code, with what a C file actually is
- For Part II, enough digital-design vocabulary to know what a register, a testbench and a simulator are; the C is taught, the hardware context is yours
What you will be able to do
- Read a declaration and say what object it creates, how large it is and how long it lives
- Predict the result of an expression by applying integer promotion and conversion rules rather than guessing
- Explain what a pointer holds, what dereferencing it means, and when it stops being valid
- Classify a behaviour as defined, implementation-defined, unspecified or undefined — and say why it matters
- Lay out a structure by hand, including padding, and explain why its size is what it is
- Build a multi-file program and explain what the preprocessor, compiler and linker each did
- Use the standard library's string and file interfaces without the bugs they are famous for
- Find a memory error with a sanitizer, and state which classes of error a clean run does not cover
- Write C that touches a memory-mapped register correctly, and justify every volatile you use
- Map a SystemVerilog type onto a C type and know which mappings the standard fixes and which it does not
- Pass arrays and packed vectors across the DPI-C boundary without reading past their bounds
- Build an independent reference model and a scoreboard that can say which side is wrong
- Diagnose a DPI failure from its symptom, including the ones that return cleanly and corrupt quietly
The learning path
- Part I — The language from zeroWhat C is and is not; values, variables, types and representation; expressions and operators; decisions and control flow; functions and program decomposition
- Part I — Data, memory and lifetimeArrays; pointers; strings; memory and object lifetime; structures, unions, enums and user-defined types
- Part I — Real programs, and correctnessBuilding multi-file programs; the standard library, files and program interfaces; undefined behaviour, sanitizers, debuggers and the habits that make C reliable
- Part II — C against hardwareC through a hardware engineer's eyes; bit-level programming; registers and memory-mapped I/O; what volatile actually guarantees, and what it does not
- Part II — C in verificationC in SoC verification; DPI-C foundations; type mapping between SystemVerilog and C; arrays and open arrays across the boundary
- Part II — Models, and what goes wrongCalling C from SystemVerilog and SystemVerilog from C; reference models and scoreboards; debugging DPI-C and simulator integration
Core concepts
New to C Programming? Work through the curriculum in order — each lesson assumes the one before it, and the sequence is what turns the roadmap above into working knowledge.
Already working with it? Use the core-concept links above to jump straight to the topic you need; each one opens the lesson that covers it in most depth.
Where this leads
Standards: ISO/IEC 9899 (the C standard) — The document that defines the language. This curriculum targets C17 (ISO/IEC 9899:2018) and names the edition whenever a claim depends on it; working drafts published by WG14 are freely available and are what most engineers actually read, but a draft is not the published standard and this track says which it is quoting · IEEE 1800 (SystemVerilog) — Governs the DPI-C boundary itself — the import and export declarations, the type mapping and the open-array layout. The C either side of that boundary is still ISO/IEC 9899; only the crossing is IEEE 1800's
