C Notes
Learn the fundamental syntax rules of C programming — statements, expressions, semicolons, code blocks, whitespace handling, and common syntax errors explained with examples.
Every spoken language has grammar rules — rules about sentence structure, punctuation, and word order. Programming languages are no different. Syntax is the set of rules that defines how C programs must be written so the compiler can understand them. Get the syntax right, and your program compiles. Break a single rule, and you get a syntax error.
The good news? C's syntax is remarkably consistent. Once you learn the patterns, you'll find them repeated everywhere in the language. Let's break down every important syntax rule you need to know.
Statements in C
A statement is a complete instruction that tells the computer to perform a specific action. Statements are the building blocks of any C program.
Types of Statements
| Statement Type | Example | Purpose |
|---|---|---|
| Declaration | int x; | Create a variable |
| Assignment | x = 10; | Store a value |
| Expression | x + y; | Evaluate (often has side effects) |
| Function call | printf("Hi"); | Execute a function |
| Control flow | if (x > 0) {...} | Branch or loop |
| Jump | return 0; | Transfer control |
| Null | ; | Do nothing (placeholder) |
| Compound | { ... } | Group multiple statements |
Every Statement Ends with a Semicolon
This is the most fundamental syntax rule in C. Every simple statement must end with a semicolon (;). The semicolon is a statement terminator — it tells the compiler where one statement ends.
int age = 25; // declaration statement
age = age + 1; // assignment statement
printf("Age: %d\n", age); // function call statement
return 0; // jump statementWhat Happens Without a Semicolon?
int x = 10 // ERROR: missing semicolon
int y = 20; // compiler gets confused starting hereThe compiler sees int x = 10 int y = 20; and produces an error because it can't figure out where the first statement ends.
Expressions in C
An expression is any combination of variables, constants, operators, and function calls that evaluates to a single value. Expressions are the computational heart of C.
// These are all expressions:
5 // literal expression (value: 5)
x // variable expression (value: whatever x holds)
x + y // arithmetic expression
x > 0 // relational expression (value: 1 or 0)
x = 10 // assignment expression (value: 10)
func(a, b) // function call expression (value: return value)
x > 0 ? x : -x // conditional expressionExpression Statements
When you add a semicolon to an expression, it becomes an expression statement:
Operator Precedence (Quick Reference)
| Priority | Operators | Associativity | ||
|---|---|---|---|---|
| 1 (highest) | () [] -> . | Left to right | ||
| 2 | ! ~ ++ -- * & sizeof | Right to left | ||
| 3 | * / % | Left to right | ||
| 4 | + - | Left to right | ||
| 5 | << >> | Left to right | ||
| 6 | < <= > >= | Left to right | ||
| 7 | == != | Left to right | ||
| 8 | & (bitwise AND) | Left to right | ||
| 9 | ^ (bitwise XOR) | Left to right | ||
| 10 | `\ | ` (bitwise OR) | Left to right | |
| 11 | && | Left to right | ||
| 12 | `\ | \ | ` | Left to right |
| 13 | ?: | Right to left | ||
| 14 | = += -= etc. | Right to left | ||
| 15 (lowest) | , | Left to right |
Tip: When in doubt about precedence, use parentheses to make your intent clear.
Code Blocks (Compound Statements)
A code block is a group of statements enclosed in curly braces { }. Blocks create a new scope and are used wherever C expects a single statement but you need to execute multiple statements.
#include <stdio.h>
int main() {
int score = 85;
if (score >= 80) {
// This is a code block
printf("Great job!\n");
printf("You scored: %d\n", score);
printf("Grade: B+\n");
}
// Blocks create new scopes
{
int temp = 100; // only exists in this block
printf("Temp: %d\n", temp);
}
// printf("%d", temp); // ERROR: temp is out of scope
return 0;
}Great job! You scored: 85 Grade: B+ Temp: 100
Important Rules About Blocks
- Blocks do not end with a semicolon after the closing
} - Variables declared inside a block are local to that block
- Blocks can be nested to any depth
if,else,for,while, and functions all use blocks
// CORRECT — no semicolon after }
if (x > 0) {
printf("positive");
}
// CORRECT — function body
int add(int a, int b) {
return a + b;
}
// WRONG — don't put semicolon after block
// (it won't always cause an error, but it's incorrect style)Semicolons — The Complete Story
Semicolons are everywhere in C, but the rules are consistent:
Where Semicolons ARE Required
int x = 5; // after declarations
x = x + 1; // after assignment statements
printf("hello"); // after function calls as statements
return 0; // after return
break; // after break
continue; // after continue
goto label; // after goto
do {
// body
} while (condition); // after do-while (the only loop that needs it)
struct Point { int x; int y; }; // after struct/union definitionWhere Semicolons are NOT Used
#include <stdio.h> // preprocessor directives — no semicolon
#define MAX 100 // preprocessor directives — no semicolon
if (condition) { } // after if
else { } // after else
for (;;) { } // after for
while (condition) { } // after while
int func() { } // after function bodyThe Null Statement
A lone semicolon is a valid null statement — it does nothing. While occasionally useful, it's often a source of bugs:
Whitespace in C
Whitespace includes spaces, tabs, and newline characters. C is largely whitespace-insensitive — you have freedom in how you format your code, with a few exceptions.
Whitespace is Ignored Between Tokens
// All of these are IDENTICAL to the compiler:
int x=5;
int x = 5;
int x = 5 ;
// Even this works (though never do this):
int
x
=
5
;Where Whitespace IS Required
Whitespace is necessary to separate tokens that would otherwise merge:
int x; // ✓ space between 'int' and 'x'
// intx; // ✗ compiler sees 'intx' as one identifier
return 0; // ✓ space between 'return' and '0'
// return0; // ✗ compiler sees 'return0' as an identifierWhere Whitespace is NOT Allowed
// Inside identifiers:
int student_age; // ✓
// int student age; // ✗ two separate tokens
// Inside string literals (whitespace is preserved):
printf("Hello World"); // includes the space
// Inside numeric literals:
int x = 1000000; // ✓
// int x = 1 000 000; // ✗ not validIndentation — For Humans, Not the Compiler
C doesn't care about indentation, but humans do. Consistent indentation makes code readable:
Both compile identically, but one is maintainable and the other is a nightmare.
Preprocessor Directives
Preprocessor directives start with # and are processed before compilation. They have their own syntax rules:
#include <stdio.h> // system header
#include "myfile.h" // local header
#define PI 3.14159 // macro definition
#ifdef DEBUG // conditional compilation
#endif // end of conditional blockRules for Preprocessor Directives
- Must start with
#(can have whitespace before it) - No semicolon at the end
- Each directive occupies one line (use
\for continuation) - Processed top-to-bottom before compilation
// Multi-line macro with backslash continuation
#define PRINT_VALUES(a, b) \
printf("a = %d\n", a); \
printf("b = %d\n", b)Function Syntax
Functions in C follow a consistent pattern:
return_type function_name(parameter_list) {
// declarations
// statements
return value;
}Complete Example
#include <stdio.h>
// Function declaration (prototype)
int maximum(int a, int b);
int main() {
int x = 15, y = 20;
int result = maximum(x, y);
printf("Maximum: %d\n", result);
return 0;
}
// Function definition
int maximum(int a, int b) {
if (a > b)
return a;
else
return b;
}Maximum: 20
Common Syntax Errors and How to Fix Them
Error 1: Missing Semicolon
// ERROR
int x = 5
int y = 10;
// FIX
int x = 5;
int y = 10;Error 2: Mismatched Braces
// ERROR
if (x > 0) {
printf("positive");
// missing closing brace
// FIX
if (x > 0) {
printf("positive");
}Error 3: Using = Instead of ==
// BUG (assignment, not comparison — always true)
if (x = 5) { ... }
// FIX (comparison)
if (x == 5) { ... }Error 4: Semicolon After if Condition
// BUG — empty if body due to semicolon
if (x > 0);
{
printf("This ALWAYS executes\n");
}
// FIX
if (x > 0) {
printf("This is conditional\n");
}Error 5: Missing Parentheses
// ERROR — condition needs parentheses
// if x > 0 { }
// FIX
if (x > 0) { }C Syntax vs Other Languages
| Feature | C | Python | Java |
|---|---|---|---|
| Statement terminator | Semicolon ; | Newline | Semicolon ; |
| Code blocks | { } | Indentation | { } |
| Whitespace significance | Minimal | Critical | Minimal |
| Variable declaration | Required with type | No type needed | Required with type |
| Main function | int main() | Not required | public static void main(String[] args) |
| Comments | // and /* */ | # and """ """ | // and /* */ |
Complete Syntax Example
Here's a program demonstrating all the syntax concepts covered:
Scores: 85 92 78 96 88 Class average: 87.8 (Good)
Interview Questions on C Syntax
Q1: Why does C require semicolons at the end of statements?
C uses semicolons as statement terminators (not separators). Since C is whitespace-insensitive, the compiler needs a way to know where one statement ends and the next begins. Without semicolons, the compiler couldn't distinguish int x = 5 int y = 10 as two separate declarations. The semicolon provides unambiguous statement boundaries regardless of how code is formatted across lines.
Q2: What is the difference between an expression and a statement in C?
An expression is any valid combination of values, variables, and operators that evaluates to a result (e.g., x + 5, a > b, func()). A statement is a complete instruction that performs an action and ends with a semicolon (e.g., x = 5;, return 0;). An expression becomes an expression statement when you add a semicolon.
Q3: Is C case-sensitive? Give an example.
Yes, C is case-sensitive. int, Int, and INT are three different tokens. int is a keyword, while Int and INT are treated as regular identifiers. Similarly, printf is a standard library function, but Printf or PRINTF would be undefined unless you created them.
Q4: What is a null statement in C? When would you use it?
A null statement is just a semicolon by itself (;). It performs no action. It's used as an empty loop body (while (condition);), as a placeholder, or sometimes in for loops where all work is done in the loop header (for (i = 0; arr[i] != 0; i++);).
Q5: Why don't we put a semicolon after #include or #define?
Preprocessor directives (#include, #define, #ifdef, etc.) are not C statements — they're instructions to the preprocessor, which runs before the compiler. They use newlines as terminators instead of semicolons. Adding a semicolon after #define MAX 100; would include the semicolon in the macro replacement text, potentially causing bugs.
Summary
- C syntax defines the rules for writing valid programs that the compiler can understand.
- Every simple statement must end with a semicolon (
;) — the statement terminator. - Expressions evaluate to values; statements perform actions.
- Code blocks (
{ }) group multiple statements and create new scopes. - Whitespace is mostly insignificant in C — except where needed to separate tokens.
- Preprocessor directives follow different rules — no semicolons, one per line.
- Consistent indentation and formatting make code readable (for humans, not the compiler).
- Common syntax errors include missing semicolons, mismatched braces, and accidental null statements.
- Understanding C syntax thoroughly helps you read error messages and debug quickly.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for C Syntax Rules — Complete Guide.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, basics, syntax, c syntax rules — complete guide
Related C Programming Topics