Как правильно писать random

Стандартный рандом из C, подойдёт пишущим на GNU

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

int main() {
    srand(time(NULL));
    printf("%d\n", rand());	
    return 0;
}

Хак для пищущих под Windows

rand() на винде (mingw, msvc) возращает 15 бит, что мало. Но можно скомбинировать два вызова rand().
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

int main() {
    srand(time(NULL));
    int tmp = rand();
    printf("%d\n", (rand() << 15) ^ tmp);	
    return 0;
}
Так как генерация случайного числа теперь занимает две строчки, то разумно создать функцию выполняющую описанные действия.

Ещё больший хак

По некоторым причинам (неопределённое поведение) писать так, как написано ниже, очень нехорошо, но работает.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

int main() {
    srand(time(NULL));
    printf("%d\n", (rand() << 15) ^ rand());	
    return 0;
}

Рандом из с++11

Новый рандом в c++, нужен стандарт c++11 (флаг -std=c++11 в g++, в кодеблоксе нужно жмакнуть правильную галочку в настройках компилятора).
#include <time.h>
#include <random>
#include <iostream>

std::uniform_int_distribution<int> distr(the_min_val, the_max_val);
std::mt19937 rnd;
// std::minstd_rand rnd;
// другой возможный генератор, менее качественный, но более быстрый

int main() {
    rnd.seed(time(NULL));
    std::cout << distr(rnd) << "\n";
}

Вещественный рандом в c++11

#include <time.h>
#include <random>
#include <iostream>

std::uniform_real_distribution<double> distr(the_min_val, the_max_val);
std::mt19937 rnd;

int main() {
    rnd.seed(time(NULL));
    std::cout << distr(rnd) << "\n"; // теперь генерируем случайное вещественное число.
}
Можно использовать один и тот же mt19937 с разными распределениями.

Список литературы

Более подробно о рандоме c++11, который значительно более функциональный, чем рандом c можно почитать на cppreference.

О переносимости

Функции rand() и srand() непереносимы совсем, работают как хотят (зачастую плохо).

std::mt19937 и другие random engines стандартизированы и работают одинаково на всех компиляторах, например следующий код всегда выдаст одно и тоже число:
#include <random>
#include <iostream>
#include <cstdint>

int main() {
    std::mt19937 rnd(228); // seed можно задавать и в конструкторе
    
    std::uint_fast32_t res = rnd();
    std::cout << res << "\n"; // 1820253573
}
uint_fast32_t это самый быстрый безнаковый тип, имеющий хотя бы 32 бита, в частности его можно сохранить в uint32_t. Более подробно о типах чисел читайте на cppreference.

Однако uniform_int_distribution, uniform_real_distribution и прочие распределения работают как хотят, но стандарт гарантирует, что числа они будут выдавать с равномерной вероятностью.

О дебаге

Для дебага рекомендуется инициализировать генератор рандома не текущим временем, а какой-нибудь константой.

Это позволит получать одинаковое поведение всегда, и не будет ситуации, что у вас програма работает в один момент времени, и не работает в другой.

Написано Дмитрием Саютиным для ЛКШ.2016.Август, отредактировано в марте 2017.
Лицензируется под CC0 (public domain)