A quick-reference instruction sheet covering the fundamentals of ANSI C programming.
C is a general-purpose, compiled programming language developed in the early 1970s. It sits close to the hardware, giving you direct control over memory and system resources.
.c extension; headers use .hgcc main.c -o main)main() function;#include <stdio.h> /* standard I/O library */
/* main() is the entry point of every C program */
int main(void) {
printf("Hello, World!\n");
return 0; /* 0 = success */
}
Compile and run:
gcc main.c -o main
./main
<stdio.h> (I/O), <stdlib.h> (memory, exit), <string.h> (strings), <math.h> (maths).int age = 30; /* whole number */
float temp = 36.6f; /* single-precision decimal */
double pi = 3.14159265; /* double-precision decimal */
char grade = 'A'; /* single character */
int active = 1; /* C has no bool: 0=false, 1=true */
/* Constants — value cannot change */
const int MAX = 100;
#define PI 3.14159 /* preprocessor constant */
| Type | Size (typical) | Range / Use |
|---|---|---|
char | 1 byte | Single character or small integer |
int | 4 bytes | Whole numbers (~±2 billion) |
long | 4–8 bytes | Larger whole numbers |
float | 4 bytes | ~6–7 decimal digits of precision |
double | 8 bytes | ~15 decimal digits of precision |
unsigned int | 4 bytes | Non-negative integers only |
int a = 10, b = 3;
a + b /* 13 */
a - b /* 7 */
a * b /* 30 */
a / b /* 3 — integer division truncates */
a % b /* 1 — modulus (remainder) */
a++ /* post-increment: use then add 1 */
++a /* pre-increment: add 1 then use */
a == b /* equal */
a != b /* not equal */
a < b /* less than */
a > b /* greater than */
a && b /* logical AND */
a || b /* logical OR */
!a /* logical NOT */
x += 5; /* x = x + 5 */
x -= 2; /* x = x - 2 */
x *= 3; /* x = x * 3 */
x /= 4; /* x = x / 4 */
#include <stdio.h>
int main(void) {
int age;
char name[50];
/* printf — formatted output */
printf("Enter your name: ");
/* scanf — formatted input */
scanf("%s", name);
scanf("%d", &age); /* & gives scanf the address to write to */
printf("Hello, %s! You are %d years old.\n", name, age);
return 0;
}
| Format specifier | Type |
|---|---|
%d | int |
%f | float / double |
%c | char |
%s | string (char array) |
%p | pointer address |
%ld | long |
\n | newline |
\t | tab |
int score = 75;
if (score >= 90) {
printf("A\n");
} else if (score >= 75) {
printf("B\n");
} else {
printf("C or below\n");
}
int day = 2;
switch (day) {
case 1: printf("Monday\n"); break;
case 2: printf("Tuesday\n"); break;
case 5: printf("Friday\n"); break;
default: printf("Other day\n"); break;
}
int max = (a > b) ? a : b; /* condition ? if_true : if_false */
for (int i = 0; i < 5; i++) {
printf("%d\n", i);
}
/* 0 1 2 3 4 */
int i = 0;
while (i < 5) {
printf("%d\n", i);
i++;
}
int i = 0;
do {
printf("%d\n", i);
i++;
} while (i < 5); /* always runs at least once */
break to exit a loop early, and continue to skip to the next iteration.#include <stdio.h>
/* Function declaration (prototype) — tells compiler about the function */
int add(int a, int b);
int main(void) {
printf("%d\n", add(3, 4)); /* 7 */
return 0;
}
/* Function definition */
int add(int a, int b) {
return a + b;
}
/* void function — no return value */
void greet(char *name) {
printf("Hello, %s!\n", name);
}
int nums[5] = {10, 20, 30, 40, 50};
nums[0]; /* 10 — zero-indexed */
nums[4]; /* 50 */
nums[2] = 99; /* update value */
/* Iterate with a for loop */
for (int i = 0; i < 5; i++) {
printf("%d\n", nums[i]);
}
/* 2D array */
int grid[2][3] = {{1,2,3}, {4,5,6}};
grid[1][2]; /* 6 */
#include <string.h>
/* A string is a char array ending with '\0' */
char name[20] = "Alice";
char greeting[] = "Hello"; /* size inferred */
strlen(name); /* 5 — length (not counting '\0') */
strcpy(dest, src); /* copy src into dest */
strcat(dest, src); /* append src to dest */
strcmp(a, b); /* 0 if equal, <0 or >0 otherwise */
strncpy(dest, src, 10); /* safer: copy at most n chars */
A pointer stores the memory address of another variable.
int x = 42;
int *ptr = &x; /* ptr holds the address of x */
printf("%p\n", ptr); /* prints the address */
printf("%d\n", *ptr); /* 42 — dereference: read the value at the address */
*ptr = 99; /* change x through the pointer */
printf("%d\n", x); /* 99 */
/* Passing a pointer to a function allows it to modify the original */
void double_it(int *n) {
*n = *n * 2;
}
double_it(&x); /* x is now 198 */
/* Array name is a pointer to its first element */
int arr[] = {1, 2, 3};
int *p = arr;
printf("%d\n", *(p + 1)); /* 2 — pointer arithmetic */
& means "address of" — * means "value at address" (dereference).A struct groups related variables of different types under one name.
#include <stdio.h>
#include <string.h>
/* Define the struct type */
struct Person {
char name[50];
int age;
float height;
};
int main(void) {
/* Declare and initialise */
struct Person p1;
strcpy(p1.name, "Alice");
p1.age = 30;
p1.height = 1.68f;
printf("%s is %d years old.\n", p1.name, p1.age);
/* Pointer to struct — use -> to access members */
struct Person *ptr = &p1;
printf("%.2f\n", ptr->height);
return 0;
}
/* typedef makes the syntax cleaner */
typedef struct {
char name[50];
int age;
} Person;
Person p2 = {"Bob", 25}; /* no 'struct' keyword needed */
Use <stdlib.h> to allocate memory on the heap at runtime.
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int n = 5;
/* malloc — allocate n ints, uninitialised */
int *arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
fprintf(stderr, "Allocation failed\n");
return 1;
}
for (int i = 0; i < n; i++)
arr[i] = i * i;
/* realloc — resize the allocation */
arr = (int *)realloc(arr, 10 * sizeof(int));
/* calloc — allocate and zero-initialise */
int *zeroed = (int *)calloc(n, sizeof(int));
/* free — ALWAYS free when done */
free(arr);
free(zeroed);
return 0;
}
malloc / calloc must have a matching free. Forgetting to free memory causes memory leaks. Never access a pointer after freeing it.