Можно ли на C заменить X[i][j] на *((X+i)+j)?

Да, в языке программирования C можно заменить выражение X[i][j] на *((X + i) + j). Это возможно благодаря особенностям работы с указателями и адресной арифметикой в языке C.

Стандарт языка C определяет, что двумерный массив X[i][j] в памяти хранится последовательно, то есть элементы массива идут один за другим. При этом каждая строка массива занимает непрерывный участок памяти.

Выражение X[i][j] можно рассматривать как обращение к элементу, находящемуся в ячейке памяти, адрес которой можно получить с помощью двух индексов: i - номер строки и j - номер столбца.

Выражение *((X + i) + j) также позволяет обратиться к элементу X[i][j]. Здесь X - указатель на начало двумерного массива, *(X + i) приводит к элементу i-й строки, что в свою очередь эквивалентно X[i]. После этого мы прибавляем j, что приводит к элементу столбца j в i-й строке. И наконец, оператор разыменовывания * позволяет получить значение, хранящееся в указанной ячейке памяти.

Таким образом, замена X[i][j] на *((X + i) + j) идентична и выполнится корректно в языке C. Однако, необходимо помнить, что оба варианта эквивалентны только при работе с массивами фиксированного размера, так как в случае массивов переменной длины может быть нужно извлекать размеры из метаданных или оперировать с указателями на указатели.