Learn C

Why C, and What a Program Really Is

Why Learn C When AI Can Write Code

In this lesson

  • Give four honest reasons to learn C in 2026.
  • Explain what AI coding tools changed, and what they did not.
  • Use an assistant as a tutor without skipping the practice.

Let us take this question head on, because you are almost certainly asking it. Zara asked an assistant for a C program that reverses a piece of text. She got one in three seconds. It looked tidy.

It ran on the word hello and printed olleh. Then she ran it on an empty line and the program died. She could not tell why, because she could not read the seven lines that mattered.

That gap is what this lesson is about. Not "AI is bad". Not "AI will take your job". Just the plain question of what you gain by understanding the code in front of you.

Reason one: you cannot check what you do not understand

An assistant is a very fast junior developer who never says "I am not sure". It will hand you a crashing program with total confidence. Someone has to read that code. Someone has to say "this loop runs one step too far".

That someone is you. Here is the exact program Zara was given. You are not expected to write this yet. You are expected to look at it once, so the rest of the lesson has something real to point at.

Example 1: the program the assistant wrote
#include <stdio.h>
#include <string.h>

void reverse(char *s)
{
    size_t i = 0;
    size_t j = strlen(s) - 1;
    while (i < j) {
        char t = s[i];
        s[i] = s[j];
        s[j] = t;
        i++;
        j--;
    }
}

int main(void)
{
    char word[64] = "hello";
    reverse(word);
    printf("[%s]\n", word);
    return 0;
}
[olleh]

It works. strlen gives the length, i starts at the front, j starts at the back, and the two letters swap until they meet. Nothing here is wrong for the word hello.

Run in Compiler
Example 2: the same program, one different input

Change one thing. Give it an empty piece of text instead of hello. Everything else is identical.

#include <stdio.h>
#include <string.h>

void reverse(char *s)
{
    size_t i = 0;
    size_t j = strlen(s) - 1;
    while (i < j) {
        char t = s[i];
        s[i] = s[j];
        s[j] = t;
        i++;
        j--;
    }
}

int main(void)
{
    char word[64] = "";
    reverse(word);
    printf("[%s]\n", word);
    return 0;
}
Segmentation fault

That line is not the program's output. It is the operating system reporting that the program touched memory it does not own, and was stopped. In the Playground the run ends with a runtime error and a non-zero exit code.

The cause is one character. strlen("") is 0, so strlen(s) - 1 is 0 minus 1. But size_t is a type that cannot hold a negative number.

Instead of minus one, j becomes the largest number that type can hold. The loop then runs about eighteen quintillion times, and dies on the first step. You will meet this type in Module 2 and this exact trap in Module 11.

Run in Compiler
Example 3: the repair, in three lines

The fix is to measure once, and to leave immediately when there is nothing to swap.

#include <stdio.h>
#include <string.h>

void reverse(char *s)
{
    size_t len = strlen(s);
    if (len < 2) {
        return;
    }
    size_t i = 0;
    size_t j = len - 1;
    while (i < j) {
        char t = s[i];
        s[i] = s[j];
        s[j] = t;
        i++;
        j--;
    }
}

int main(void)
{
    char empty[8] = "";
    char one[8] = "a";
    char word[8] = "hello";

    reverse(empty);
    reverse(one);
    reverse(word);

    printf("[%s] [%s] [%s]\n", empty, one, word);
    return 0;
}
[] [a] [olleh]

Three inputs, three correct answers, no crash. The assistant could have written this. It did not, because nobody asked it what should happen to an empty line. Zara would have asked, because Zara tests edge cases first.

Run in Compiler
Example 4: the bug that is still there

Now the harder point. Example 3 does not crash, and it is still wrong for most of the world's text. It reverses bytes, and a Bangla letter is not one byte.

#include <stdio.h>
#include <string.h>

void show_bytes(const char *label, const char *s)
{
    printf("%s (%zu bytes):", label, strlen(s));
    for (size_t i = 0; i < strlen(s); i++) {
        printf(" %02X", (unsigned char)s[i]);
    }
    printf("\n");
}

int main(void)
{
    char city[32] = "ঢাকা";
    show_bytes("before", city);

    size_t i = 0;
    size_t j = strlen(city) - 1;
    while (i < j) {
        char t = city[i];
        city[i] = city[j];
        city[j] = t;
        i++;
        j--;
    }

    show_bytes("after ", city);
    return 0;
}
before (12 bytes): E0 A6 A2 E0 A6 BE E0 A6 95 E0 A6 BE
after  (12 bytes): BE A6 E0 95 A6 E0 BE A6 E0 A2 A6 E0

Four Bangla letters, twelve bytes. Reversing the bytes does not reverse the letters. It shreds them, and the terminal prints replacement marks.

No compiler warns you. No test fails unless somebody wrote one. You only catch this bug if you know what a byte is. That is Module 2 and Module 10 of this track.

Run in Compiler

So the uncomfortable summary. AI makes weak code less bad for everybody. It does not make the strongest programmers much stronger. The people who gain most already know what correct code looks like. They can steer it, reject a bad answer and repair a broken one.

Reason two: C is the floor under everything

Look at what C is holding up while you read this page.

What stands on C: your code, runtimes, system libraries, the kernel, hardware Your Python, JavaScript or Java program the layer most courses start at Language runtimes: CPython, Node.js, the JVM written in C and C++ System libraries: glibc, OpenSSL, SQLite, zlib written in C The kernel: Linux, XNU on macOS, Windows NT written in C Hardware: the processor, memory, the disk machine instructions and bytes three layers of C
Figure 1. Learn Python and you learn a tool. Learn C and you learn what the tool stands on.

Operating systems are C. Databases are C: PostgreSQL, MySQL, SQLite, Redis. Language runtimes are C: CPython runs your Python, and it is a C program. Networking gear is C, so the router in your house runs C right now.

Embedded systems are C too. These are small computers hidden inside other things: microwave ovens, smart meters, drones, car engine controllers and pacemakers. Anything with a chip and a strict power budget tends to be C. C lets you see exactly what the machine will do.

Every "why is my Python program slow" question eventually gets a C level answer. Memory, addresses, bytes, the stack. You can spend years not knowing. You will spend those years guessing.

Reason three: C makes every other language easier

C is small. The 1989 standard had 32 keywords. C17, the version this track uses, has 44, and most of the extra ten you may never type. Java reserves more than fifty words. Python 3.12 has 35.

Once you truly know C's handful, a lot of other languages stop looking new. Their loops are C loops. Their if statements are C if statements. Their curly braces are C curly braces. Even the languages that reject C's memory model, like Rust, borrowed its shape.

There is a second effect that matters more. Learners who start with Python often hit a wall later, when they finally meet pointers and memory. Learners who start with C hit that wall on day one. They climb it while the programs are ten lines long, which is the cheapest time to climb anything.

Reason four: contests, lab exams and interviews

Contests, university lab exams and job interviews all judge the same two things. They judge data structures and algorithms. C and C++ are the languages where those ideas hide the least.

An array in C is a block of memory with its items side by side. A linked list is a chain of addresses. Nothing is doing secret work behind your back. When an interviewer asks "what does this cost", you answer from what you can see.

Note

Most contests, including ICPC and Codeforces, accept C and C++ among other languages. Everything you learn here transfers to C++ with very little friction. That is why the Progsity CP course shares these same lessons.

What AI changed, and what it did not

Here is a fair summary rather than a motivational poster.

What AI changedWhat it did not change
Writing repetitive setup code is now fastDeciding what to build is still on you
Looking up syntax is instantFixing a bug still needs understanding
Learning has a tutor that never gets tiredSkill still comes from your own practice
Small scripts are nearly freeDesigning a large system is still hard
A first draft arrives in secondsSomeone has to notice the empty-string case

How to use an assistant while you learn

None of this is an argument for switching the tools off. It is an argument for a method. Here is one that works.

  1. Try first, always. Write your own version before you ask. Even a broken attempt changes what you notice in the answer.
  2. Ask why, not what. "Why does this crash on an empty line" teaches you something. "Write me a reverse function" teaches you nothing.
  3. Paste your error message, not your problem. An assistant is very good at explaining expected ';' before 'return'. Let it do that, then fix the line yourself.
  4. Ask for three inputs that would break it. This is the single most useful prompt while learning. You are training the habit Zara already has.
  5. Read every line before you run it. If a line is a mystery, ask about that line. A program you cannot explain is a program you cannot debug.
  6. Never paste a solution into a graded problem. Not because you would be caught. Because the practice is the entire product you are paying for.

Use the tool a lot. Use it as a tutor who never sleeps and never gets bored of your questions. Write the code yourself first. Get it wrong yourself first. You will build the one thing a tool cannot hand you: judgment.

Where this is used

  • The Linux kernel. Around 30 million lines, mostly C, started by Linus Torvalds in 1991. It is what boots your Android phone and most of the internet's servers. When your program asks for a file, it is C code that answers.
  • CPython. The standard Python interpreter is a C program. Every Python line you will ever write is read and executed by C. Its performance work happens in C, not in Python.
  • SQLite. One C file, about 250,000 lines, in your browser, your phone and most aircraft entertainment systems. It is the most widely deployed database in the world. Its test suite is far larger than the code.
  • Redis. The in-memory data store behind countless web backends, written in C since 2009. Progsity uses it for caching and rate limits. So C code sits on the path of this page.

Common mistakes

1. Running generated code before reading it.

size_t j = strlen(s) - 1;   /* looks harmless */

There is no compiler message here at all, which is what makes it dangerous. The program builds cleanly and dies at run time with Segmentation fault. The fix is the habit, not the line: read every line, and ask what happens when the input is empty.

2. Asking for the answer instead of the explanation.

"Write a program that reverses a string" gets you Example 1. "Explain why my loop crashes on an empty string" gets you the idea of unsigned wraparound. You will use that idea for thirty years. Same tool, very different return.

3. Trusting that "it compiled" means "it is correct".

int average = total / count;   /* compiles perfectly */

The compiler checks grammar, not meaning. If count is zero this builds without a word and then fails at run time. You will meet this idea properly in the next lesson but one.

4. Copying a solution into a graded problem.

There is no error message for this either. The cost arrives later, in a lab exam or an interview. There the problem is small and the help is gone. Use the hint ladder in these lessons instead: hint one, hint two, then the solution.

Brain teaser

Look again at Example 1, the program the assistant wrote. Work out, on paper and without running anything, what it does for each of these three inputs.

  1. An empty piece of text, "".
  2. A single letter, "a".
  3. The Bangla word "ঢাকা", which is four letters and twelve bytes.

For each one, say whether it crashes, prints the wrong thing, or is fine. Then say which of the three an ordinary test would have caught.

Ask what strlen returns in each case, then what strlen(s) - 1 becomes when strlen(s) is 0. For the third input, count bytes, not letters.

Exercise 1Easy

On paper, write your four reasons for learning C, in your own words, in one sentence each. Do not copy the four headings above.

Rules. One sentence per reason. Each sentence must name something concrete: a system, a language, an exam, a kind of bug.

Check yourself. Read them to somebody who does not code. If a reason makes them ask "so what", rewrite that one.

Exercise 2Medium

Pick any assistant you use. Ask it for a C program that finds the largest number in a list. Do not run it.

Rules. Read the program line by line first. Write down three inputs that you think would break it. Empty list, one item, and all values equal are a good start.

Check yourself. Now run it on your three inputs. You are looking for one honest answer: did you predict the failure before the machine showed it to you?

Exercise 3Hard

Write a set of rules, in plain English, for reviewing generated code. A reviewer should be able to follow them and decide whether the code is safe to use.

Rules. Between five and eight rules. Every rule must be checkable by reading, not by running. "Looks clean" is not a rule. "Every loop has a stated stopping condition" is.

Check yourself. Apply your rules to Example 1. A good rule set rejects it, and names the exact reason. Keep this list; you will improve it in Module 16.

Common doubts

  • Will programming still be a job in five years?

    Nobody can promise you anything about 2031. What is visible today is that the work moved: less typing, more reviewing, connecting, securing and speeding up systems. All of that is reading work, and C is the best language for learning to read code.

  • Should I start with Python instead, since it is easier?

    Python is easier to start and harder to see through. Both paths reach the same place. C front-loads the difficulty, which means Module 11 of this track hurts and then nothing hurts again. Pick C if you want to understand the machine.

  • Is C not too old to be worth learning in 2026?

    C turned fifty and is still in the top ten of every language index. Age is the wrong measure. The right measure is what would break if it disappeared, and the honest answer is every operating system on earth.

  • Can I use an assistant on this track's graded problems?

    Nothing stops you, and you will be the one who loses. The problems are small on purpose, so the only thing they produce is your skill. Use the hint ladder first: hint one, hint two, then the worked solution.

  • How do I know when I understand a program well enough?

    Use this test. Can you predict the output before you run it, and can you name one input that would break it? If both answers are yes, you understand it. If not, you have read it, which is a different thing.

Key takeaways

  • You cannot check code you do not understand, and checking is now most of the job.
  • C is the floor under kernels, databases, language runtimes and embedded devices.
  • C is small, so learning it makes most other languages look familiar.
  • Contests, lab exams and interviews reward the visibility C gives you.
  • AI changed the speed of a first draft, not the need for judgment about it.
  • Try first, ask why, ask for the inputs that break it, read every line.

Next you will meet the people who made this language, and the problem they were stuck on. The story explains almost every odd decision in C.

Keyboard: j for the next lesson, k for the previous one, r to open the editor.