178

From the number of questions posted here, it's clear that people have some pretty fundemental issues when getting their heads around pointers and pointer arithmetic.

I'm curious to know why. They've never really caused me major problems (although I first learned about them back in the Neolithic). In order to write better answers to these questions, I'd like to know what people find difficult.

So, if you're struggling with pointers, or you recently were but suddenly "got it", what were the aspects of pointers that caused you problems?

tshepang
  • 12,111
  • 21
  • 91
  • 136
The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
  • 55
    **Snarky, overstated, needlessly controversial, answer with a grain of truth:** They've been crippled---mentally maimed, I tell 'ya---by l'arning one of them "expressive" high level languages first. They shoulda started by programming on bare metal like God a Daniel Boone intended! – dmckee --- ex-moderator kitten Oct 26 '10 at 16:47
  • 3
    ...and Programmer would be better because it *will* develop into a discussion despite you best efforts. – dmckee --- ex-moderator kitten Oct 26 '10 at 16:50
  • This is argumentative and subjective, it generates N results, my difficult is your easy. It probably will work on programmers, but we are not migrating these questions there yet because the site is not out of beta. – Sam Saffron Oct 27 '10 at 06:27
  • To channel Christian Bale -- "oohhhhhhh gooooooood for youuuuuu!" Some people can and some people can't. Simple as that. – Jack Marchetti Oct 27 '10 at 16:50
  • 2
    @Sam Saffron: While I generally do agree that this is more of a programmers.SE type question, honestly it wouldn't be bad if people were willing to mark "I think it's easy" and "I hate seeing pointers" as the spam they are. – jkerian Oct 27 '10 at 17:04
  • 3
    Someone has to bring this up: "It is like a finger pointing away to the moon. Don't concentrate on the finger or you will miss all that heavenly glory" --Bruce Lee – mu is too short Nov 03 '10 at 01:43
  • I never understand them because every book on C++ and C is just a rehash of a rehash of a rehash, just like the accepted answer is a rehash of a rehash of a rehash. None of it tells us why the choice is made to use pointers and addresses rather than simply using values. There's no formative knowledge in any of the answers below; so, how can a new programmer learn to make decisions independently? This "points" to a fundamental flaw in teaching styles across the industry, overshadowed by an infectious, atypical disdain for skillful teachers and tactile learners. No wonder CIS is stalled. – Wolfpack'08 May 13 '19 at 23:59

29 Answers29

152

When I first started working with them, the biggest problem I had was the syntax.

int* ip;
int * ip;
int *ip;

are all the same.

but:

int* ip1, ip2;  //second one isn't a pointer!
int *ip1, *ip2;

Why? because the "pointer" part of the declaration belongs to the variable, and not the type.

And then dereferencing the thing uses a very similar notation:

*ip = 4;  //sets the value of the thing pointed to by ip to '4'
x = ip;   //hey, that's not '4'!
x = *ip;  //ahh... there's that '4'

Except when you actually need to get a pointer... then you use an ampersand!

int *ip = &x;

Hooray for consistency!

Then, apparently just to be jerks and prove how clever they are, a lot of library developers use pointers-to-pointers-to-pointers, and if they expect an array of those things, well why not just pass a pointer to that too.

void foo(****ipppArr);

to call this, I need the address of the array of pointers to pointers to pointers of ints:

foo(&(***ipppArr));

In six months, when I have to maintain this code, I will spend more time trying to figure out what all this means than rewriting from the ground up. (yeah, probably got that syntax wrong -- it's been a while since I've done anything in C. I kinda miss it, but then I'm a bit of a massochist)

MadhavanRP
  • 2,832
  • 1
  • 20
  • 26
Jeff Knecht
  • 2,518
  • 1
  • 14
  • 12
  • 23
    Your comment on the first one, >>*ip = 4; //sets the value of ip to '4'<< is wrong. It should be >>//sets the value of the thing pointed at by ip to '4' – aaaa bbbb Oct 26 '10 at 20:57
  • 2
    That's what I like in assembly. You have a DWORD and can treat is as int, int*, pointer to any structure or function, and everything without casts. – ruslik Oct 26 '10 at 20:59
  • @ruslik: That's very unsafe, apart from anything else. If your DWORD is an int, you can't suddenly call it an int*- cause now your program crashes. – Puppy Oct 26 '10 at 21:23
  • 1
    @DeadMG well.. anarchy means responsability :) – ruslik Oct 26 '10 at 21:35
  • @ruslik: Except you could just get a program (the compiler) to make sure that you have it right. – Puppy Oct 26 '10 at 21:48
  • 8
    Stacking too many types on top of each other is a bad idea, in any language. You may find writing "foo(&(***ipppArr));" strange in C, but writing something like "std::map,std::pair,std::tuple>>>" in C++ is also very complex. This does not mean that pointers in C or STL containers in C++ are complex. It just means that you have to use better type-definitions to make it understandable for the reader of your code. – Patrick Oct 27 '10 at 06:51
  • 21
    I sincerely can't believe an misunderstanding of the _syntax_ is the most heavily voted answer. That's the easiest part about pointers. – jason Oct 27 '10 at 13:39
  • 4
    Even reading this answer, I was tempted to get a sheet of paper and draw the picture. In C, I was always drawing pictures. – Michael Easter Oct 27 '10 at 16:06
  • 1
    Wait'll Jeff gets to function pointers.... – Tommy McGuire Oct 27 '10 at 16:56
  • 20
    @Jason What objective measure of difficulty is there other than what the majority of people find difficult? – Rupert Madden-Abbott Dec 01 '10 at 05:21
  • 1
    I think the confusion about the fact that the use of & is consistent, and the inability to follow a chain of pointers (although I'll agree it's not terribly maintainable) points to a more fundamental misunderstanding than the syntax. Trying to explain why `*` vs `&` is as consistent as `*` vs `/` if your student can't tell what the operators do in isolation is silly... even if the students will tell you over and over that they just need to know if they should use `*` or `&`. – jkerian Apr 12 '11 at 21:30
  • 2
    C++ makes this even worse -- `&` gets overloaded so that it can also be used in declarations (`int& ir(i);` declares a reference). This means that there are two symbols (`*` and `&`) with 6 meanings between them (depending on where they occur syntactically). – Mankarse May 12 '12 at 02:42
  • This. The syntax around pointers and address references kills me, and I've mentally blocked it out. I should go back and learn C++ and pointers. – CokoBWare Dec 21 '16 at 16:46
  • @MichaelEaster I would really love to see those pictures, I'm such a visual learner I wish I knew how to properly request some examples of them from you (I'm relatively new to SO) can you tweet a few to me? at debtwielder I also realize you posted this almost ten years ago... if anyone has visually pleasing examples of reading code, please share! – Robert Houghton Aug 07 '19 at 17:07
87

I suspect people are going a bit too deep in their answers. An understanding of scheduling, actual CPU operations, or assembly-level memory management isn't really required.

When I was teaching, I found the following holes in students' understanding to be the most common source of problems:

  1. Heap vs Stack storage. It is simply stunning how many people do not understand this, even in a general sense.
  2. Stack frames. Just the general concept of a dedicated section of the stack for local variables, along with the reason it's a 'stack'... details such as stashing the return location, exception handler details, and previous registers can safely be left till someone tries to build a compiler.
  3. "Memory is memory is memory" Casting just changes which versions of operators or how much room the compiler gives for a particular chunk of memory. You know you're dealing with this problem when people talk about "what (primitive) variable X really is".

Most of my students were able to understand a simplified drawing of a chunk of memory, generally the local variables section of the stack at the current scope. Generally giving explicit fictional addresses to the various locations helped.

I guess in summary, I'm saying that if you want to understand pointers, you have to understand variables, and what they actually are in modern architectures.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
jkerian
  • 16,497
  • 3
  • 46
  • 59
  • 1
    This sounds exactly like my professor for my computing 1 and 2 (data structures) course. The very first day, we filled out memory templates for some programs and followed the flow of the programs. Fictional addresses for the heap helped, and constantly being quizzed/tested on those templates really helps with an understanding of pointers. We even followed some in the data structures course for case studies. – Kizaru Oct 26 '10 at 17:39
  • 15
    IMHO, understanding stack and heap are as unnecessary as low level CPU details. Stack and heap happen to be implementation details. The ISO C spec does not have a single mention of the word "stack" and neither does K&R. – sigjuice Oct 27 '10 at 15:29
  • 1
    Honestly, you don't really need to know it anymore. They used to teach latin and greek in school. They don't anymore. Sure SOME people might need/want to know it, but overall it's not necessary. – Jack Marchetti Oct 27 '10 at 16:52
  • 4
    @sigjuice: Your objections miss the point of both the question and answer. A) K&R C is an anachronism B) ISO C is not the only language with pointers, my points 1 and 2 were developed against a non-C-based language C) 95% of the architectures (not languages) out there use the heap/stack system, it's common enough that exceptions are explained relative to it. D) The point of the question was "why don't people understand pointers", not "how do I explain ISO C" – jkerian Oct 27 '10 at 16:57
  • 1
    @John Marchetti: You don't need to know Latin and Greek to use English. (With that said, I'm disappointed in people who call themselves linguists who don't have at least a technical understanding of both) C is not in the same category for the obvious reason that there are hundreds of billions of lines of C code in production. 90% of real-world programming is maintenance. – jkerian Oct 27 '10 at 17:01
  • 9
    @John Marchetti: Even more so... given that the question was "What is the root issue with people's problem with pointers", I don't think the people asking the pointer-related questions would be terribly impressed with "You don't really need to know" as an answer. Obviously they disagree. :) – jkerian Oct 27 '10 at 17:14
  • 4
    @jkerian It might be outdated, but the three or four pages of K&R that explain pointers do so without the need for implementation details. A knowledge of implementation details is useful for various reasons, but IMHO, it should not be a prerequisite for understanding the key constructs of a language. – sigjuice Oct 27 '10 at 20:29
  • @sigjuice: If we're going to be pedantic about it, I'll point out that most of K&R's context is not guaranteed to be true by the current standard. For all practical purposes, the problem in K&R 5.2 is best described if the student can grasp stack frames (although perhaps not by name). K&R didn't skip implementation details for "purity" or "brevity", it skipped them because it assumed an audience familiar with low-level constructs. (as both authors have said). Regardless, neither the question nor the answer was actually about C. – jkerian Oct 27 '10 at 20:49
  • 3
    "Generally giving explicit fictional addresses to the various locations helped." -> +1 – fredoverflow Oct 31 '10 at 21:42
  • 1
    The heap/stack thing has nothing to do with pointer understanding anyway. Pointers can be in either and they can point into either. – M.M Oct 01 '14 at 23:37
  • 1
    MM.... my (poorly expressed, I think) answer here was trying to get at the point that it's not _just_ pointers that students generally don't understand. It is the entire C memory abstraction along with its common implementations. What I was trying to describe was the groundwork you needed to lay in order for pointers to seem "obvious". The answer was written to be somewhat opposed to the "you have to understand the architecture" answers by paring down to what I _do_ feel you need to understand about the C memory idealization. – jkerian Jul 02 '18 at 22:03
52

Proper understanding of pointers requires knowledge about the underlying machine's architecture.

Many programmers today don't know how their machine works, just as most people who know how to drive a car don't know anything about the engine.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Nice with the neutral POV, there. – dmckee --- ex-moderator kitten Oct 26 '10 at 16:52
  • 18
    @dmckee: Well, am I wrong? How many Java programmers could deal with a segfault? – Robert Harvey Oct 26 '10 at 16:54
  • 1
    @Robert Harvey: `How many Java programmers could deal with a segfault?` And there goes the neutral POV! ;-) (not saying I disagree with your comment) – Praetorian Oct 26 '10 at 17:03
  • 1
    Learning about computers from the bottom-up (started literally by looking up instructions for an HC11 and typing them in hex into an S-record) makes it fairly straightforward as to what my processor does when it sees a pointer. I've never done x86 assembly, but those concepts still hold (though they're vastly more complex nowadays) – Nick T Oct 26 '10 at 17:06
  • 5
    Are segfaults something to do with stick shift? *-- A Java Programmer* – Tom Anderson Oct 26 '10 at 17:25
  • 4
    @Robert Harvey: How many C++ programmers can write comprehensible, maintainable, leak-proof code? Hint - they're usually the same people. I don't think your beef is with Java, or with the lack of knowledge about the underlying machine, but with the long tail of programming talent :) – Merlyn Morgan-Graham Oct 26 '10 at 18:54
  • 6
    @Robert: it was meant as a genuine complement. This is a tough subject to discuss without hurting peoples feelings. And I'm afraid my comment precipitated the very conflict I thought you'd managed to avoid. *Mea cupla.* – dmckee --- ex-moderator kitten Oct 26 '10 at 18:57
  • @Merlyn: Exactly right. Unfortunately there are days when I feel like I'm at the end of that long tail ;). – Robert Harvey Oct 26 '10 at 19:11
  • 32
    I disagree; you do not need to understand the underlying architecture to get pointers (they are an abstraction, anyway). – jason Oct 26 '10 at 19:40
  • 11
    @Jason: In C, a pointer is essentially a *memory address.* Working with them safely is impossible without understanding the machine architecture. See http://en.wikipedia.org/wiki/Pointer_(computing) and http://boredzo.org/pointers/#definition – Robert Harvey Oct 26 '10 at 20:01
  • @Merlyn - good point. You could rephrase Robert's response to ask how many Java programmers really understand how their **virtual** machine works. – Steve Townsend Oct 26 '10 at 20:11
  • 5
    @Jason: You're right that you don't need to understand the architecture to get pointers, but they're trivial to understand if you understand the architecture, and a huge pain if you don't. I learned C after I spent several years writing 8502 and 6809 assembly, and I never understood why people dreaded pointers when I learned them. I thought they were just like index registers... – Ori Pessach Oct 26 '10 at 21:42
  • 5
    C pointers are an abstraction. If you stick within the "defined" bits of the standard your code will be safe without you knowing anything about the underlying architecture. It's just that in practice many kinds of things are not efficient (or even not possible) using portable standard C and so details about architecture (and compiler!) become important. But the fact is pointers are an abstraction meant to hide the underlying platform's concept of an address. Is an address 8, 16, 32, or 64 bits? Segmented? Tagged? Doesn't matter. Portable C will handle all the above. – James Iry Oct 26 '10 at 22:20
  • 1
    I don't think your analogy is as correct as it could be. It should be "… just as most *mechanics* don't know anything about an engine." (Since people who drive a car are the consumers, not the people who work on cars.) And by the way, I think that analogy would be false then. Most mechanics probably know more about cars than programmers know about computers. – Josh Leitzel Oct 27 '10 at 02:40
  • 3
    lol. After all the development in programming languages, a bunch of really smart people are still fighting over C vs Java. That's hilarious. – zengr Oct 27 '10 at 03:34
  • 1
    Exactly. I regularly see young fanatic developers that despite low-level C and pointers, but if a problem pops up at a customer, are unable to understand the memory dumps and solve the problem in the debugger, because they don't understand anymore what's actually going on. – Patrick Oct 27 '10 at 06:54
  • 1
    @Robert Harvey: No. I think those definitions you gave are bad. C pointers are an abstraction of the memory. A pointer is probably better defined as something that lets you indirectly refer to certain values. When I learned pointers I didn't need to know anything about the underlying architecture of the NeXT boxes in our computer lab because the concepts applied equally to the x86 box I had at home. – jason Oct 27 '10 at 13:47
  • 2
    @Ori Pessach: I respectfully disagree. The underlying architecture just gets in the way. If you understand pointers correctly, what you learn applies equally to 8502s and x86s. What you learned from working in assembly was _indirection_, and that is the key concept to understanding C pointers; it had nothing to do with the particular architecture. – jason Oct 27 '10 at 13:52
  • 5
    @Jason: Indirection only tells you part of the story. It doesn't help you understand the relationship between arrays and pointers, pointer arithmetic, how to write code that generates code, function pointers, the difference between pointers to the stack to pointers to the heap, or really much of anything that ends up biting you when you don't understand it. There's no substitute for a good, solid understanding of what happens at least one level of abstraction lower than the one you work with. – Ori Pessach Oct 27 '10 at 14:13
  • @Ori Pessach: None of the things that you listed is any different with knowledge of the underlying architecture. (Except maybe generating code, depending on what kind of code you're talking about.) I prefer to think of them in terms of the C abstractions. – Steve M Oct 27 '10 at 19:14
  • @Steve M: When you don't understand what's going on beneath the abstraction it might be hard to understand (for example) why, when you define two arrays and modify one of them, the other might change. The reason is that C's abstraction of memory is leaky. I've seen, time and again, people who don't have a good working knowledge of the underlying concepts stumbling over these exact problems. Abstraction is great when it works, but it gets in the way when it doesn't. I see a huge difference between the level of competence of people who understand the architecture and people who don't. – Ori Pessach Oct 28 '10 at 16:11
44

When dealing with pointers, people that get confused are widely in one of two camps. I've been (am?) in both.

The array[] crowd

This is the crowd that straight up doesn't know how to translate from pointer notation to array notation (or doesn't even know that they are even related). Here are four ways to access elements of an array:

  1. array notation (indexing) with the array name
  2. array notation (indexing) with the pointer name
  3. pointer notation (the *) with the pointer name
  4. pointer notation (the *) with the array name

 

int vals[5] = {10, 20, 30, 40, 50};
int *ptr;
ptr = vals;

array       element            pointer
notation    number     vals    notation

vals[0]     0          10      *(ptr + 0)
ptr[0]                         *(vals + 0)

vals[1]     1          20      *(ptr + 1)
ptr[1]                         *(vals + 1)

vals[2]     2          30      *(ptr + 2)
ptr[2]                         *(vals + 2)

vals[3]     3          40      *(ptr + 3)
ptr[3]                         *(vals + 3)

vals[4]     4          50      *(ptr + 4)
ptr[4]                         *(vals + 4)

The idea here is that accessing arrays via pointers seems pretty simple and straightforward, but a ton of very complicated and clever things can be done this way. Some of which can leave experienced C/C++ programmers befuddled, let alone inexperienced newbies.

The reference to a pointer and pointer to a pointer crowd

This is a great article that explains the difference and which I'll be citing and stealing some code from :)

As a small example, it can be very difficult to see exactly what the author wanted to do if you came across something like this:

//function prototype
void func(int*& rpInt); // I mean, seriously, int*& ??

int main()
{
  int nvar=2;
  int* pvar=&nvar;
  func(pvar);
  ....
  return 0;
}

Or, to a lesser extent, something like this:

//function prototype
void func(int** ppInt);

int main()
{
  int nvar=2;
  int* pvar=&nvar;
  func(&pvar);
  ....
  return 0;
}

So at the end of the day, what do we really solve with all this gibberish? Nothing.

Now we have seen the syntax of ptr-to-ptr and ref-to-ptr. Are there any advantages of one over the other? I am afraid, no. The usage of one of both, for some programmers are just personal preferences. Some who use ref-to-ptr say the syntax is "cleaner" while some who use ptr-to-ptr, say ptr-to-ptr syntax makes it clearer to those reading what you are doing.

This complexity and the seeming (bold seeming) interchangeability with references ,which is often another caveat of pointers and an error of newcomers, makes understanding pointers hard. It's also important to understand, for completion's sake, that pointers to references are illegal in C and C++ for confusing reasons that take you into lvalue-rvalue semantics.

As a previous answer remarked, many times you'll just have these hotshot programmers that think they are being clever by using ******awesome_var->lol_im_so_clever() and most of us are probably guilty of writing such atrocities at times, but it's just not good code, and it's certainly not maintainable.

Well this answer turned out to be longer than I had hoped...

David Titarenco
  • 32,662
  • 13
  • 66
  • 111
  • 6
    I think you may have given a C++ answer to a C question here... at least the second part. – detly Oct 27 '10 at 03:43
  • Pointers to pointers apply to C, as well :p – David Titarenco Oct 28 '10 at 22:30
  • 1
    Heh? I only see pointers to pointers when passing around arrays - your second example isn't really applicable to most decent C code. Also, you're dragging C into C++'s mess - references in C don't exist. – new123456 Apr 01 '11 at 01:38
  • You have to deal with pointers to pointers in many many legitimate cases. For example, when dealing with a function pointer pointing to a function that returns a pointer. Another example: a struct that can hold a variable number of other structs. And many more... – David Titarenco Apr 01 '11 at 05:44
  • 3
    "pointers to references are illegal in C" - more like "absent" :) – Kos Oct 31 '12 at 17:14
  • Can anyone explain me in detail or give any reference for `void func(int*& rpInt);` part? I seriously didn't get that. – asn Jan 04 '19 at 04:17
  • @AjaySinghNegi -- see https://stackoverflow.com/questions/3128662/reference-to-a-pointer?lq=1 – David Titarenco Jan 04 '19 at 06:36
30

I blame the quality of reference materials and the people doing the teaching, personally; most concepts in C (but especially pointers) are just plain taught badly. I keep threatening to write my own C book (titled The Last Thing The World Needs Is Another Book On The C Programming Language), but I don't have the time or the patience to do so. So I hang out here and throw random quotes from the Standard at people.

There's also the fact that when C was initially designed, it was assumed you understood machine architecture to a pretty detailed level just because there was no way to avoid it in your day-to-day work (memory was so tight and processors were so slow you had to understand how what you wrote affected performance).

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 3
    Yes. 'int foo = 5; int *pfoo = &foo; See how useful that is? OK, moving along...' I didn't really use pointers until I wrote my own double-linked list library. – John Lopez Oct 27 '10 at 02:52
  • 2
    +1. I use to tutor CS100 students and so many of their problems were solved just by going over pointers in an understandable way. – benzado Oct 27 '10 at 03:09
  • 1
    +1 for the historical context. Having started long after that time, this has never occurred to me. – Lumi May 15 '12 at 11:50
27

There is a great article supporting the notion that pointers are hard on Joel Spolsky's site - The Perils of JavaSchools.

[Disclaimer - I am not a Java-hater per se.]

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • Pointers were considered difficult long before Java came into existence and dominated the CS curriculum. – jason Oct 26 '10 at 19:39
  • 2
    @Jason - that is true but does not negate the argument. – Steve Townsend Oct 26 '10 at 19:42
  • 4
    Spolsky isn't saying that JavaSchools are the reason people find pointers difficult. He's saying they result in pointer-illiterate people with Computer Science degrees. – benzado Oct 27 '10 at 03:07
  • 1
    @benzado - fair point - my brief post would be improved if it read 'a great article supporting the notion that pointers are hard'. What the article does imply is that "having a CS degree from a 'good school'" is not as good a predictor of success as a developer as it used to be, while "understands pointers" (and recursion) still is. – Steve Townsend Oct 27 '10 at 10:51
  • 1
    @Steve Townsend: I think you're missing the point of Mr. Spolsky's argument. – jason Oct 27 '10 at 13:30
  • @Jason - possibly - what do you think that is? I will tell you if I missed it or disagree, and why. – Steve Townsend Oct 27 '10 at 13:36
  • 2
    @Steve Townsend: Mr. Spolsky is arguing that Java schools are raising a generation of programmers that don't know pointers and recursion, not that pointers are hard because of the prevalence of Java schools. As you stated "there is a great article about why this is hard" and linked to said article, it seems you have the latter interpretation. Forgive me if I'm wrong. – jason Oct 27 '10 at 13:50
  • @Jason - agreed, see my comment above in response to @benzado. Any better? perhaps this makes my response offtopic, but I really like that article and its tangential relevance led me to post. – Steve Townsend Oct 27 '10 at 13:52
  • Steve, my comment was actually for Jason. I forgot to use tweet syntax. I don't think any of us are missing the point of anything. – benzado Oct 27 '10 at 16:37
  • @benzado - I do think my original text is not quite what I meant and am editing in the revised version. – Steve Townsend Oct 27 '10 at 16:40
  • I'm not quite sure why people don't realise that Java is full of pointers. Without that, you won't get the difference between `int` and `Integer`. – Olaf Seibert Sep 09 '15 at 10:14
25

Most things are harder to understand if you're not grounded in the knowledge that's "underneath". When I taught CS it got a lot easier when I started my students on programming a very simple "machine", a simulated decimal computer with decimal opcodes whose memory consisted of decimal registers and decimal addresses. They would put in very short programs to, for example, add a series of numbers to get a total. Then they would single step it to watch what was happening. They could hold down the "enter" key and watch it run "fast".

I'm sure almost everyone on SO wonders why it is useful to get so basic. We forget what it was like not knowing how to program. Playing with such a toy computer puts in place concepts without which you can't program, such as the ideas that computation is a step-by-step process, using a small number of basic primitives to build up programs, and the concept of memory variables as places where numbers are stored, in which the address or name of the variable is distinct from the number it contains. There is a distinction between the time at which you enter the program, and the time at which it "runs". I liken learning to program as crossing a series of "speed bumps", such as very simple programs, then loops and subroutines, then arrays, then sequential I/O, then pointers and data structure. All of these are much easier to learn by reference to what a computer is really doing underneath.

Finally, when getting to C, pointers are confusing though K&R did a very good job of explaining them. The way I learned them in C was to know how to read them - right to left. Like when I see int *p in my head I say "p points to an int". C was invented as one step up from assembly language and that's what I like about it - it is close to that "ground". Pointers, like anything else, are harder to understand if you don't have that grounding.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • 1
    A good way to learn this is to program 8-bit microcontrollers. They are easy to understand. Take the Atmel AVR controllers; they are even supported by gcc. – Xenu Oct 27 '10 at 15:53
  • @Xenu: I agree. For me it was Intel 8008 and 8051 :-) – Mike Dunlavey Oct 27 '10 at 18:54
  • For me it was a custom 8-bit computer (the "Maybe") at MIT in the dim mists of time. – QuantumMechanic Apr 13 '12 at 00:09
  • Mike -- you should get your students a CARDIAC :) – QuantumMechanic Apr 13 '12 at 00:10
  • 1
    @Quantum: CARDIAC- good one, hadn't heard of that. The "Maybe" - let me guess, was that when Sussman (et al) had people reading the Mead-Conway book and fabbing their own LSI chips? That was a little after my time there. – Mike Dunlavey Apr 13 '12 at 00:30
  • Not quite. It was an 8-bit machine build from discrete TTL as part of 6.004 using Steve Ward's *Computation Structures* book. I loved the class. In a semester you went from talking how to build an `AND` gate with a couple of transistors to talking about virtual memory and paging in operating systems. You (with guidance) learned about nanocode and microcode and how by changing microcode you could have the same hardware change from a stack-based instructions set to a more typical registered-based instruction set. So cool. – QuantumMechanic Apr 13 '12 at 00:52
  • I was so great to finally understand why, when a program counter was pointing to the value `0x67` that would do a return from subroutine or whatever. On a more pop sci level I heartily recommend *Code* by Charles Petzel. Covers some of the same ground but much more accessible to laypeople. – QuantumMechanic Apr 13 '12 at 00:54
  • @Quantum: I'm jealous :) I would have loved to take that course, but I was a dumb-old Mech E. (4-bar linkages, anyone? film-boiling?, roadway transition spirals? how 'bout Wankel engines?) – Mike Dunlavey Apr 13 '12 at 01:09
18

I didn't get pointers until I read the description in K&R. Until that point, pointers didn't make sense. I read a whole bunch of stuff where people said "Don't learn pointers, they are confusing and will hurt your head and give you aneurysms" so I shied away from it for a long time, and created this unnecessary air of difficult-concept.

Otherwise, mostly what I thought was, why on earth would you want a variable that you have to go through hoops to get the value of, and if you wanted to assign stuff to it, you had to do strange things to get values to go into them. The whole point of a variable is something to store a value, I thought, so why someone wanted to make it complicated was beyond me. "So with a pointer you have to use the * operator to get at its value??? What kind of goofy variable is that?", I thought. Pointless, no pun intended.

The reason it was complicated was because I didn't understand that a pointer was an address to something. If you explain that it is an address, that it is something that contains an address to something else, and that you can manipulate that address to do useful things, I think it might clear up the confusion.

A class that required using pointers to access/modify ports on a PC, using pointer arithmetic to address different memory locations, and looking at more complicated C-code that modified their arguments disabused me of the idea that pointers were, well, pointless.

warren
  • 32,620
  • 21
  • 85
  • 124
J. Polfer
  • 12,251
  • 10
  • 54
  • 83
12

Here's a pointer/array example that gave me pause. Assume you have two arrays:

uint8_t source[16] = { /* some initialization values here */ };
uint8_t destination[16];

And your goal is to copy the uint8_t contents from source destination using memcpy(). Guess which of the following accomplish that goal:

memcpy(destination, source, sizeof(source));
memcpy(&destination, source, sizeof(source));
memcpy(&destination[0], source, sizeof(source));
memcpy(destination, &source, sizeof(source));
memcpy(&destination, &source, sizeof(source));
memcpy(&destination[0], &source, sizeof(source));
memcpy(destination, &source[0], sizeof(source));
memcpy(&destination, &source[0], sizeof(source));
memcpy(&destination[0], &source[0], sizeof(source));

The answer (Spoiler Alert!) is ALL of them. "destination", "&destination", and "&destination[0]" are all the same value. "&destination" is a different type than the other two, but it is still the same value. The same goes for the permutations of "source".

As an aside, I personally prefer the first version.

Andrew Cottrell
  • 3,312
  • 3
  • 26
  • 41
  • I prefer the first version as well (less punctuation). – sigjuice Oct 27 '10 at 20:00
  • ++ So do I, but you really need to be careful with `sizeof(source)`, because if `source` is a pointer, `sizeof` it will not be what you want. I sometimes (not always) write `sizeof(source[0]) * number_of_elements_of_source` just to stay far away from that bug. – Mike Dunlavey Mar 31 '11 at 14:40
  • destination, &destination, &destination [0] are not at all the same - but each will through a different mechanism be converted to the same void* when used in memcpy. However, when used as the argument of sizeof, you will get two different results, and three different results is possible. – gnasher729 May 09 '14 at 17:25
  • I thought the address of operator was required? – MarcusJ Aug 05 '15 at 03:42
7

I should start out by saying that C and C++ were the first programming languages I learned. I started with C, then did C++ in school, a lot, and then went back to C to become fluent in it.

The first thing that confused me about pointers when learning C was the simple:

char ch;
char str[100];
scanf("%c %s", &ch, str);

This confusion was mostly rooted in having been introduced to using reference to a variable for OUT arguments before pointers were properly introduced to me. I remember that I skipped writing the first few examples in C for Dummies because they were too simple only to never get the first program I did write to work (most likely because of this).

What was confusing about this was what &ch actually meant as well as why str didn't need it.

After I became familiar with that I next remember being confused about dynamic allocation. I realized at some point that having pointers to data wasn't extremely useful without dynamic allocation of some type, so I wrote something like:

char * x = NULL;
if (y) {
     char z[100];
     x = z;
}

to try to dynamically allocate some space. It didn't work. I wasn't sure that it would work, but I didn't know how else it might work.

I later learned about malloc and new, but they really seemed like magical memory generators to me. I knew nothing about how they might work.

Some time later I was being taught recursion again (I'd learned it on my own before, but was in class now) and I asked how it worked under the hood -- where were the separate variables stored. My professor said "on the stack" and lots of things became clear to me. I had heard the term before and had implemented software stacks before. I had heard others refer to "the stack" long before, but had forgotten about it.

Around this time I also realized that using multidimensional arrays in C can get very confusing. I knew how they worked, but they were just so easy to get tangled up in that I decided to try to work around using them whenever I could. I think that the issue here was mostly syntactic (especially passing to or returning them from functions).

Since I was writing C++ for school for the next year or two I got a lot of experience using pointers for data structures. Here I had a new set of troubles -- mixing up pointers. I would have multiple levels of pointers (things like node ***ptr;) trip me up. I'd dereference a pointer the wrong number of times and eventually resort to figuring out how many * I needed by trial and error.

At some point I learned how a program's heap worked (sort of, but good enough that it no longer kept me up at night). I remember reading that if you look a few bytes before the pointer that malloc on a certain system returns, you can see how much data was actually allocated. I realized that the code in malloc could ask for more memory from the OS and this memory was not part of my executable files. Having a decent working idea of how malloc works is a really useful.

Soon after this I took an assembly class, which didn't teach me as much about pointers as most programmers probably think. It did get me to think more about what assembly my code might be translated into. I had always tried to write efficient code, but now I had a better idea how to.

I also took a couple of classes where I had to write some lisp. When writing lisp I wasn't as concerned with efficiency as I was in C. I had very little idea what this code might be translated into if compiled, but I did know that it seemed like using lots of local named symbols (variables) made things a lot easier. At some point I wrote some AVL tree rotation code in a little bit of lisp, that I had a very hard time writing in C++ because of pointer issues. I realized that my aversion to what I thought were excess local variables had hindered my ability to write that and several other programs in C++.

I also took a compilers class. While in this class I flipped ahead to the advanced material and learned about static single assignment (SSA) and dead variables, which isn't that important except that it taught me that any decent compiler will do a decent job of dealing with variables which are no longer used. I already knew that more variables (including pointers) with correct types and good names would help me keep things straight in my head, but now I also knew that avoiding them for efficiency reasons was even more stupid than my less micro-optimization minded professors told me.

So for me, knowing a good bit about the memory layout of a program helped a lot. Thinking about what my code means, both symbolically and on the hardware, helps me out. Using local pointers that have the correct type helps a lot. I often write code that looks like:

int foo(struct frog * f, int x, int y) {
    struct leg * g = f->left_leg;
    struct toe * t = g->big_toe;
    process(t);

so that if I screw up a pointer type it is very clear by the compiler error what the problem is. If I did:

int foo(struct frog * f, int x, int y) {
    process(f->left_leg->big_toe);

and got any pointer type wrong in there, the compiler error would be a whole lot more difficult to figure out. I would be tempted to resort to trial and error changes in my frustration, and probably make things worse.

Robert Houghton
  • 1,202
  • 16
  • 28
nategoose
  • 12,054
  • 27
  • 42
  • 1
    +1. Thorough and insightful. I had forgotten about scanf, but now that you bring it up, I remember having the same confusion. – Joe White Oct 27 '10 at 21:04
6

Looking back, there were four things that really helped me to finally understand pointers. Prior to this, I could use them, but I did not fully understand them. That is, I knew if I followed the forms, I would get the results I desired, but I did not fully understand the 'why' of the forms. I realize that this is not exactly what you have asked, but I think it is a useful corollary.

  1. Writing a routine that took a pointer to an integer and modified the integer. This gave me the necessary forms upon which to build any mental models of how pointers work.

  2. One-dimensional dynamic memory allocation. Figuring out 1-D memory allocation made me understand the concept of the pointer.

  3. Two-dimensional dynamic memory allocation. Figuring out 2-D memory allocation reinforced that concept, but also taught me that the pointer itself requires storage and must be taken into account.

  4. Differences between stack variables, global variables and heap memory. Figuring out these differences taught me the types of memory to which the pointers point/refer.

Each of these items required imagining what was going on at a lower level--building a mental model that satisfied every case I could think of throwing at it. It took time and effort, but it was well worth it. I am convinced that to understand pointers, you have to build that mental model on how they work and how they are implemented.

Now back to your original question. Based on the previous list, there were several items that I had difficulty in grasping originally.

  1. How and why would one use a pointer.
  2. How are they different and yet similar to arrays.
  3. Understanding where the pointer information is stored.
  4. Understanding what and where it is the pointer is pointing at.
Sparky
  • 13,505
  • 4
  • 26
  • 27
  • Hey, could you point me to an article/book/your drawing/doodle/anything where I could learn in a similar fashion that you described in your answer? I firmly believe that this is the way to go when learning well, basically anything. Deep understanding and good mental models – Alexander Starbuck Mar 29 '16 at 08:55
  • 1
    @AlexStarbuck - I don't mean for this to sound flippant, but the scientific method is a great tool. Draw yourself a picture about what you think might happen for a particular scenario. Program something to test it, and analyze what you got. Did it match what you expect? If not, identify where differs? Repeat as necessary, gradually increasing the complexity to test both your understanding and mental models. – Sparky Mar 29 '16 at 17:32
6

I had my "pointer moment" working on some telephony programs in C. I had to write a AXE10 exchange emulator using a protocol analyser that only understood classic C. Everything hinged on knowing pointers. I tried writing my code without them (hey, I was "pre-pointer" cut me some slack) and failed utterly.

The key to understanding them, for me, was the & (address) operator. Once I understood that &i meant the "address of i" then understanding that *i meant "the contents of the address pointed to by i" came a bit later. Whenever I wrote or read my code I always repeated what "&" meant and what "*" meant and eventually I came to use them intuitively.

To my shame, I was forced into VB and then Java so my pointer knowledge is not as sharp as it once was, but I am glad I am "post-pointer". Don't ask me to use a library that requires me to understand **p, though.

Gary
  • 7,167
  • 3
  • 38
  • 57
  • If `&i` is the address and `*i` is the contents, what is `i`? – Thomas Ahle Nov 14 '10 at 13:06
  • 2
    I'm sort of overloading the usage of i. For an arbitrary variable i, &i means "the address of" i, i on it's own means "the contents of &i", and *i means "treat the contents of &i as an address, go to that address, and pass back the contents". – Gary Nov 15 '10 at 10:41
5

The main difficulty with pointers, at least to me, is that I didn't start with C. I started with Java. The whole notion of pointers were really foreign until a couple of classes in college where I was expected to know C. So then I taught myself the very basics of C and how to use pointers in their very basic sense. Even then, every time I find myself reading C code, I have to look up pointer syntax.

So in my very limited experience(1 year real world + 4 in college), pointers confuse me because I've never had to really use it in anything other than a classroom setting. And I can sympathize with the students now starting out CS with JAVA instead of C or C++. As you said, you learned pointers in the 'Neolithic' age and have probably been using it ever since that. To us newer people, the notion of allocating memory and doing pointer arithmetic is really foreign because all these languages have abstracted that away.

P.S. After reading the Spolsky essay, his description of 'JavaSchools' was nothing like what I went through in college at Cornell ('05-'09). I took the structures and functional programming (sml), operating systems (C), algorithms (pen and paper), and a whole slew of other classes that weren't taught in java. However all the intro classes and electives were all done in java because there's value in not reinventing the wheel when you are trying to do something higher leveled than implementing a hashtable with pointers.

shoebox639
  • 2,312
  • 15
  • 14
  • 4
    Honestly, given that you have difficulties with pointers still, I'm not sure that your experience at Cornell substantively contradicts Joel's article. Obviously enough of your brain is wired in a Java-mindset to make his point. – jkerian Oct 26 '10 at 17:18
  • 5
    Wat? References in Java (or C#, or Python, or propably dozens of other languages) are just pointers without the arithmetic. Understanding pointers means understanding why `void foo(Clazz obj) { obj = new Clazz(); }` is a no-op while `void bar(Clazz obj) { obj.quux = new Quux(); }` mutates the argument... –  Oct 26 '10 at 18:17
  • 1
    I know what references are in Java, but I'm just saying that if you asked me to do reflection in Java or write anything meaningful in C I can't just chug it out. It requires a lot of research, like learning it for the first time, every time. – shoebox639 Oct 26 '10 at 18:23
  • 1
    How is it that you got through an operating systems class in C without becoming fluent in C? No offense intended, it's just I remember having to pretty much develop a simple operating system from scratch. I must have used pointers a thousand times... – Gravity Sep 06 '11 at 02:15
5

Here is a non-answer: Use cdecl (or c++decl) to figure it out:

eisbaw@leno:~$ cdecl explain 'int (*(*foo)(const void *))[3]'
declare foo as pointer to function (pointer to const void) returning pointer to array 3 of int
eisbaw
  • 2,678
  • 2
  • 19
  • 18
4

I think one reason C pointers are difficult is that they conflate several concepts which are not really equivalent; yet, because they are all implemented using pointers, people can have a hard time disentangling the concepts.

In C, pointers are used to, amoung other things:

  • Define recursive data structures

In C you'd define a linked list of integers like this:

struct node {
  int value;
  struct node* next;
}

The pointer is only there because this is the only way to define a recursive data structure in C, when the concept really has nothing to do with such a low-level detail as memory addresses. Consider the following equivalent in Haskell, which doesn't require use of pointers:

data List = List Int List | Null

Pretty straightforward - a list is either empty, or formed from a value and the rest of the list.

  • Iterate over strings and arrays

Here's how you might apply a function foo to every character of a string in C:

char *c;
for (c = "hello, world!"; *c != '\0'; c++) { foo(c); }

Despite also using a pointer as an iterator, this example has very little in common with the previous one. Creating an iterator that you can increment is a different concept from defining a recursive data structure. Neither concept is especially tied to the idea of a memory address.

  • Achieve polymorphism

Here is an actual function signature found in glib:

typedef struct g_list GList;

void  g_list_foreach    (GList *list,
                 void (*func)(void *data, void *user_data),
                         void* user_data);

Whoa! That's quite a mouthful of void*'s. And it's all just to declare a function that iterates over a list that can contain any kind of thing, applying a function to each member. Compare it to how map is declared in Haskell:

map::(a->b)->[a]->[b]

That's much more straightforward: map is a function that takes a function which converts an a to a b, and applies it to a list of a's to yield a list of b's. Just like in the C function g_list_foreach, map doesn't need to know anything in its own definition about the types to which it will be applied.

To sum up:

I think C pointers would be a lot less confusing if people first learned about recursive data structures, iterators, polymorphism, etc. as separate concepts, and then learned how pointers can be used to implement those ideas in C, rather than mashing all of these concepts together into a single subject of "pointers".

gcbenison
  • 11,723
  • 4
  • 44
  • 82
4

I had programmed in c++ for like 2 years and then converted to Java(5 years) and never looked back. However, when I recently had to use some native stuff, I found out (with amazement) that I hadn't forgotten anything about pointers and I even find them easy to use. This is a sharp contrast to what I experienced 7 years ago when I first tried to grasp the concept. So, I guess understanding and liking is a matter of programming maturity ? :)

OR

Pointers are like riding a bike, once you figure out how to work with them, there's no forgetting it.

All in all, hard to grasp or not, the whole pointer idea is VERY educational and I believe it should be understood by every programmer regardless if he programs on a language with pointers or not.

Nikola Yovchev
  • 9,498
  • 4
  • 46
  • 72
4

They add an extra dimension to the code without a significant change to the syntax. Think about this:

int a;
a = 5

There's only one thing to change: a. You can write a = 6 and the results are obvious to most people. But now consider:

int *a;
a = &some_int;

There are two things about a that are relevant at different times: the actual value of a, the pointer, and the value "behind" the pointer. You can change a:

a = &some_other_int;

...and some_int is still around somewhere with the same value. But you can also change the thing it points to:

*a = 6;

There's a conceptual gap between a = 6, which has only local side effects, and *a = 6, which could affect a bunch of other things in other places. My point here is not that the concept of indirection is inherently tricky, but that because you can do both the immediate, local thing with a or the indirect thing with *a... that might be what confuses people.

detly
  • 29,332
  • 18
  • 93
  • 152
3

I think it requires a solid foundation, probably from the machine level, with introduction to some machine code, assembly, and how to represent items and data structure in RAM. It takes a little time, some homework or problem solving practice, and some thinking.

But if a person knows high level languages at first (which is nothing wrong -- a carpenter uses an ax. a person who needs to split atom uses something else. we need people who are carpenters, and we have people who study atoms) and this person who knows high level language is given a 2 minute introduction to pointers, and then it is hard to expect him to understand pointer arithmetics, pointers to pointers, array of pointers to variable size strings, and array of array of characters, etc. A low-level solid foundation can help a lot.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • 2
    Groking pointers does not require an understanding of machine code or assembly. – jason Oct 26 '10 at 19:43
  • 1
    Require, no. But people who do understand assembly would likely find pointers much, much easier, as they've already made most (if not all) of the necessary mental connections. – cHao Nov 04 '10 at 14:53
3

Pointers are difficult because of the indirection.

jason
  • 236,483
  • 35
  • 423
  • 525
  • "It is said that there is no problem in computer science which cannot be solved by one more level of indirection" (no idea who said it first, though) – The Archetypal Paul Oct 26 '10 at 19:52
  • It's like magic, where the misdirection is what confuses people (but is totally awesome) – Nick T Oct 26 '10 at 20:09
3

Pointers (along with some other aspects of low-level work), require the user to take away the magic.

Most high level programmers like the magic.

Paul Nathan
  • 39,638
  • 28
  • 112
  • 212
3

Pointers are a way of dealing with the difference between a handle to an object and an object itself. (ok, not necessarily objects, but you know what I mean, as well as where my mind is)

At some point, you probably have to deal with the difference between the two. In modern, high-level language this becomes the distinction between copy-by-value and copy-by-reference. Either way, it is a concept that is often difficult for programmers to grasp.

However, as has been pointed out, the syntax for handling this problem in C is ugly, inconsistent, and confusing. Eventually, if you really attempt to understand it, a pointer will make sense. But when you start dealing with pointers to pointers, and so on ad nauseum, it gets really confusing for me as well as for other people.

Another important thing to remember about pointers is that they're dangerous. C is a master programmer's language. It assumes you know what the heck you're doing and thereby gives you the power to really mess things up. While some types of programs still need to be written in C, most programs do not, and if you have a language that provides a better abstraction for the difference between an object and its handle, then I suggest you use it.

Indeed, in many modern C++ applications, it is often the case that any required pointer arithmetic is encapsulated and abstracted. We don't want developers doing pointer arithmetic all over the place. We want a centralized, well tested API that does pointer arithmetic at the lowest level. Making changes to this code must be done with great care and extensive testing.

Samo
  • 8,202
  • 13
  • 58
  • 95
2

The problem I have always had (primarily self-taught) is the "when" to use a pointer. I can wrap my head around the syntax for constructing a pointer but I need to know under which circumstances a pointer should be used.

Am I the only one with this mindset? ;-)

Larry
  • 21
  • 1
2

Once upon a time... We had 8 bit microprocessors and everyone wrote in assembly. Most processors included some type of indirect addressing used for jump tables and kernels. When higher level languages came along we add a thin layer of abstraction and called them pointers. Over the years we have gotten more and more away from the hardware. This is not necessarily a bad thing. They are called higher level languages for a reason. The more I can concentrate on what I want to do instead of the details of how it is done the better.

Jim C
  • 4,981
  • 21
  • 25
2

It seems many students have a problem with the concept of indirection, especially when they meet the concept of indirection for the first time. I remember from back when I was a student that out of the +100 students of my course, only a handful of people really understood pointers.

The concept of indirection is not something that we often use in real life, and therefore it's a hard concept to grasp initially.

axilmar
  • 836
  • 1
  • 13
  • 17
2

I have recently just had the pointer click moment, and I was surprised that I had been finding it confusing. It was more that everyone talked about it so much, that I assumed some dark magic was going on.

The way I got it was this. Imagine that all defined variables are given memory space at compile time(on the stack). If you want a program that could handle large data files such as audio or images, you wouldn't want a fixed amount of memory for these potential structures. So you wait until runtime to assign a certain amount of memory to holding this data(on the heap).

Once you have your data in memory, you don't want to be copying that data all around your memory bus every time you want to run an operation on it. Say you want to apply a filter to your image data. You have a pointer that starts at the front of the data you have assigned to the image, and a function runs across that data, changing it in place. If you didn't know what you we're doing, you would probably end up making duplicates of data, as you ran it through the operation.

At least that's the way I see it at the moment!

Chris Barry
  • 4,564
  • 7
  • 54
  • 89
  • As an after thought, you could define a fixed amount of memory for holding images/audio/video, say on a memory limited device, but then you would have to deal with some kind of streaming in and out of memory solution. – Chris Barry Sep 26 '11 at 23:43
1

Speaking as a C++ newbie here:

The pointer system took a while for me to digest not necessarily because of the concept but because of the C++ syntax relative to Java. A few things I found confusing are:

(1) Variable declaration:

A a(1);

vs.

A a = A(1);

vs.

A* a = new A(1); 

and apparently

A a(); 

is a function declaration and not a variable declaration. In other languages, there's basically just one way to declare a variable.

(2) The ampersand is used in a few different ways. If it is

int* i = &a;

then the &a is a memory address.

OTOH, if it is

void f(int &a) {}

then the &a is a passed-by-reference parameter.

Although this may seem trivial, it can be confusing for new users - I came from Java and Java's a language with a more uniform use of operators

(3) Array-pointer relationship

One thing that's a tad bit frustrating to comprehend is that a pointer

int* i

can be a pointer to an int

int *i = &n; // 

or

can be an array to an int

int* i = new int[5];

And then just to make things messier, pointers and array are not interchangeable in all cases and pointers cannot be passed as array parameters.

This sums up some of the basic frustrations I had with C/C++ and its pointers, which IMO, is greatly compounded by the fact that C/C++ has all these language-specific quirks.

Some Newbie
  • 1,059
  • 3
  • 14
  • 33
0

The main problem people do not understand why do they need pointers. Because they are not clear about stack and heap. It is good to start from 16bit assembler for x86 with tiny memory mode. It helped many people to get idea of stack, heap and "address". And byte:) Modern programmers sometimes can't tell you how many bytes you need to address 32 bit space. How can they get idea of pointers?

Second moment is notation: you declare pointer as *, you get address as & and this is not easy to understand for some people.

And the last thing I saw was storage problem: they understand heap and stack but can't get into idea of "static".

user996142
  • 2,753
  • 3
  • 29
  • 48
0

I personally did not understand the pointer even after my post graduation and after my first job. The only thing I was knowing is that you need it for linked list, binary trees and for passing arrays into functions. This was the situation even at my first job. Only when I started to give interviews, I understand that the pointer concept is deep and has tremendous use and potential. Then I started reading K & R and writing own test program. My whole goal was job-driven.
At this time I found that pointers are really not bad nor difficult if they are been taught in a good way. Unfortunately when I learn C in graduation, out teacher was not aware of pointer, and even the assignments were using less of pointers. In the graduate level the use of pointer is really only upto creating binary trees and linked list. This thinking that you don't need proper understanding of pointers to work with them, kill the idea of learning them.

Manoj R
  • 3,197
  • 1
  • 21
  • 36
0

Pointers.. hah.. all about pointer in my head is that it give a memory address where the actual values of whatever its reference.. so no magic about it.. if you learn some assembly you wouldn't have that much trouble learning how pointers works.. come on guys... even in Java everything is a reference..

cass
  • 1,286
  • 14
  • 13