¿Cuál es la lógica de este código?

El bucle for externo se ejecuta para cada valor de i de 2 a 99.

Dentro de ese ciclo se hacen dos cosas, la primera es un ciclo for-j, la segunda es una declaración if.

El bucle for interno verificará cada valor de j desde 2 hacia arriba a través de la raíz cuadrada de i (tenga en cuenta lo inteligente que se hace. Si j ≤ i / j, entonces j aún es menor o igual que la raíz cuadrada de i) para ver si j divide uniformemente i. Eso también es inteligente. i% j da el resto después de dividir i entre j, por lo que es un número entre 0 y j-1. ¡Entonces el operador unario! se aplica a ese número. ! 0 se convierte en 1, pero! cualquier otra cosa se convierte en 0. El número resultante, ya sea 1 o 0, se trata como un valor booleano en la instrucción if. Un 1 se considera verdadero mientras que un 0 se considera falso. Entonces, si j dividió uniformemente i, entonces se ejecuta la instrucción break, pero si j no dividió uniformemente i, entonces el break no se ejecuta, por lo que j se incrementa en 1 en el bucle for interno.

De una forma u otra, termina el bucle for interno. Si algo de j dividió uniformemente i, entonces debido a la declaración de ruptura, el valor de j seguirá siendo ≤ i / j, pero si no j dividió uniformemente i, entonces j habrá crecido hasta que j ≤ i / j ya no sea cierto. Eso se usa en la declaración final if para determinar si i es primo o no. Cuando no j dividió uniformemente i, no será el caso de que j ≤ i / j, por lo que se ejecuta la declaración de impresión.

Por inteligente que sea este programa, es más un tutorial en C ofuscado que en C. legible

Como las otras respuestas ya mencionadas, enumera los números primos entre 2 y 100. Sin embargo, esta no es la forma más rápida de hacerlo, especialmente si desea verificar el número de primos entre 1 y 1000000.

Este código verifica que el número sea primo o no con menos complejidad tym y sin el uso de la tercera variable.