8 ms·
The 5-minute Guide to C Pointers
- chris_wot 14y agoNothing on pointer pointers :( so sad.
- denniskubes 14y agoI added a pointers to pointers section. :)
- chris_wot 14y agoYou rock.
- Jun8 14y ago30 second guide to C pointers, from Alice in Wonderland: `It's long,' said the Knight, `but very, very beautiful. Everybody that hears me sing it -- either it brings the tears into their eyes, or else -- ' `Or else what?' said Alice, for the Knight had made a sudden pause. `Or else it doesn't, you know. The name of the song is called "Haddocks' Eyes."' `Oh, that's the name of the song, is it?' Alice said, trying to feel interested. `No, you don't understand,' the Knight said, looking a little vexed. `That's what the name is called. The name really is "The Aged Aged Man."' `Then I ought to have said "That's what the song is called"?' Alice corrected herself. `No, you oughtn't: that's quite another thing! The song is called "Ways and Means": but that's only what it's called, you know!' `Well, what is the song, then?' said Alice, who was by this time completely bewildered. `I was coming to that,' the Knight said. `The song really is "A-sitting On A Gate": and the tune's my own invention.' The song that the Knight is referring to is this one: http://en.wikipedia.org/wiki/Haddocks%27_Eyes http://en.wikipedia.org/wiki/Haddocks%27_Eyes
- Danieru 14y agoOver the past four months I wrote a library in C. In said library exists the following chain: typedef hidden pointer -> object -> dictionary -> attribute object -> linked list -> object Then the whole thing can start again from the last object. At both the linked list and dictionary points the pointers have been cast to void. During development there was linked list in place of the dictionary. Since this was before I wrote output debuging involved manually walking the two linked lists. Else where a function takes a void * array of structs yet needs to access the contents and thus requires a pointer to an accessor function. I love C but it can get confusing. My plan is to spend the next few weeks in recovery learning RoR.
- densh 14y agoYou might want to look at Go. It always felt like a revised version of C with great standard library and sane defaults.
- phao 14y agoYet another broken C pointers guide out there to confuse people.
- denniskubes 14y agoWhat is broken about it? I am happy to make corrections.
- jorgem 14y agoSome thoughts: >> A pointer is a variable that holds, literally points to, a memory address What is a memory address? How does a pointer literally point to a memory address?
- jcoder 14y agoIt's the guide to pointers, not the guide to memory addresses—I think readers are expected to google unfamiliar terms.
- jorgem 14y agoI think if I understand memory addresses and assembly language, then I understand pointers. If the guide doesn't explain why pointers are useful and efficient on real hardware, then it's missing the point. Which was my point.
- phao 14y agoC assumes some sort of object space addressable to the byte (each object is composed of one or more bytes -- no such a thing as a 0 bytes object in C). It's the memory pretty much. Afaik, what is an address is not defined as part of the language. I guess people should use the knowledge they got from their "how computers work" classes =D. A pointer holds an address. I think that's as deep as you can get with this as clarifying goes. You can though, say, to help learners that the address of an object is a value which can be used to indirectly access the object. You could say that it's a value that you can keep with you, to access the object later, indirectly. And, as any language that I am aware of. Things are usually defined abstractly (in terms of what you want to be true about them). C is not different. You won't find concrete definitions (things may look concretely defined, but they're not). As far as we're concerned, addresses are these things that - the address-of operator returns - is help by pointers - can be indirected - ... It could be represented as a character string for all we know.
- manaskarekar 14y agoHere's another one with more information on pointers in C. http://www.thegeekstuff.com/2012/01/advanced-c-pointers/ http://www.thegeekstuff.com/2012/01/advanced-c-pointers/
- ddfreyne 14y agoAnother tutorial about pointers that I found quite nicely written is http://boredzo.org/pointers/ http://boredzo.org/pointers/.
- rosser 14y agoEvery time someone tries offering a simplified explanation of pointers, I've countered with the old Buddhist saying that, "The pointing finger is not the moon," followed by a brief foray into syntax and operators, e.g., moon* finger = &luna; As often as not, enlightenment occurs.
- sageikosa 14y agovoid* finger = &luna; Don't force the finger to only point to the moon.
- deleted 14y ago[deleted]
- deleted 14y ago[deleted]
- jakejake 14y agoTo me your line of code seems a bit too clever and complicates the concept of pointers. But we all learn differently so it's cool if it flips a switch for people who are, perhaps, more philosophical than I. I tend to use more boring examples like a card catalog vs a book when I'm explaining the idea of pointers.
- zaptheimpaler 14y agoWhy do you say its clever/complicated? The example he mentioned seems like a fairly basic example of a pointer.
- jakejake 14y agowell mainly because it uses a kinda abstract/poetic concept that to explain something concrete. In order to understand the example you have to understand the little puzzle about the moon & the finger as well. Maybe I do understand the saying fully - maybe I don't fully understand the depth of that saying..? Now I'm confused about both! Also using the term moon & luna. Are they the meant to be the thing? Where was luna mentioned in the saying? Is luna representing the moon?
- khakimov 14y agothanks, also recommend to read "What do people find difficult about C pointers?" http://stackoverflow.com/questions/4025768/what-do-people-find-difficult-about-c-pointers http://stackoverflow.com/questions/4025768/what-do-people-fi...
- keporahg 14y agoI never really had much of a problem with the syntax, but the point at which the behavior of pointers really clicked for me (after a night of many segfaults of course) was when I realized that when you pass a pointer to a function, you're sending a copy of that pointer, just like with any other primitive type. E.g: void foo(int *p) { /* assignment won't be persistent after foo() returns; need to send **p */ p = (int *)malloc(1024 * sizeof(int)); } Not sure why my brain had decided to make an exception for pointers for the rule that all variables are passed as copies when I first learned C, but after that I never had any problems.
- eswangren 14y agoJust like any other type. Everything is passed by value in C. Everything.
- RegEx 14y agoI experienced the same frustration. The exercise that gave me the "ah-ha!" moment I needed was prepending to a linked list via the head instead of the tail: You need to pass the address of `head` into the function so that the new head is reflected in the calling environment when you say `head = np`.
- _kst_ 14y ago> Imagine an array variable like a pointer that cannot be changed that holds the memory address of the first element of the array it points to. Nope. Arrays are not pointers; pointers are not arrays. This is perhaps the most common misconception about C, and a "Guide to C Pointers" should not propagate it. For more information about why this is wrong, read section 6 of the [comp.lang.c FAQ](http://www.c-faq.com http://www.c-faq.com).
- ninetax 14y agoWell for a quick sum up: An array is like a constant pointer, it's always pointing at the first element of the the array. To try to point it at something else is an error. array[2] is short for *(array + 2*sizeof(<type of array>)) which takes the address of the first element and adds the appropriate number of bytes to it in order to access the requested element, then it dereferences the "pointer" and you get the value of the element. If this isn't 100% correct, please let me know.
- RegEx 14y agoFrom the C standard: > The definition of the subscript operator [] is that E1[E2] is identical to (((E1)+(E2))). So array[2] == (array + 2)
- dbaupp 14y agoAs RegEx implies, pointer arithmetic implicitly includes the sizeof(<array type>) term, i.e. given int* array; then array + 1 points to the next int, not the next byte. And so array[2] == *(array + 2). (The fact that addition commutes means that using 2[array] instead is valid and works in C.)
- eswangren 14y agoJust as with pointer arithmetic (because that's what this actually is) you don't multiply by the size of its elements. This: array[2] is the same as this: *(array + 2) The compiler knows what the type of data the pointer refers to and can produce the byte offset itself. Also: "...it's always pointing at the first element of the the array" Eh... an array can degrade into a pointer when needed, but what does the following produce? char arr[10]; ??? x = &arr; Is "x" a pointer to pointer to char? From your assessment it would seem so, but in reality the type of "x" is char (*)[10] i.e., pointer to array of char 10. An array is an array, and arrays can degrade into pointer types.
- pjmlp 14y agoNice tutorial! Maybe it shows my age, but I am yet to understand why so many developers nowadays have such a hard time grasping pointers, regardless of the language being used to teach them.
- mikeash 14y agoI learned BASIC, then Pascal, then C. I had a terrible time understanding pointers, until one day it clicked, and ever since that point I have a terrible time understanding how anyone could not understand pointers. I don't think having difficulty understanding pointers is anything new. I was struggling with them in the early 90s, and there was plenty of literature out there talking about how to understand them and how people had trouble with them. But I can't help you understand why people have trouble, because I don't know myself.
- zaptheimpaler 14y agoI had the same opinion at one point. Like you said, the concept of pointers is very simple, but it can get confusing in application, as you start dealing with more levels of indirection. Try coding something/understanding code that requires triple star pointers, then you'll see why they're confusing.
- pjmlp 14y agoEasy, just grab a pencil and paper, draw the data structures and you're done. Again, maybe it just shows my age, as I started coding with BASIC and Z80 assembly.
- aerique 14y agoMy first programming language where I used pointers was 68000 and they were easy for me to grasp, but for some reason it was harder when I started using C and everytime I get back to C or C++ I need a little refresher. For me it is the syntax used by C for pointers that makes it confusing.
- pjmlp 14y ago
- sausagefeet 14y agoWhen printfing pointers you need to cast them to (void\). %p only prints void\ and there is no guarantee two pointer types have the same size. And I can't figure out how to write an astrix. I also think it is a mistake to bring up memory addresses so early. The first paragraph is incredibly confuses. A pointer is simple. It's a variable that points at something. You can change where it points and you can change the value that it is pointing to. (&) is the pointer-to operator and gives you a pointer to something. I think that is roughly all that needs to be said. The all of locations, memory, addresses is just confusion.
- sausagefeet 14y agoPedantic notes: - "The cast isn’t explicitly needed in C but it does make things more readable" - I think many people would disagree with this, including me. Casting is ugly, error prone, and conceals errors. Don't do it, there is no need. If you think it is helping you because you can see what type things are then your functions are too large and incoherent, fix that problem instead. - "Here we print out the values of our uninitialized and NULL pointers. Notice that our uninitialized pointer has a memory location" - This behaviour is completely undefined and it is doing injustice to those who would benefit from this blog post. All code people run on an example site should be well-defined. "Worst case the program crashes badly" - No, worst case is you have no idea what could happen! Old versions of gcc ran nethack when it detected undefined behaviour at compile time. In practice, crashing is actually the best case since you can see the error. In worst case it silently corrupts data in your program and you can't find it until it's so far from the error site that it's near impossible to track down. - "using the NULL keyword" - NULL is not a keyword, it's a macro defined in stddef.h (maybe stdlib.h? I forget). - "doing so will cause a segmentation fault" - No, it's undefined behaviour. On DOS systems the memory addresses 0 was valid and writable. - "That being said an array variable does point to the memory address of the first element of the array." - No, it IS the first element. It decays to a pointer to its first element under various operations, though. - "char * fullname = "full name";" - const char * . Modifying string literals is undefined and the fact that the compiler does not require fullname to be a const char * is merely a historic oversight. I understand the desire to learn-by-writing, but I don't feel this tutorial offers much to the discussion and confuses some of the same things the many other pointer tutorials confuse. I don't think someone new to pointers will actually come out with a superior understanding of pointers after reading this. Much of the content is not technically wrong the wording and method of introduction isn't any less confusing.
- sown 14y agoPointers are sometimes not arrays. :) extern int *x; extern int y[] x is a pointer to an int and y is a pointer to an array of ints of unspecified size. It's equivalent to saying float x and then extern int x somewhere else. They're type mismatched. If you said 'x is a char pointer', you mean lookup symbol table for address of x, then do a memory address dereference and then get the contents of the memory at dereferenced address. If you said 'x is a char array', you mean use the symbol table to get the address, then calculate offset and get contents from that address. When you define it one way and then do it another, you end up doing both of those above. get contents of x, then get value of offset, add it to the contents of x, then get contents of the resulting address+offset. The issue is the declaration which can happen many times and the definition which occurs just once. Now, you can have an array and a pointer be equivalent if it is used in an expression because the compiler converts array references to pointers.
- mikeash 14y agoArrays and pointers are completely different entities in C. The only reason people think there's any sort of equivalence is because: 1. The "array indexing operator" [] actually works only on pointers. 2. Arrays are automatically converted to a pointer to the first array element whenever necessary. 3. Arrays are really uncommon in C, and many things we think of as arrays are not arrays as C considers them. Declare a function parameter with []? That's a pointer, not an array. Malloc a bunch of memory? Not an array.
- Kiro 14y agoSo... What do you use them for?
- mike-cardwell 14y agoThere are many uses. It greatly helps to understand the difference between the heap and the stack, and to understand the difference between static and dynamic allocation. Functions in C are "pass by value" rather than "pass by reference". To simulate "pass by reference", the "value" you would pass is the memory address of the data in question, ie the pointer. Also, if you put data on the heap, you must keep a reference to its memory address, otherwise you wont be able to access it again. You use a pointer for this. The following bit of code allocates some space on the heap, sticks an integer (5) on it and then returns a reference to that memory address, which is stored in a pointer variable named x. int * x = new int(5); To understand why you would do the above instead of "int x = 5", you really need to understand what the stack and heap are, and why/when to use them. Also, you can create read-only versions of variables this way. Eg: int x = 5; const int * y = &x; At this point, y points to the address containing x, but can only be used to read. printing out "x" and "* y" will both give you the same result. If you want to update it, you can do "x=6", but "* y=6" will cause a compile time error, because of the const. There are probably loads of other uses too. I only started learning C/C++ last month, in my spare time. Hmm, I seem to have learnt a few things.
- nosefrog 14y agoCorrect me if I'm wrong, but I'm pretty sure C doesn't use the 'new' keyword, it uses 'malloc'.
- mike-cardwell 14y agoYou are correct, as you know. That was a C++ example, as you know.
- ExpiredLink 14y agoI expected a repost of a repost of this: http://www.youtube.com/watch?v=f-pJlnpkLp0 http://www.youtube.com/watch?v=f-pJlnpkLp0
- bnegreve 14y ago> The * operator is used to both declare a pointer variable and to dereference a pointer depending on where it appears. You seem to be suggesting that this is an inconsistency, it isn't: int *ptr; means that (*ptr) is of type ptr. *ptr = 3; Means the same and affect 3 to (*ptr)
- derleth 14y agoThe nontechnical guide to C pointers: They're post office box numbers. In this analogy, the post office is all your RAM. The big place where my analogy breaks down a bit is that, in this little world, the post office will store things bigger than one box in multiple adjacent boxes, so to get anything into or out of the post office you have to specify which box you want them to start with and how many boxes they'll have to use. The star (dereference) operator takes as its argument a post office box number and instructs the machine to go to that post office box and start taking things out of enough boxes beginning with that box to satisfy the type of the pointer. The only things that only take one box are char values; the number of boxes everything else takes up depends greatly on the specific kind of hardware. It's possible to put a slip of paper containing a number into a post office box; in 32-bit x86, a number long enough to encode a post office box number takes up four boxes. In 64-bit x86, it takes up eight boxes. Using two stars means 'Go to this box, take out enough stuff from the next few boxes to make a pointer, go to the box specified by that pointer, and take enough stuff out from that box (and possibly the next few) to satisfy the type of that pointer.' Using three stars involves another go-to-box step, using four stars another, and using five stars is usually a sign of gross mental derangement. (Oh, and if you're running under an OS much more featureful than MS-DOS, the post office box is a total lie told to your application by the OS. Getting into that gets a bit complicated.)