c – Qual a forma correta de declarar uma função main()?

Ambas funcionam na maioria dos compiladores. Pode depender da opção ligada e ao padrão que deseja atender.

A recomendação costuma ser usar pelo menos o padrão C99 onde estas duas formas são aceitas:

int main(void)
int main(int argc, char *argv())

Mas alguns preferem o padrão C89 que é mais compatível com compiladores não modernos (raros, mas encontrados em plataformas embarcadas). Aí o void como parâmetro pode ser evitado (sem trocadilho :P). Se for seguir o padrão do C++ ele também é evitado.

O uso do void indica que a função não tem parâmetro. Se não tiver nada, ela tem um número de parâmetro indefinidos e a implementação pode ter os parâmetros que quiser. Isto pode gerar confusão em alguns casos.

O retorno sempre deve ser int, ainda que alguns compiladores aceitem outro tipo, especialmente o void. No C89 é necessário dar o return com um número inteiro. No C99 isto pode ser implícito, ele retorna 0 para você.

Lembrando que alguns compiladores podem não estar totalmente dentro do padrão e exigir uma forma diferente.

A melhor é a segunda. A primeira é aceitável quase sempre e a última não deve ser usada.

Especificação:

5.1.2.2.1 Program startup

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

int main(void) { /* … */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

int main(int argc, char *argv()) { /* … */ }
or equivalent; or in some other implementation-defined manner.