C
The language underneath everything.
C is small, fast and close to the hardware. Operating systems, databases, embedded devices and the runtimes of Python and PyTorch are written in it, and llama.cpp's core ggml library is C.
Why learn C?
Learning C teaches you how computers really work: memory, pointers and how data is laid out. That knowledge makes you better in every other language and is essential for GPU and AI performance work.
- Understand the machine: memory, pointers and the stack, with nothing hidden.
- Speed: C is the baseline other languages are measured against.
- AI runtimes: ggml, llama.cpp and many inference engines use C at their core.
Set up and run your first program
Install a compiler: GCC or Clang on Linux and macOS, or MSVC / MinGW on Windows.
gcc --version
gcc -O2 -Wall hello.c -o hello
./hello#include <stdio.h>
int main(void) {
const char *name = "Ada";
printf("Hello, AI! Welcome to C, %s.\n", name);
return 0;
}-Wall to see warnings; they often point to real bugs.Variables and types
C has a few built-in types: int, long, float, double, char. Sizes depend on the platform; use <stdint.h> types like int64_t when size matters.
#include <stdio.h>
#include <stdint.h>
int main(void) {
int layers = 32;
double lr = 3e-4;
int64_t params = 8030000000LL;
float fp16_gb = params * 2 / 1e9f;
printf("%d layers, lr %g, %.1f GB\n", layers, lr, fp16_gb);
return 0;
}Control flow and functions
if, for, while and switch work like in most C-family languages. Functions must be declared before use.
#include <stdio.h>
double params(int layers, int d) { return 12.0 * layers * d * d; }
int main(void) {
for (int i = 0; i < 3; i++) printf("epoch %d\n", i);
int bits = 8;
switch (bits) {
case 16: puts("FP16"); break;
case 8: puts("FP8"); break;
default: puts("other");
}
printf("%.2e params\n", params(32, 4096));
return 0;
}Arrays and pointers
An array is a block of memory; a pointer holds a memory address. Passing a pointer lets a function work on data without copying it, which is how fast numeric code is written.
#include <stdio.h>
void scale(float *v, int n, float k) {
for (int i = 0; i < n; i++) v[i] *= k; // modifies the caller's array
}
int main(void) {
float w[4] = {0.5f, -1.0f, 2.0f, 0.25f};
scale(w, 4, 2.0f);
for (int i = 0; i < 4; i++) printf("%.2f ", w[i]);
printf("\naddress of w[0]: %p\n", (void *)&w[0]);
return 0;
}Dynamic memory
Use malloc to allocate memory at runtime and free to release it. Forgetting free leaks memory; using memory after freeing it is a serious bug.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t n = 1 << 20; // one million floats
float *buf = malloc(n * sizeof *buf);
if (!buf) { perror("malloc"); return 1; }
for (size_t i = 0; i < n; i++) buf[i] = 1.0f;
printf("allocated %.1f MB\n", n * sizeof *buf / 1e6);
free(buf);
return 0;
}Structs
A struct groups related values. Combined with pointers, structs are how C models tensors, network layers and devices.
#include <stdio.h>
typedef struct { const char *name; int vram_gb; float tflops_fp16; } Gpu;
int main(void) {
Gpu gpus[] = {{"H100", 80, 989.0f}, {"RTX 5090", 32, 419.0f}};
for (int i = 0; i < 2; i++)
printf("%-9s %3d GB %6.0f TFLOPS\n", gpus[i].name, gpus[i].vram_gb, gpus[i].tflops_fp16);
return 0;
}AI with C
C is the language of fast inference. llama.cpp's ggml tensor library, many embedded ML runtimes and the low-level kernels behind Python libraries are written in C. Knowing C lets you read and optimise that code.
The essential libraries
Gradient descent from scratch
Learn y = 3x + 0.5 using arrays and loops.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
enum { N = 100 };
double xs[N], ys[N], w = 0, b = 0, lr = 0.1;
for (int i = 0; i < N; i++) {
xs[i] = -1 + 2.0 * i / (N - 1);
ys[i] = 3 * xs[i] + 0.5 + 0.1 * ((double)rand() / RAND_MAX - 0.5);
}
for (int step = 0; step < 500; step++) {
double gw = 0, gb = 0;
for (int i = 0; i < N; i++) {
double err = w * xs[i] + b - ys[i];
gw += 2 * err * xs[i] / N; gb += 2 * err / N;
}
w -= lr * gw; b -= lr * gb;
}
printf("w = %.2f, b = %.2f\n", w, b);
return 0;
}Call an LLM from C
A full agent in C needs an HTTP library (libcurl) and a JSON parser (such as cJSON). This example sends one chat request to a local model; an agent repeats it, parsing tool_calls from the reply and sending tool results back.
// gcc chat.c -lcurl -o chat
#include <stdio.h>
#include <curl/curl.h>
int main(void) {
const char *body =
"{\"model\":\"llama3.1\",\"messages\":[{\"role\":\"user\","
"\"content\":\"Explain a pointer in one sentence.\"}]}";
CURL *c = curl_easy_init();
if (!c) return 1;
struct curl_slist *h = curl_slist_append(NULL, "Content-Type: application/json");
curl_easy_setopt(c, CURLOPT_URL, "http://localhost:11434/v1/chat/completions");
curl_easy_setopt(c, CURLOPT_HTTPHEADER, h);
curl_easy_setopt(c, CURLOPT_POSTFIELDS, body);
CURLcode rc = curl_easy_perform(c); // prints the JSON reply to stdout
if (rc != CURLE_OK) fprintf(stderr, "error: %s\n", curl_easy_strerror(rc));
curl_slist_free_all(h);
curl_easy_cleanup(c);
return 0;
}For the full agent loop, parse the reply with cJSON, check choices[0].message.tool_calls, run the matching C function and append a tool message before calling again.
ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.C learning roadmap
Tick items off as you go. Your progress is saved in this browser.
Beginner
Intermediate
Advanced
Projects to build
C cheat sheet
| Task | Syntax |
|---|---|
printf("%d\n", x); | |
| Array | int a[4] = {1,2,3,4}; |
| Pointer | int *p = &x; |
| Allocate | p = malloc(n * sizeof *p); |
| Struct | typedef struct { int x; } P; |
| Loop | for (int i = 0; i < n; i++) |
Common mistakes
- Reading or writing past the end of an array is undefined behaviour and may not crash right away.
- Every
mallocneeds exactly onefree. - Strings need room for the terminating
\0.
Where to go next
- Beej's Guide to C — free and friendly
- cppreference (C) — reference
- ggml — tensor library
On TensorCore.si: C++ volume, CUDA volume.
Keyboard: [ previous language · ] next language · / search the library