8 ms·
IMHO pointers are mostly hard at the beginning because the asterisk-operator is overloaded: On one hand it declares (and optionally initializes) a pointer (type
by protomikron 10y ago
IMHO pointers are mostly hard at the beginning because the asterisk-operator is overloaded: On one hand it declares (and optionally initializes) a pointer (type * x = ...;) and on the other it dereferences it (type y = * x;). At least for me that was the thing that puzzled me the most. I would prefer something like that:
// declare and initialize x
@uint32_t x = 42;
// dereference x
uint32_t y = ~x;
I.e. have different symbols for the type and the dereferencer ('@' and '~' as an example).
//edit: thanks for the help, fixed snippets - HN's parser does not get pointers either apparently :)
- greenshackle2 10y agoI was about to tell you to escape it but I actually cant find a way to print an asterisk on HN EDIT: you can print one by leaving a space after it: * aa
- protomikron 10y agoYeah thx, I just realized that myself.
- jstimpfle 10y agoDo it like * this
- jpindar 10y agoI agree, the notation was the hardest part of learning about pointers. Having a 'cheat sheet' - a program with examples of common ways of using pointers - helped me quite a bit.
- mixmastamyk 10y agoI first learned pointers with Pascal and believe it was simpler with the ^ operator, but it has been so long I don't remember.
- e12e 10y agoFor some reason I also found pointer/references easy in Pascal, but struggle with them in C. I also find it easier to work with direct/indirect addressing in assembler than in C. I'm not entirely sure why - seemingly the differences between C and Pascal syntax and behavior for references seem trivial -- and yet somehow in Pascal it feels intuitive, while in C it feels complicated.
- Iv 10y agoIf I recall correctly (long long time ago) there was only one pointer type un Pascal and it was considered a number that it was legal to modify without warnings. C insists that int * , char * and int are totally different types that you should not mix. It makes sense most of the time but it can be confusing when you do not realize that internally they typically are the same thing <insert here the disclaimer about 32/64 bits systems>.
- evincarofautumn 10y agoI think it seems simpler because Pascal differentiates the type ^integer (“pointer to integer”) from the expression i^ (“dereference i”) and didn’t originally have an address-of operator—you could only get the address of a new anonymous value.
- e12e 10y agoIt's been so long, I don't really recall - but I was using object pascal which is fairly similar to free pascal: http://www.freepascal.org/docs-html/ref/refse15.html http://www.freepascal.org/docs-html/ref/refse15.html It's quite similar to c - yet I find it a little bit clearer.
- emmelaich 10y agoYou can consider them the "same" thing if you regard the asterisk as binding closer to the var instead of the type. Which the declaration syntax hints at: int i, *p;
- protomikron 10y agoCan you elaborate? My point is that the concepts "having a datatype, that stores an address" and "reading (typed) data stored at a specific address" are different, but share the same keyword (which is in this case just one symbol - maybe because C programmers have to use it often). E.g. assuming C99's bool (0|1) datatype, you might define the "negate" functionality, which is often done by '!'. So we have something like that: // init a new bool bool success = 1; ... // negate the bool if (!success) { ... } For me that makes sense. However if we take the pointer approach (as it is implemented), it would look like this: // init a new bool bool success = 1; ... // negate the bool if (bool success) { ... } I hope this makes sense. For an experienced programmer * 's role is obvious from the context, but for me that was the most troubling concept when starting with C's pointers.
- belovedeagle 10y agoI don't see how the bool example follows; in what way is negating a boolean like dereferencing a pointer w/r/t types? ! is bool->bool; * is * P -> P. The reason the same symbol is used is because of the way C types are read: int x; // (x) is an int int *x; // (*x) is an int int **x; // (**x) is an int int x(double); // (x(1.)) is an int
- protomikron 10y agoYeah, sorry, my example sucks. However, I am still believing a different operator would make more sense.
- belovedeagle 10y agoAnd what of [a-zA-Z0-9_]? Why should we allow them in both types and variables and functions? That's really confusing.
- roel_v 10y agoI've been programming C++ for too long to really understand why people find pointers hard, but I do remember that I did too at the beginning, and I do remember my epiphany (reading on the train, funny how I remember such senseless details 15 years later yet can't memorize a 4-item shopping list): given a declaration of struct Foo { int a; }; Foo* f; , the following two are equivalent: int b = f->a; and int b = (*f).a; Never had it spelled out for me like this, probably because it's so obvious once you get it - thought I'd share in case it gives anyone else an 'aha' moment.
- allenbrunson 10y agoi also had trouble with pointers while learning C, and, like everyone else, it seems so obvious now that i wonder what the hell my problem was. like learning to ride a bike, or drive a car with a manual transmission. i learned 8086 assembler before C and had no difficulty with indirection there. for what its worth, your "aha" scenario would have just confused me more. even today, i have to think a bit before your second example makes sense to me.
- acbart 10y agoThe trick to teaching pointers is to model memory with boxes. You have a stack, and a heap, and you draw arrows to represent pointers. At some point, you need to reveal that those arrows are just numeric indices, but the visual helps early on. The * and & operators just let you follow the value in the pointer. I've had a number of students who were baffled up until I showed them this model. Notational Machine for the win!
- userbinator 10y agoIn general, thinking of memory as an array of bytes is helpful, and each byte has an address which is itself a series of bits that can be stored in memory --- and the concept that ties it all together and what I find makes a lot of people just "get it" is the fact that memory can itself store addresses that denote locations within it.
- 10y ago
- grahamburger 10y agoThis exactly captures the struggle I've been having with pointers in Go - I have no problem grasping what a pointer is and how to use it, but I keep getting tripped up on the syntax because of exactly this.
- blueside 10y agoI well remember that if how arrays decay to pointers was properly explained to me in the beginning, I would have "got" pointers a lot sooner
- mettamage 10y agoFor me the reason pointers were hard is because I didn't get clear feedback when I dereferenced them. When pointers are taught conceptually they don't tell you that there is a kernel terminating the program because you access invalid memory. I confused that termination with the idea that my pointer has never been dereferenced in the first place. Now, I don't know if the kernel intervenes before the invalid address is going to be dereferenced or just after it. The thing is, I understood the concept, but getting this error was giving me doubt since I made an error of accessing valid memory. Once I understood that I tried to force a normal int to become a pointer and eventually it worked (needed two ints and an 8-bit variable to cast it to a 64 bit address), proving to me that I understood the concept. Accessing (valid) memory and pointers should be explained together.
- caro_douglos 10y agoI recall them being a way of seeing how much you studied at uni...or some professor wanting to bring up the morris worm
- brandmeyer 10y agoYou may be interested in the SPECS design. They used a prefix ^ for this purpose. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.2481&rep=rep1&type=pdf http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34....