1) Indirection. Pointers require thinking in a few steps. Indirection is hard. It is a vital skill in any kind of programming (or especially debugging), but it does not come naturally to people who've only ever had to deal with the concrete.
2) Early on, you learn that ints and chars and floats and some_structs are fundamentally different data types. Then suddenly you're told that int%s, char%s, float%s, some_struct%s, and even void%s are fundamentally the same. Huh?
3) The fact that C uses % both to create a pointer and to dereference. These are conflicting meanings, and the unrelatedness of those two concepts is not sufficiently explained.
EDIT: Silly HN parser. I now replaced asterisks with %s.
It may be a problem with the teaching though, rather than the subject matter itself. I understand why it takes a little bit of thinking to get used to, but not why it is fundamentally hard.
Now, algorithms can be difficult to understand and many of them use pointers... Do some people confuse the 2?
I don't think the difficulty is fundamental, and I don't think anyone here claimed that it was. But it is initially challenging nonetheless.
To tie this back in to the beginning of the thread, being able to understand indirection (such as in pointers and algorithms) is a far more important skill than understanding OOP.
2) Early on, you learn that ints and chars and floats and some_structs are fundamentally different data types. Then suddenly you're told that int%s, char%s, float%s, some_struct%s, and even void%s are fundamentally the same. Huh?
3) The fact that C uses % both to create a pointer and to dereference. These are conflicting meanings, and the unrelatedness of those two concepts is not sufficiently explained.
EDIT: Silly HN parser. I now replaced asterisks with %s.