У лоба - поділити число на все, на що воно може потенційно ділитися. Якщо на щось поділилося - складене. Якщо ні - просте.
Уточнення: "поділити" насправді означає знайти залишок від ділення, якщо він 0 - значить, ділиться.
for(int i=2;i<n;++i) //від 2, бо 1<2, до n-1, бо n-1<n
if(a%i==0){не просте}
if(ще не визначили, чи число просте){просте}
Ідея для оптимізації №1:
не треба ділити на числа, більші за a/2, на них точно не ділитиметься
Ідея для оптимізації №2:
не треба ділити на числа, більші за корінь квадратний з a, бо якщо число ділиться на щось, більше за корінь із себе, то воно гарантовано ділиться на інше число, менше за цей корінь
Ідея для оптимізації №3:
не треба ділити на парні, достатньо перевірити, що не ділиться на 2
Ідея для оптимізації №4:
після 2 і 3 можна ділити лише на числа, що мають вигляд 6k±1
Ідея для оптимізації №5:
не треба ділити на взагалі все, достатньо лише на прості числа
Проблема: як не оптимізуй цей алгоритм, все одно виходить складність O(n^2).
Є інші алгоритми, так звані "решета" - там ідея полягає в створенні масиву і "викреслюванні" складених чисел. Решета загалом швидші, але все одно для дуже великих чисел повільні і вимагають великих масивів.
Є також складні ознаки, що дозволяють визначити, що число є складеним (але не гарантують, що число буде простим).
Оскільки у вас виникають такі питання, раджу вам взяти алгоритм "у лоба" і оптимізувати, наскільки вийде.