Это зависит.Если вы объявляете массив следующим образом:
int values[m][n];
, то компилятор оптимизирует доступ, то есть использует линейный фрагмент памяти и вычисляет правильные смещения (как в вашем псевдокоде).
Но если вы объявите массив следующим образом:
int **values;
values = new int*[m];
for (size_t i = 0; i < m; ++i) values[i] = new int[n];
, то компилятор не сможет оптимизировать доступ к массиву, как
values[row][col]
// same as
*(*(values+row) + col)
Т.е. такой код дает один дополнительный доступ к памяти.А поскольку в современных архитектурах доступ к памяти на несколько порядков дороже, чем вычисление смещения, этот тип многомерных массивов менее эффективен, чем использование линейного блока памяти и вычислений (или, если возможно, компилятор вычисляет)смещения.