Many people find C language a bit "rigid" when they first encounter it.

There aren't many ready-made wrappers, not much syntactic sugar, and many things have to be written step by step yourself.

But precisely because of this, C is particularly well-suited for building a foundation.

It forces you to understand: what a variable really is, why you need to pass an address for input, how arrays work with loops, how functions pass parameters, and why pointers are always unavoidable.

If you truly master these most fundamental concepts, your understanding will be more solid whether you later continue with C++, Java, Python, or delve into operating systems, embedded systems, and data structures.

This article strings together the core fundamentals of C language in an order that is easiest for beginners to build understanding, helping you construct a complete knowledge framework.


I. Learning C: First, Grasp Three Main Threads

When starting to learn C, the easiest mistake is to treat it like memorizing vocabulary.

Memorize an if today, a for tomorrow, and then scanf, arrays, and pointers the day after.

It seems like you're learning a lot, but in your mind, it's just a pile of loose sand.

A better approach is to first grasp three main threads:

First, how data is stored.

Variables, arrays, structures, and strings essentially all address the question of "where information is placed."

Second, how the program controls flow.

Sequential execution, conditional branching, and loop repetition all answer the question of "how things are done step by step."

Third, how the program finds data.

This will run through scanf, function parameter passing, arrays, pointers, and even file operations.

As long as you learn along these three main threads, many seemingly scattered knowledge points will naturally connect.


II. Variables: Why Programs Can "Remember" Data

For a program to process data, it must first be able to store it.

And variables are the most basic "storage units" in a program.

For example:

int age = 18;

This line of code means: define an integer variable named age and store the value 18 in it.

Two fundamental concepts must be clarified first:identifiers and data types.

1. Identifiers: Naming Data

Variable names, function names, and array names are collectively called identifiers.

Identifiers are not written arbitrarily; they must meet basic rules:

  • Composed of letters, digits, and underscores
  • Cannot start with a digit
  • Cannot have the same name as a keyword
  • Case-sensitive

For example:

int score;
int _num;
int age1;

These ways of writing are all fine.

But the following are illegal:

int 2a;
int if;

So, the first step in learning to define variables is actually learning to give data a legal and clear name.

2. Data Types: Determining What a Variable Can Hold

In C, you can't just "use any variable to hold anything"; each variable must have its type declared first.

Common basic types include:

int a = 10;       // 整数
float b = 3.14;   // 浮点数
char c = 'A';     // 字符

This means a variable not only has a name but also a restriction on "what this box is allowed to hold."

You must build this awareness in the beginner stage, as it will affect all your subsequent input, output, calculations, and memory understanding.


III. Input and Output: How Programs Interact with People

A program doesn't just calculate quietly internally; it also needs to interact with people.

The most common interaction methods are input and output.

1. Output: Displaying Results

The most common output function in C is printf.

For example:

printf("Hello C!\n");

If you want to output a variable, you need to use format specifiers:

int age = 18;
printf("%d\n", age);

Here, %d means "output in integer format."

Common format specifiers are:

  • %d: integer
  • %f: floating-point number
  • %c: character
  • %s: string

For example:

float price = 19.9;
char ch = 'A';

printf("%f\n", price);
printf("%c\n", ch);

The most important thing about printf

is not memorizing the symbols, but understanding that: when a program outputs data, it must know what type to interpret it as.

2. Input: Why scanf Often Uses &

If printf is "displaying content," then scanf is "reading user input."

For example:

int age;
scanf("%d", &age);

This line of code means: read an integer from the keyboard and store it in the variable age.

Some might wonder why it's written as &age here, not age?

The reason is simple:

scanf doesn't need to read the current value of age; it needs to "write the user's input into the location where age is stored."

So what it needs is not the value, but the address.

That is to say:

  • age represents the value in the variable
  • &age represents the address of the variable in memory

This & has actually already brought you into the core low-level thinking of C:

A program not only processes values but also the locations where values are stored.


IV. Operators and Expressions: How Programs Actually "Calculate"

With variables, input, and output in place, the program next needs to process data.

And processing data is inseparable from operators and expressions.

1. Arithmetic Operators

The most basic arithmetic operators are:

+  -  *  /  %

For example:

int a = 10;
int b = 3;

printf("%d\n", a + b);
printf("%d\n", a % b);

Among them, what deserves the most attention from beginners are / and %.

Integer Division

If both sides are integers:

15 / 4

The result is 3, not 3.75.

Because integer division only keeps the integer part.

Floating-Point Division

As long as one side is a floating-point number:

15 / 4.0

The result will then be 3.75.

Modulo Operation

15 % 4

The result is 3, representing the remainder.

% can only be used with integers, but it is very practical.

It is often used when determining odd/even, splitting digits, and handling periodic patterns.

2. Compound Assignment

Besides:

a = a + 3;

It can also be written as:

a += 3;

Similarly, there are also:

a -= 3;
a *= 3;
a /= 3;
a %= 3;

These forms are especially common in loops and array processing.

3. Logical Operations

Logical operators are used to combine multiple conditions:

  • !: NOT
  • &&: AND
  • ||: OR

For example:

if (age >= 18 && age <= 60)
{
    printf("符合条件\n");
}

So a program isn't limited to judging just one condition; it can also combine multiple conditions to make a decision together.


V. Branching: Teaching Programs to "Make Choices"

In real-world problems, many things aren't done straight through; instead, "if a certain condition is met, execute A; otherwise, execute B."

This is the role of branching structures.

1. if: The Most Basic Conditional Judgment

For example:

if (x > 0)
{
    printf("x是一个正数");
}
else
{
    printf("x不是一个正数");
}

This kind of code is almost a direct translation of natural language:

  • If the condition is true, execute the preceding code block
  • Otherwise, execute the following code block

2. Multi-branch Judgment

If there are more situations, you can use else if to extend further:

if (score >= 90)
    printf("A");
else if (score >= 80)
    printf("B");
else if (score >= 70)
    printf("C");
else if (score >= 60)
    printf("D");
else
    printf("E");

This structure is particularly suitable for handling "segmented rules," such as grade classification, fee calculation, and age grouping.

3. switch: Clearer for Handling Fixed Values

If the judgment condition is "which fixed value a variable equals,"switch will be neater:

switch (grade)
{
case 'A':
    printf("优秀");
    break;
case 'B':
    printf("良好");
    break;
default:
    printf("其他");
}

The most critical point here is break.

If you forget to write it, the program will continue executing downwards, resulting in a "fall-through" effect.


VI. Loops: Teaching Programs to Do Things Repeatedly

If branching is "making choices," then looping is "doing things repeatedly."

One of the things computers are best at is accurately executing the same set of rules many times.

And loops are precisely the embodiment of this capability.

1. while: Execute as Long as the Condition is True

int i = 1;
while (i <= 5)
{
    printf("%d\n", i);
    i++;
}

This code will output 1 to 5.

The characteristic of while

is: check first, then execute. So if the condition is false from the start, the loop might not execute even once.

2. do...while: Execute at Least Once First

int i = 1;
do
{
    printf("%d\n", i);
    i++;
} while (i <= 5);

Unlike while, do...while executes once first, then checks the condition.

3. for: The Most Common Counting Loop

for (int i = 1; i <= 5; i++)
{
    printf("%d\n", i);
}

for puts initialization, condition check, and update on one line, making the structure more compact, so it is very common in actual programming.

4. The True Value of Loops

The most common loop tasks for beginners include:

  • Summation
  • Counting
  • Finding maximum and minimum values
  • Traversing arrays
  • Outputting numbers within a range that meet a condition

So loops are not just syntax templates, but an important programming mindset:

breaking down a problem into a process of "repeatedly executing the same set of steps."


VII. Functions: Encapsulating a Block of Functionality

When a program gets longer and longer, putting all the code in main will look very messy.

This is when functions are needed.

A function can be understood as:

a block of code specifically designed to complete a certain task, which can be called repeatedly.

For example:

int add(int a, int b)
{
    int c = a + b;
    return c;
}

When calling, it's written as:

int sum = add(10, 20);
printf("%d", sum);

1. Why Functions are Important

The core value of functions is twofold:

  • Breaking down complex programs to make the structure clearer
  • Encapsulating repetitive logic to avoid writing the same code repeatedly

2. Parameters and Return Values

Parameters in a function are for passing data in.

The return value is for bringing the result out.

These two concepts seem simple, but they almost determine the entire meaning of a function.

3. Pass by Value and Pass by Address

This is a very crucial step when learning functions.

Ordinary parameter passing essentially copies the value to the function.

Even if the function modifies the parameter internally, it may not affect the external variable.

If what is passed in is an address, the situation is different.

The function can use this address to directly manipulate the memory where the external variable resides.

This is also why there is a very strong connection between functions, scanf, and pointers.

4. Arrays as Function Parameters

Passing arrays as parameters is particularly noteworthy.

Because when an array is passed as a parameter to a function, what is essentially passed is the address of the first element.

This means that modifications to array elements inside the function will often directly affect the original array.

This is very important for understanding "pass by address."


VIII. Arrays: When One Variable Isn't Enough

If a program only processes one number, one variable is enough.

But if you need to process 10 scores, 5 coordinates, or a class's list of grades, a single variable is clearly insufficient.

This is when you need arrays.

1. One-Dimensional Arrays: A Group of Data of the Same Type

int arr[5] = {1, 2, 3, 4, 5};

This means defining an array containing 5 integers.

The essence of an array can be understood as:

putting a group of data of the same type together in order.

2. Subscripts Start from 0

One of the most important rules of arrays is that subscripts start from 0.

arr[0]   // 第一个元素
arr[1]   // 第二个元素

This small detail is one of the places where beginners are most prone to making mistakes.

3. Arrays and Loops are Natural Partners

Common array operations almost always need to be paired with loops:

for (int i = 0; i < 5; i++)
{
    printf("%d\n", arr[i]);
}

Traversal, summation, searching, and counting are basically inseparable from this combination.

4. Two-Dimensional Arrays: Arrays of Arrays

For example:

int arr[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

Two-dimensional arrays are very suitable for representing two-dimensional data like tables, matrices, and report cards.


IX. Pointers: The Most Critical Step in Understanding C

Many people get nervous at the mention of pointers.

It is indeed a relatively abstract part of C, but it is also the place that best reflects the low-level characteristics of this language.

1. What is a Pointer

First, remember one sentence:

A pointer is a variable that stores an address.

For example:

int a = 10;
int *p = &a;

Here:

  • a is an ordinary variable
  • &a is the address of a
  • p is a pointer variable
  • p stores the address of a

2. What Does *p Represent

If p stores the address of a, then:

*p

means using this address to retrieve the value at the corresponding location.

For example:

printf("%d\n", *p);

The output will be 10.

3. Single-Level and Double-Level Pointers

If a pointer variable itself also has an address, then you can continue to define a "pointer to a pointer":

int a = 10;
int *p = &a;
int **pp = &p;

Although it seems convoluted, the essence is just that "an address can also be stored further."

For example:

int arr[5] = {10, 20, 30, 40, 50};

When accessing the third element:

arr[2]
*(arr + 2)

are equivalent in many scenarios.

This shows that there is a very close connection between array names and addresses, and this is precisely the key to understanding arrays, function parameter passing, and pointer arithmetic.


X. Structures, Strings, and Preprocessing

Once the previous foundations are solid, C language will gradually transition from "practicing syntax" to "expressing real objects."

1. Structures: Combining Multiple Attributes Together

For example:

struct Person
{
    char name[10];
    int age;
    float height;
};

This means a "person" can simultaneously have multiple attributes like name, age, and height.

When accessing structure members, the common way is:

person.age

If it's a structure pointer, it should be written as:

p->age

The important significance of structures is that they allow a program to not just process single values, but to start processing "an object."

2. Strings

In C language, strings are not actually an independent data type, but character arrays.

For example:

char str[] = "hello";

Its essence is several characters stored consecutively, with \0 as the end marker.

Understanding this is very important for later learning about string length, character array space, and string processing functions.

3. #define: Pre-compilation Replacement

For example:

#define PI 3.14

This is not a variable, but a text replacement performed during the preprocessing stage.

At the introductory stage, knowing this is enough:

Its core is not "storing data," but "replacing code content before compilation."


XI. Files: Letting Programs Interact with External Data

At this point in learning, the program is no longer just interacting with the keyboard and screen.

It can also read and write files.

1. The Basic Entry Point for File Operations

In C language, files are typically operated through file pointers.

For example:

FILE *fp = fopen("output.txt", "w");

This means opening a file in write mode.

2. Common Open Modes

Common modes include:

  • "r": read-only
  • "w": write-only
  • "a": append
  • "rb" / "wb": binary read/write
  • With +: combined read and write

The open mode determines what the program can do with the file.

3. Common File Read/Write Functions

For example:

  • fgetc / fputc
  • fgets / fputs

Conceptually, file operations are essentially consistent with the previous input and output:

it's just that the target of input and output has changed from the keyboard and screen to files on the disk.


XII. A Complete Picture

The content above is a path that unfolds layer by layer:

  • Starting from variables, learning to store data
  • Using input/output to establish interaction with the program
  • Using operators to process data
  • Using branching and loops to control flow
  • Using functions to break down tasks
  • Using arrays to handle batches of data
  • Using pointers to understand addresses and memory
  • Then expanding to more realistic application scenarios like structures, strings, and files

If we compare the fundamentals of C to building a house, then variables, input/output, branching, loops, functions, arrays, and pointers are the structures built up layer by layer.

Individually, none of these knowledge points are particularly complex. But only by connecting and mastering them will you truly move from "being able to write a few examples" to "beginning to understand programming."

This is also why many people find C difficult, but once they truly delve into it, they find it particularly fundamental.

Because it's not teaching you "how to piece together code," but rather:

how a computer program actually works.