Понимание указателей требует концептуального понимания архитектуры памяти вашей компьютерной системы: каждый адрес в пронумерованной памяти - это слот, в который вы можете помещать данные, а некоторые из слотов содержат номера других слотов. Это нетривиально. Что еще более важно, это не требуется для простых программ. Наличие такого концептуального понимания и способность решать проблемы с ним, на мой взгляд, показывают желание понять, что на самом деле происходит в компьютере.
Далее, чтобы свободно владеть указателями, вам нужна практика. Думайте о головоломках C как: 'из объявления ниже опишите тип a словами'
int* (*)(int*[]) (a*[])(int *[]*, float[][]**);
Что требуется, чтобы ответить на этот вопрос быстро и легко, или любой другой, который имеет дело со многими уровнями косвенности? Вам нужно потратить время, чтобы глубоко задуматься о том, что представляют собой указатели на уровне языка программирования.
Это похожая история с рекурсией. Чтобы просто пройти через рекурсивную функцию, вы должны понимать стек вызовов и то, как аргументы передаются и возвращаются. Чтобы освоить рекурсивные функции, вы должны разбить задачу на более мелкие части и решать каждую часть за частью.
Свободное владение рекурсией и указателями требует концепций, которые являются основой для написания жесткого кода. Я считаю, что самоотдача, необходимая для овладения этими концепциями, является ключевым элементом хорошего программиста. Более того, нетрудно показать пробелы в чьем-то знании концепций с помощью 10-минутного теста по программированию на тему, которая требует их. Звучит как замечательные вопросы для интервью.