Dovresti scorrere l'array elemento per elemento, confrontando gli elementi per segnalare tutti i casi "doppi".
Nel ciclo, potresti usare due contatori (i e j), il primo dei quali usato per scorrere tutti i valori una sola volta (i, da 0 a Q_ELEMENTI-1), il secondo invece usato per confrontare con quello che stai prendendo in considerazione tutti i valori NON ANCORA CONFRONTATI (j, da i+1 a Q_ELEMENTI-1).
Il fatto che j non riprende ogni volta da capo deriva dal fatto che i confronti hanno questo schema (ipotizzando un array di 5 elementi e indicando coi numeri gli indici degli elementi dell'array):
0-1 0-2 0-3 0-4 // nel primo ciclo controlliamo tutti gli abbinamenti
1-2 1-3 1-4 // 1-0 è già stato controllato nel ciclo precedente
2-3 2-4 // 2-0 e 2-1 son già stati controllati nei cicli precedenti
3-4 // 3-0, 3-1 e 3-2 son già stati controllati nei cicli precedenti
Ovviamente non avrebbe senso controllare 0-0, 1-1, 2-2 e così via, che infatti vengono saltati.
#include <stdio.h>
#include <stdlib.h>
#define Q_ELEMENTI 13
int main() {
int i, j, v[Q_ELEMENTI] = { 3,1,3,4,2,0,6,5,3,8,4,9,7 };
printf( "L'elenco dei valori:\n" );
for( i=0; i<Q_ELEMENTI; ++i )
printf( "%d%s", v[i], i!=Q_ELEMENTI-1?" ":"\n\n" );
for( i=0; i<Q_ELEMENTI; ++i ) {
for( j=i+1; j<Q_ELEMENTI; ++j ) {
if( v[i] == v[j] ) {
printf( "L'elemento #%d e' uguale all'elemento #%d (%d)\n",
i+1, j+1, v[i] );
}
}
}
printf( "\nPremi \"invio\" per lasciare il programma... " );
getchar();
return 0;
}
Ha ragione migliorabile quando ti dice che ti conviene prendere le cose un po' "alla lontana" e andare a vedere con attenzione gli argomenti che ti ha indicato.