C
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
3: Anatomy of a C Program
Let's stop talking about theory and actually build something. I want to make a tiny utility that calculates roughly how many days old a person is based on their age in years. It's a dead-simple calculation, but it's the perfect excuse to pull apart a C file and see what's actually happening under the hood.
Waiting for the entry point
If I were to just write a line of code in a file—say, printf("Days: 10000");—and try to compile it, the compiler would have a complete meltdown. It wouldn't even get to the point of complaining about syntax; it would tell me it can't find the "entry point."
C doesn't just start at line one and run down to the bottom like a Python script. It needs a specific door to walk through to start the execution. That door is always called main. Let's wrap our logic in that function and see what happens:
int main() {
printf("Days: 10000");
}
Now the compiler is happier, but we've hit a new snag. Depending on your compiler settings, you'll likely see a warning: "implicit declaration of function 'printf'". I've seen this trip up a lot of beginners. The compiler is basically saying, "I see you're trying to use printf, but I have no idea what that is or how it's supposed to work."
Asking for the blueprint
C is lean. It doesn't load every possible function into memory by default because that would make your programs bloated. If we want to use printf, we have to tell C where to find the "blueprint" (the declaration) for that function.
That's where the preprocessor comes in. I'll add a line at the very top with a hashtag. This isn't actually C code; it's an instruction to the compiler to go grab another file and paste it right here before the actual compilation starts.
#include <stdio.h>
int main() {
printf("Days: 10000");
}
stdio.h stands for "Standard Input Output." By including it, we're giving the compiler the map it needs to understand how to send text to your screen. Now the warnings are gone, but if I look closely at my main function, I notice something. I told C that main would return an int (an integer), but I didn't actually return anything.
Reporting back to the OS
Your program doesn't exist in a vacuum; it's being run by an Operating System (Windows, macOS, or Linux). When a program finishes, the OS wants to know if it finished successfully or if it crashed. This is why we use int main instead of void main—which you'll see in some old, outdated tutorials. Always use int.
Let's polish this into a real program. I'll add a variable for the age and a return 0; statement. In the world of C, returning 0 typically means "Everything went fine."
#include <stdio.h>
int main() {
int age_years = 25;
int age_days = age_years * 365;
printf("You are roughly %d days old!\n", age_days);
return 0;
}
Look at the structure we've arrived at. We have the preprocessor directive at the top, the function signature that defines our entry point, the curly braces that carve out the "body" of our logic, and a final integer returned to the system. That is the skeleton of almost every C program you will ever write.
📋 Practical Task
Build a Basic Circle Area Calculator
Using the anatomy we just explored, create a complete C program that calculates the area of a circle. You will need to:
- Include the
stdio.hheader. - Define the
mainfunction with the correct return type. - Create a variable for the radius (you can use
float radius = 5.0;). - Calculate the area (use
3.14159 * radius * radius). - Print the result to the console using
printf. - Ensure the program returns 0 to the operating system.
There are no comments for now.