I did a mix of CS and EE in university, and I was really remarkably poor at one particular part - signal processing. I scraped by the first module, just about. I took a class which I can only describe as "applied DSP" - it was basically just programming the DSP theory we had done the previous semester, and I was top of the class. When we did DSP 2 the following semester with the same lecturer, I was pretty much top of the class again, without going back to basics on the theory stuff. Either I was unfairly graded in the first instance (probably some amount of this is true or I learned enough practical application during the second class to fill in the gaps where it all fell into place.
When I used to teach CS, I’d tell my students they would need to learn pointers 3 times. First, they’d hear me explain it in a lecture and think they understood it. Then they’d try and implement a linked list and realise they didn’t get it at all, and figure it all out from scratch. Then at some point it would all click and seem really easy.
Lots of stuff is like this. You learn what you do. Sitting in a lecture theatre hearing about pointers, or photography, or DSP, isn’t really learning those things. Some people are definitely better at using their imagination to actually learn things during a lecture. But it’s a long shot at the best of times I think. For everyone.
Pointers finally clicked for me when I started doing things with a normal int and treat it as a memory address. I forgot the details, but I remember making a Stack Overflow post about it. The people on Stack Overflow didn't seem too happy with my program from a software engineering standpoint, not realizing I was just trying to really test some ideas of what pointers actually are.