← Back to Index

C Reference

0. Basics

0.1 Hello World

Standard entry point and STDOUT.

#include <stdio.h>

int main() {
    // printf prints formatted strings to STDOUT
    printf("Hello, World!\n");
    return 0; // Return 0 to indicate process success
}
TERMINAL OUTPUT
Hello, World!

0.2 Building & Running

C is a compiled language. gcc is the standard compiler.

# Compile source to a binary named 'main'
gcc -std=c11 main.c -o main

# Run the binary
./main
TERMINAL OUTPUT
Hello, World!

0.3 Comments

// Single-line comment

/* Multi-line
   comment block */
TERMINAL OUTPUT
(No output)

0.4 Imports

#include <stdio.h>  // Standard I/O (printf, etc.)
#include <stdlib.h> // Standard Library (malloc, exit)
#include <string.h> // String manipulation
#include "myheader.h" // Local header file
TERMINAL OUTPUT
(No output)

0.5 Exit Codes

#include <stdlib.h>

int main() {
    // exit(0) for success, EXIT_FAILURE (usually 1) for errors
    exit(EXIT_FAILURE);
}
TERMINAL OUTPUT
(Process exits with status 1)

0.6 Error Handling

C uses the global errno variable and perror for system errors.

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

int main() {
    FILE *f = fopen("nonexistent.txt", "r");
    if (f == NULL) {
        // Print descriptive error message to STDERR
        fprintf(stderr, "Error: %s\n", strerror(errno));
    }
    return 0;
}
TERMINAL OUTPUT
Error: No such file or directory

1. Environment & Time

1.1 Variable Declaration

C requires explicit typing.

int x = 10;           // Integer
const double PI = 3.14; // Constant
char grade = 'A';     // Character
float price = 19.99f; // Floating point
TERMINAL OUTPUT
(No output)

1.2 Integer Types

Using <stdint.h> for fixed-width types and size_t for counts.

#include <stdint.h>
#include <stddef.h>

int32_t fixed_int = 42;   // Guaranteed 32-bit signed
uint64_t big_uint = 1000; // Guaranteed 64-bit unsigned
size_t len = 10;          // Unsigned type for sizes/counts
TERMINAL OUTPUT
(No output)

1.3 Casting

Explicit type conversion.

double d = 3.99;
int i = (int)d; // Truncation to 3
TERMINAL OUTPUT
(No output)

1.4 Truthiness

In C, 0 is false, and any non-zero value is true.

#include <stdio.h>

int main() {
    if (42) printf("True\n");
    if (0) printf("False\n");
    return 0;
}
TERMINAL OUTPUT
True

1.5 Environment Vars

#include <stdlib.h>
#include <stdio.h>

int main() {
    // Retrieve environment variable
    char *path = getenv("PATH");
    if (path) printf("PATH is set\n");
    return 0;
}
TERMINAL OUTPUT
PATH is set

1.6 Time

Using <time.h> for epoch time and formatting.

#include <stdio.h>
#include <time.h>

int main() {
    time_t now = time(NULL); // Current epoch seconds
    struct tm *t = localtime(&now);
    char buf[64];
    strftime(buf, sizeof(buf), "%Y-%m-%d", t);
    printf("%s\n", buf);
    return 0;
}
TERMINAL OUTPUT
2024-05-16

2. Operators & Regex

2.1 Arithmetic/Logic

int a = 10 / 3;      // Integer division (3)
int b = 10 % 3;      // Modulo (1)
int c = (1 && 0);    // Logical AND (0)
int d = (1 || 0);    // Logical OR (1)
TERMINAL OUTPUT
(No output)

2.2 Regex

Using POSIX <regex.h>.

#include <regex.h>
#include <stdio.h>

int main() {
    regex_t regex;
    // Compile regex
    if (regcomp(&regex, "^[a-z]+", REG_EXTENDED) == 0) {
        // Execute regex match
        if (regexec(&regex, "hello", 0, NULL, 0) == 0) {
            printf("Match found\n");
        }
    }
    regfree(&regex);
    return 0;
}
TERMINAL OUTPUT
Match found

3. Argument Parsing

3.1 CLI Argument Parsing

Using POSIX getopt.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int opt;
    // Parse flags -a and -b (with argument)
    while ((opt = getopt(argc, argv, "ab:")) != -1) {
        switch (opt) {
            case 'a': printf("Flag A set\n"); break;
            case 'b': printf("Value B: %s\n", optarg); break;
        }
    }
    return 0;
}
TERMINAL OUTPUT
(Depends on CLI arguments, e.g., -a -b 123)

4. Functions & Memory

4.1 Declaration/Returns

// Function declaration
int add(int a, int b) {
    return a + b;
}

int main() {
    int sum = add(5, 3);
    return 0;
}
TERMINAL OUTPUT
(No output)

4.2 References/Pointers

C uses pointers for pass-by-reference and manual memory management.

#include <stdlib.h>
#include <stdio.h>

void increment(int *n) {
    (*n)++; // Dereference and increment
}

int main() {
    // Stack allocation
    int x = 10;
    increment(&x);

    // Heap allocation
    int *p = malloc(sizeof(int));
    if (p) {
        *p = 42;
        free(p); // Always free heap memory
    }
    return 0;
}
TERMINAL OUTPUT
(No output)

5. Loops & Iteration

5.1 Basic Loops

#include <stdio.h>

int main() {
    // for loop
    for (int i = 0; i < 3; i++) printf("%d", i);
    // while loop
    int j = 0;
    while (j < 3) { j++; }
    return 0;
}
TERMINAL OUTPUT
012

5.2 Break/Continue

for (int i = 0; i < 10; i++) {
    if (i == 2) continue; // Skip 2
    if (i == 5) break;    // Stop at 5
}
TERMINAL OUTPUT
(No output)

5.3 Iterating Collections

Arrays and pointer arithmetic.

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30};
    int len = sizeof(arr) / sizeof(arr[0]);
    
    for (int i = 0; i < len; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}
TERMINAL OUTPUT
10 20 30 

6. Strings & Files

6.1 Manipulation

Using <string.h>. Strings in C are null-terminated char arrays.

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

int main() {
    char s1[20] = "Hello";
    strcat(s1, " World"); // Concatenation
    int len = strlen(s1); // Length (excluding \0)
    int cmp = strcmp(s1, "Hello World"); // Comparison (0 if equal)
    printf("%s (len: %d)\n", s1, len);
    return 0;
}
TERMINAL OUTPUT
Hello World (len: 11)

6.2 Path Joining

Using snprintf for safe path construction.

#include <stdio.h>

int main() {
    char path[256];
    const char *dir = "/usr";
    const char *file = "bin";
    snprintf(path, sizeof(path), "%s/%s", dir, file);
    printf("%s\n", path);
    return 0;
}
TERMINAL OUTPUT
/usr/bin

6.3 Streaming I/O

Using fread and fwrite.

#include <stdio.h>

void write_binary() {
    FILE *f = fopen("data.bin", "wb");
    int data = 12345;
    fwrite(&data, sizeof(int), 1, f);
    fclose(f);
}

void read_binary() {
    FILE *f = fopen("data.bin", "rb");
    int data;
    if (fread(&data, sizeof(int), 1, f) == 1) {
        printf("Read: %d\n", data);
    }
    fclose(f);
}
TERMINAL OUTPUT
Read: 12345

6.4 Read to Memory

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *f = fopen("test.txt", "r");
    fseek(f, 0, SEEK_END);
    long size = ftell(f);
    rewind(f);

    char *buf = malloc(size + 1);
    fread(buf, 1, size, f);
    buf[size] = '\0';
    
    fclose(f);
    free(buf);
    return 0;
}
TERMINAL OUTPUT
(No output)

7. Binary & Bitwise

7.1 Allocation/Packing

Using struct with alignment attributes.

#include <stdint.h>
#include <stdio.h>

struct __attribute__((packed)) Packet {
    uint8_t  type;
    uint32_t payload;
};

int main() {
    printf("Size: %zu\n", sizeof(struct Packet)); // Size: 5
    return 0;
}
TERMINAL OUTPUT
Size: 5

7.2 Bitwise Ops

uint8_t a = 0x0F & 0xF0; // AND (0x00)
uint8_t b = 0x0F | 0xF0; // OR  (0xFF)
uint8_t c = 1 << 3;      // Shift Left (8)
uint8_t d = 0x0F ^ 0x01; // XOR (0x0E)
TERMINAL OUTPUT
(No output)

7.3 Hex Conversion

#include <stdio.h>

int main() {
    int val = 255;
    printf("%x\n", val); // To hex string: ff

    int parsed;
    sscanf("ff", "%x", &parsed); // From hex string: 255
    return 0;
}
TERMINAL OUTPUT
ff

8. Collections & JSON

8.1 Lists/Maps/Sets

Custom linked list example.

#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

void insert(struct Node **head, int val) {
    struct Node *new_node = malloc(sizeof(struct Node));
    new_node->data = val;
    new_node->next = *head;
    *head = new_node;
}
TERMINAL OUTPUT
(No output)

8.2 JSON Parsing

Example using cJSON.

#include <stdio.h>
#include <cJSON.h>

int main() {
    const char *json_str = "{\"name\":\"C\", \"year\":1972}";
    cJSON *json = cJSON_Parse(json_str);
    if (json) {
        cJSON *name = cJSON_GetObjectItemCaseSensitive(json, "name");
        if (cJSON_IsString(name)) {
            printf("Name: %s\n", name->valuestring);
        }
        cJSON_Delete(json);
    }
    return 0;
}
TERMINAL OUTPUT
Name: C

9. Systems & Networking

9.1 TCP

POSIX Sockets TCP client.

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

void tcp_client() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(80),
    };
    inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr);
    
    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
        write(sock, "GET / HTTP/1.1\r\n\r\n", 18);
    }
    close(sock);
}
TERMINAL OUTPUT
(No output)

9.2 UDP

POSIX Sockets UDP client.

#include <sys/socket.h>
#include <netinet/in.h>

void udp_client() {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(1234),
    };
    sendto(sock, "hi", 2, 0, (struct sockaddr *)&addr, sizeof(addr));
}
TERMINAL OUTPUT
(No output)

9.3 Concurrency

Using pthreads.

#include <pthread.h>
#include <stdio.h>

void *task(void *arg) {
    printf("Thread running\n");
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, task, NULL);
    pthread_join(thread, NULL);
    return 0;
}
TERMINAL OUTPUT
Thread running

9.4 SQLite

#include <sqlite3.h>
#include <stdio.h>

int main() {
    sqlite3 *db;
    if (sqlite3_open(":memory:", &db) == SQLITE_OK) {
        sqlite3_exec(db, "SELECT 42;", NULL, NULL, NULL);
        printf("Database opened\n");
        sqlite3_close(db);
    }
    return 0;
}
TERMINAL OUTPUT
Database opened