C 1

Phase 1 — C Fundamentals

We’ll build this phase from “What actually happens when I run C?” → variables/types → operators → input/output → conversion → debugging.

I’ll divide Phase 1 into 8 chapters so the concepts stay manageable without artificially splitting tiny topics.


Chapter 1 — What Is C? Source Code → Compiler → Executable

Before writing serious C, you need to understand what happens to a .c file.

Question

The following program is saved as hello.c. What will happen when it is compiled and run?

#include <stdio.h>

int main(void)
{
    // Ask the compiler to include the standard input/output declarations.
    printf("Hello, C!\n");

    // Tell the operating system that the program finished successfully.
    return 0;
}

What is the important sequence?

A. hello.c → executable → compiler → output

B. hello.c → compiler → executable → execution → output

C. hello.c → output directly

D. hello.c → linker → source code → output

Answer

B.

hello.c
   ↓
Compiler / build process
   ↓
Executable program
   ↓
Run executable
   ↓
Hello, C!

Step-by-step explanation

  1. You write source code in a file such as hello.c.

  2. The .c file contains instructions written in the C language.

  3. A compiler translates C into lower-level machine-oriented code.

  4. The build process eventually produces an executable.

  5. When you run that executable, the operating system loads and executes it.

  6. printf() produces text on the terminal.

How to read the important code

#include <stdio.h>

Think:

“I need declarations for standard input/output functionality.”

int main(void)

Think:

“This is the main function where program execution begins.”

printf("Hello, C!\n");

Think:

“Call printf and print this string.”

return 0;

Think:

“Finish main and report successful termination.”

Beginner trap

Compiler ≠ program execution.

The compiler creates/translates the program. Running the resulting executable is a separate step.

Key takeaway

C source code is compiled into an executable, and the executable is then run.


Chapter 2 — Program Structure, main(), Statements & Comments

Now let's understand the basic anatomy of a C program.

Question

What does this program print?

#include <stdio.h>

int main(void)
{
    // Store two values.
    int a = 10;
    int b = 20;

    // Calculate their sum.
    int sum = a + b;

    // Display the result.
    printf("Sum = %d\n", sum);

    return 0;
}

Answer

Sum = 30

Step-by-step explanation

int a = 10;

Creates an integer variable named a containing 10.

int b = 20;

Creates b containing 20.

int sum = a + b;

C evaluates:

10 + 20
= 30

So sum contains 30.

Then:

printf("Sum = %d\n", sum);

prints the value.

Important structure

#include <stdio.h>

int main(void)
{
    statements;
    statements;

    return 0;
}

Important pieces:

  • #include → preprocessing instruction

  • main → program's entry function

  • { } → block of code

  • ; → ends a statement

  • // → single-line comment

How to read the symbols

() → parentheses

main(void)

{} → braces

{
    ...
}

; → semicolon

int a = 10;

// → comment

// Calculate their sum.

Beginner trap

A semicolon usually ends a statement:

int x = 10;

But don't blindly put semicolons after everything. For example:

if (x > 5)
{
    printf("Yes");
}

The if itself does not end with ;.

Key takeaway

C programs are built from functions, blocks, statements, and expressions.


Chapter 3 — Identifiers, Keywords, Variables & Constants

Now we need to distinguish names, reserved words, and values.

Question

What will this print?

#include <stdio.h>

int main(void)
{
    // Create a variable whose value can change.
    int age = 20;

    // Change the value stored in age.
    age = 21;

    // Create a constant that cannot be modified.
    const int days = 7;

    printf("Age = %d\n", age);
    printf("Days = %d\n", days);

    return 0;
}

Answer

Age = 21
Days = 7

Step-by-step explanation

Initially:

age → 20

Then:

age = 21;

changes the stored value:

age → 21

But:

const int days = 7;

means days is not intended to be modified.

Variable

A variable is a named object whose stored value can change during execution.

int score = 100;
score = 150;

Constant

const int days = 7;

You cannot normally assign a new value to it:

days = 10;   // ERROR

Identifier

An identifier is a name you give to something such as:

age
days
score
main
calculateTotal

Keywords

Keywords have special meaning to C:

int
return
if
else
while
for
struct
const
void

You cannot freely use them as your own variable names.

For example:

int return = 5;   // invalid

Naming

Prefer:

student_count
total_marks
average_score

over:

x
abc
thing

when the meaning matters.

Key takeaway

Variables store changeable values; const is used when a value should not be modified.


Chapter 4 — Primitive Data Types & sizeof

A variable has both a value and a type.

Question

What is the important idea behind this output?

#include <stdio.h>

int main(void)
{
    // Create variables of different basic types.
    int age = 35;
    float temperature = 36.5f;
    double price = 99.99;
    char grade = 'A';

    printf("age = %d\n", age);
    printf("temperature = %.1f\n", temperature);
    printf("price = %.2f\n", price);
    printf("grade = %c\n", grade);

    printf("int bytes = %zu\n", sizeof(int));
    printf("double bytes = %zu\n", sizeof(double));

    return 0;
}

Will sizeof(int) and sizeof(double) necessarily be the same on every C system?

Answer

No.

Their sizes are implementation-dependent, although common systems often use:

int     → 4 bytes
double  → 8 bytes

Do not memorize those as universal laws.

Step-by-step

int

Usually used for integers:

int age = 35;

No decimal portion.

float

Floating-point number:

float temperature = 36.5f;

The f explicitly makes the literal a float.

double

Higher-precision floating-point type:

double price = 99.99;

char

Stores a character:

char grade = 'A';

Notice:

'A'

uses single quotes.

A string uses double quotes:

"Hello"

sizeof

sizeof tells you the size, in bytes, of a type or object.

sizeof(int)

or:

sizeof(age)

The result has type size_t, which is why %zu is used with printf.

Important idea

Don't think:

int = exactly 4 bytes everywhere.

Think:

int is an integer type whose size is determined by the implementation and must satisfy C's requirements.

Key takeaway

A type tells C how to interpret an object's stored data; sizeof tells you its size in bytes.


Chapter 5 — Format Specifiers & printf

C's printf() doesn't automatically understand the type of every value from the format string.

You tell it what you're printing.

Question

What is printed?

#include <stdio.h>

int main(void)
{
    // Store values of different types.
    int count = 25;
    double price = 49.95;
    char grade = 'A';

    // Use the appropriate conversion specifier for each value.
    printf("Count: %d\n", count);
    printf("Price: %.2f\n", price);
    printf("Grade: %c\n", grade);

    return 0;
}

Answer

Count: 25
Price: 49.95
Grade: A

Important format specifiers

SpecifierCommon use
%dint
%iinteger input/output context
%uunsigned integer
%ffloating-point output
%ccharacter
%sstring
%zusize_t
%ppointer

For example:

printf("%d", 25);
printf("%f", 12.5);
printf("%c", 'A');
printf("%s", "Hello");

Precision

printf("%.2f", 49.956);

prints approximately:

49.96

The .2 means two digits after the decimal point.

Beginner trap

Don't casually mismatch format specifiers and arguments.

For example, don't treat:

double x = 12.5;

as though it were an int.

C's variadic functions such as printf rely heavily on you supplying compatible arguments.

Key takeaway

The format specifier tells printf how to interpret the corresponding argument.


Chapter 6 — Operators & Expressions

Now we start actually computing things.

Question

Guess the output.

#include <stdio.h>

int main(void)
{
    // Create two integer operands.
    int a = 10;
    int b = 3;

    // Perform several arithmetic operations.
    int sum = a + b;
    int difference = a - b;
    int product = a * b;
    int quotient = a / b;
    int remainder = a % b;

    printf("%d %d %d %d %d\n",
           sum, difference, product, quotient, remainder);

    return 0;
}

Answer

13 7 30 3 1

Step-by-step

Addition:

10 + 3 = 13

Subtraction:

10 - 3 = 7

Multiplication:

10 × 3 = 30

Division:

10 / 3 = 3

Why not 3.333...?

Because both operands are int.

This is integer division.

Remainder:

10 % 3 = 1

because:

10 = 3 × 3 + 1

Main arithmetic operators

+    addition
-    subtraction
*    multiplication
/    division
%    remainder

Assignment

This:

x = 10;

means:

Store 10 in x.

It does not mean mathematical equality.

Increment/decrement

x++;
x--;

means:

increase x by 1
decrease x by 1

Comparison operators

Later, these become extremely important:

==    equal
!=    not equal
>     greater than
<     less than
>=    greater than or equal
<=    less than or equal

Logical operators

&&    AND
||    OR
!     NOT

Key takeaway

An expression produces a value, and operators determine how those values are combined or compared.


Chapter 7 — Precedence, Associativity & Type Conversion

This is where seemingly simple expressions can produce surprising results.

Question

Guess the output.

#include <stdio.h>

int main(void)
{
    // Integer division happens because both operands are integers.
    int a = 5;
    int b = 2;

    // Force floating-point division using a cast.
    double result = (double)a / b;

    // Multiplication has higher precedence than addition.
    int calculation = 10 + 2 * 3;

    // Parentheses explicitly control the order.
    int calculation2 = (10 + 2) * 3;

    printf("result = %.1f\n", result);
    printf("calculation = %d\n", calculation);
    printf("calculation2 = %d\n", calculation2);

    return 0;
}

Answer

result = 2.5
calculation = 16
calculation2 = 36

Step-by-step

First:

double result = (double)a / b;

a starts as an int:

5

The cast:

(double)a

converts it to a double:

5.0

So:

5.0 / 2
= 2.5

Now:

10 + 2 * 3

Multiplication happens first:

2 × 3 = 6

Then:

10 + 6 = 16

But:

(10 + 2) * 3

parentheses force:

12 × 3
= 36

Important distinction

These are different:

5 / 2

→ integer division → 2

versus:

5.0 / 2

→ floating-point division → 2.5

Implicit conversion

C can automatically convert values between compatible types in many expressions.

Example:

double x = 5 + 2.5;

The integer 5 participates in the floating-point calculation.

Explicit conversion

You can request conversion:

double x = (double)5 / 2;

Operator precedence

A simplified mental model:

()
*
/
%
+
-
comparisons
&&
||
=

But don't rely on memorizing a giant table.

Use parentheses when the intended order matters.

Key takeaway

Know the types of your operands, know the operator order, and use parentheses/casts when you need explicit behavior.


Chapter 8 — Input/Output: printf, scanf, fgets

Now we move from fixed values to interaction with the user.

Question

What does this program do if the user enters 25?

#include <stdio.h>

int main(void)
{
    // Reserve an integer variable for user input.
    int age;

    // Ask the user for a value.
    printf("Enter your age: ");

    // Read an integer and store it in age.
    scanf("%d", &age);

    // Display the value that was entered.
    printf("You are %d years old.\n", age);

    return 0;
}

Answer

A possible interaction is:

Enter your age: 25
You are 25 years old.

The important part

scanf("%d", &age);

You might notice something new:

&age

This means:

“Give scanf the address of age.”

We're only introducing the idea here. Pointers and addresses will be studied deeply in Phase 4.

Why does scanf need an address?

scanf needs to put the user's input into age.

Conceptually:

age
┌───────┐
│   ?   │
└───────┘

scanf receives the location of age and stores the entered value there:

age
┌───────┐
│  25   │
└───────┘

printf vs scanf

Think:

printf → program → screen
scanf  ← keyboard ← user

More accurately:

printf()
    ↓
output

scanf()
    ↑
input

fgets

For text input, fgets is often preferable to naïvely using %s with scanf.

Example:

char name[50];

fgets(name, sizeof name, stdin);

This reads a line into a character array while respecting its specified capacity.

We will study strings and buffers properly in Phase 3.

Important warning about scanf

scanf can be useful, but input handling with it has many subtleties:

  • invalid input

  • leftover characters

  • whitespace behavior

  • buffer handling

  • return value checking

Don't treat:

scanf("%d", &age);

as automatically robust input validation.

Key takeaway

printf produces output; input functions such as scanf and fgets obtain data from the user.


Chapter 9 — Escape Sequences & Basic Output Formatting

These tiny symbols appear constantly in C.

Question

Guess the exact output.

#include <stdio.h>

int main(void)
{
    // Print several pieces of formatted text.
    printf("Name:\tAlice\n");
    printf("Age:\t25\n");
    printf("She said: \"Hello!\"\n");
    printf("C:\\Programs\\test\n");

    return 0;
}

Answer

Name:   Alice
Age:    25
She said: "Hello!"
C:\Programs\test

Important escape sequences

EscapeMeaning
\nnewline
\ttab
\"double quote
\\backslash
\'single quote
\0null character

For example:

printf("Hello\nWorld");

produces:

Hello
World

Why \\?

A backslash begins an escape sequence.

Therefore:

" C:\Programs "

is not how you should represent a literal Windows-style path.

Use:

"C:\\Programs"

Key takeaway

Escape sequences let you represent special characters and formatting inside C character/string literals.


Chapter 10 — Basic Debugging & Compiler Warnings

The final Phase 1 skill is learning that the compiler is not merely an obstacle—it is one of your first debugging tools.

Question

Consider:

#include <stdio.h>

int main(void)
{
    // Declare two integer values.
    int total = 10;
    int count = 0;

    // Attempt to calculate an average.
    int average = total / count;

    // Display the result.
    printf("Average = %d\n", average);

    return 0;
}

What is wrong?

Answer

The problem is:

total / count

where:

count = 0

So the program attempts:

10 / 0

For integer division, that is undefined behavior.

The correct response isn't:

“What number does C give me?”

There is no valid result you should rely on.

Step-by-step debugging

Start with the variables:

total = 10
count = 0

Then inspect the expression:

total / count

Substitute the values mentally:

10 / 0

Problem found.

Fix the logic

For example:

if (count != 0)
{
    int average = total / count;
    printf("Average = %d\n", average);
}
else
{
    printf("Cannot calculate average.\n");
}

Compiler warnings

Compile C with strong warnings enabled.

With GCC or Clang, a common starting point is:

gcc -Wall -Wextra -Wpedantic program.c -o program

The exact warning set can vary with compiler/version/project requirements, but the principle is important:

Don't ignore compiler warnings.

Errors vs warnings

A compiler error generally prevents successful compilation.

A warning says:

“Your code may be valid, but something looks suspicious.”

Warnings can expose:

  • uninitialized variables

  • suspicious conversions

  • unused variables

  • questionable constructs

  • type mismatches

  • other potential bugs

Important distinction

The compiler cannot prove your program's logic is correct.

This can compile:

int age = 10;

if (age > 100)
{
    printf("Child");
}

The compiler doesn't necessarily know that your intended logic is wrong.

Key takeaway

Compile with warnings, investigate warnings, and debug by tracing values through expressions.


Phase 1 — Master Mental Model

You should now have this basic picture:

                C PROGRAM
                    │
                    ▼
              Source code
                 .c file
                    │
                    ▼
            Preprocessing /
              compilation /
               assembling /
                linking
                    │
                    ▼
               Executable
                    │
                    ▼
                Execution
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
       Memory              CPU work
          │
          ▼
       Variables

And when reading a simple C program, think in this order:

1. What is the type?
2. What value is stored?
3. What expression is being evaluated?
4. What operators are involved?
5. What order are they evaluated in?
6. What conversion happens?
7. Where does the result go?
8. What does printf/input do?
9. Could anything be invalid or undefined?

Phase 1 vocabulary you should now recognize

TermMeaning
Source codeHuman-written C code
CompilerTranslates C into lower-level code
ExecutableProgram that can be executed
FunctionNamed block of code
main()Program's entry function
StatementInstruction/expression statement ending where appropriate
VariableNamed object storing a value
TypeDetermines how data is interpreted
IdentifierProgrammer-defined name
KeywordReserved C word
ConstantValue intended not to be modified
ExpressionCode that produces a value
OperatorPerforms an operation
CastExplicit type conversion
printfFormatted output
scanfFormatted input
sizeofDetermines size in bytes
Undefined behaviorBehavior for which C imposes no requirements

The most important Phase 1 distinction

Don't memorize C as:

int means number, printf means print, scanf means input.

Start thinking like a C programmer:

What object exists? What is its type? What value does it contain? What operation is being performed? What conversion occurs? Where is the data going?

That mental model becomes extremely important when we reach pointers and memory in Phase 4.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.