 
 
Я еще не разу не видел не-"простых циклов". Все циклы простые, но это так, из общей язвительности. 
Я прочитал решение Вашего друга, и оно (в основном) работает. В основном, поскольку модифицирует строки. В нынешних процессорах это не всегда возможно, и контролируется (я получил ошибку времени выполнения write access denied). Хотя функция и не специфицирет указатели на константы, строки по сути таковыми являются. Беда С то, что эта проблема маскируется компилятором. 
Другой его недостаток -- то, что алгоритм не совсем корректен. А именно, 
findMaxSub("123456bcaa", "aadef") подстроки 
"аа" не находит. Это поправимо, но без правки -- bug.
Попробую переписать программу по своему разумению (функция 
out(ss, count) выдает результат):
Код:
const char* mss; // max substring;
int mc; // max count
void find0(const char* s1, const char* s2) {
  int i, shift, count;
  const char* ss;
  for (shift = 0; s2[shift] != 0; ++shift) {
    // сравниваем строку s1 со сдвинутой s2
    // находим за один проход все совпавшие подстроки
    // при несовпадении, запоминаем указатель на следующий символ и срасываем счетчик
    // при совпадении -- наращиваем счетчик 
    // (указатель на начало установлен при предыдущем несовпвдении)
    ss = s1; count = 0;
    for (i = 0; s1[i] != 0 && s2[i+shift] != 0; ++i) {
      if (s1[i] == s2[i+shift]) {
        ++count;
      } else {
        if (count > mc) {
          mc = count; mss = ss;
        }
        count = 0;
        ss = s1 + (i+1);
      }
    }
    if (count > mc) {
      mc = count; mss = ss;
    }
  } 
}
void find(const char* s1, const char* s2) {
  mss = s1; mc = 0;
  find0(s1, s2);
  find0(s2, s1);
  out(mss, mc);
} 
В основном, по мотивам решения Вашего друга. Глобальные переменные -- из-за того, что лень было структуры описывать, да указатели на них туда-сюда таскать. Скорость - действительно T(n^2), ну да тут это очевидно. Поиск (
find0())повторяется два раза, фактически эмулируя отрицательный сдвиг между строками.