Надо проверять на выход за границы массива. В некоторых языках программа может крэшнутся, в других может работать неправильно, читая какой-то мусор.
Можно писать так:
if ((i > 0 && a[i-1][j] > a[i][j]) || (i < n-1 && a[i+1][j] > a[i][j])) {
// текущий элемент меньше хотя бы одного соседа в том же столбце.
}
еще можно так:
if ((i == 0 || a[i-1][j] > a[i][j]) && (i == n-1 || a[i+1][j] > a[i][j])) {
// текущий элемент меньше всех соседей в том же столбце.
}
Комбинируя условия на циклы через
||
и
&&
можно составить любое нужное вам условие, которое смотрит только на существующих соседей. Но тут важен порядок операций. В C++ (да и почти везде, на самом деле) условия выполняются слева направо и прекращают выполнение, как только результат становится известен. Вот, в первом примере сначала идет проверка на
i>0
а потом обращение к массиву через логическое И. Поэтому, если программа будет обрабатывать первый элемент в строке уже на первом условии она заметит, что все условие обязательно false, ведь там стоит &&. И условие с обращением к массиву не будет произведено никогда.