Pointers in C are a massive source of confusion for newbies who have come from Java.
They are generally a massive source of confusion for everyone that first encounters them. Having your experience colored by another language doesn't help, but they will make sense eventually. I would recommend a short amount of time with plain C getting used to the general syntax and figuring out concepts like pointers before diving headlong into Objective-C. Others disagree with this, but I feel like a foundation in C will serve you well outside of the context of Objective-C.
My last question about this is that is the reason why pointers are used to hold objects' address instead of normal variables being used to hold them directly that the object can be assigned to other pointers without changing the object? (and primitive types do not need pointers because there is no harm from copying them, as they can not be changed).
There's a lot going on there. I'll try to break it down. The first part:
... the reason why pointers are used to hold objects' address instead of normal variables being used to hold them directly
This was a design choice in Objective-C. There are languages (C++, surely others) that do let you choose if you want a "local" Object. In C++ they can simply be declared:
Code:
std::string myString = "Test";
The assignment part of this is more tricky than it seems, invoking
Code:
string& operator= ( const char* s )
, but anyhow... C++ also lets you have pointers to Objects like Objective-C. I like having pointers to Objects only, because it means EVERY Object you're dealing with is off in the heap, you know you have a pointer to it, you know exactly how to deal with it. In C++ you need to know if you have a std::string * or just a std::string, and must apply different operators to invoke methods, etc.
I can imagine you might then question, if Objective-C were to only pick one, why pick pointers? My opinion on this is the great expense that can be incurred in copying a large object around when it needs to be passed to a function (if you only have Object "values", this is what you'd have to do), assigned to another local instance, etc. Every instance variable has to be copied, etc. And what if you have Objects that are instance variables of other Objects? Then copying the parent will mean copying the child. That could get very, very expensive. With pointers only, if you just want another pointer to the Object, the assignment of a 4 or 8-byte pointer is very cheap. If you really DO need a copy, there are explicit methods to make one, so you get to control when you really need this behavior.
There is also a LOT more space on the heap than on the stack. This means that if you wanted to have an array of 200 Objects in a method, you'd use the size of all of the Objects ivars, and however the system stores function pointers for its methods, etc. taking up memory * 200. You could very easily overwhelm the stack, get a stack overflow, and have your program die. You'd have to break things into extremely small bits to deal with the inability to stick your Objects on the heap.
So Objective-C has a heap-only, pointer-only Object system. I like this, I'm sure some people don't. However, this really isn't different from Java at all. You just don't deal with the pointers explicitly in Java. But it does do pointer-only, heap-only Objects, too. You just don't see *s everywhere, the pointers are implicit in Java.
So now the next part, that I had a little more trouble understanding:
... the object can be assigned to other pointers without changing the object?
I'm not sure what you're asking, but I'll try to answer one interpretation, which is that you want an easy "copy" mechanism for Objects that just uses the = operator. This is a result of the compromises of the language design that I discussed above. There is an easy way to make copies, though:
http://developer.apple.com/mac/libr...Reference.html#//apple_ref/occ/intf/NSCopying
Many Objects will implement this protocol, and allow for a simple [myObject copy] message to be sent to an Object. You can just assign the result of this to another Object * and get the result you're looking for.
primitive types do not need pointers because there is no harm from copying them, as they can not be changed
I am having trouble understanding what you mean here, too. Primitive variables can be changed, that's the whole point. I'm sure that's not what you meant, though. The real issue here is that primitive types have a well-understood size, and it is pretty small. The largest I can think of might be 16-bytes. Copying 1,2,4,8, or 16 bytes around is pretty trivial. Copying around a few thousand may not be, in the case of a very large Object. It's also pretty important to have a type to assign literals to.
One could certainly imagine a system like Java stripping out primitives like int and short and replacing them with their object equivalents Integer and Short, then taking literals like 5 and simply replacing that with a fixed Integer object with the value 5 stored, but this seemed to even be outside of the Object-Oriented-only design of Java. People love primitives, and for things like loop control variables, it seems overkill to use Objects. Also, x + y where x and y are ints is pretty straight forward. If they were Integers, an Integer method would have to be invoked that would return a new Integer Object. It seems like a lot of overhead.
On your road to understanding pointers, you really need to not think of them as a different sort of thing than other primitives. I would just ignore Objects and pointers to them in Objective-C for now. Just deal with the concept in C. A pointer is a primitive type whose value is a memory address. An int's value might be 4 or 2334235, a char's value might be 'A' or '%', etc. A pointer's value might be the address 0x87432309 on a system with 32-bit addresses. If the pointer is of type int *, the integer value stored in the 4 (normally, sometimes 8) bytes starting at memory address 0x87432309 might be 7. A pointer is just a few bytes (enough to store a memory address on a specific system) that stores memory addresses. That's it. There's no magic.
There are a few special operators that you can apply to deal with pointers, because otherwise you really couldn't do anything with the memory address values they store. These operators are:
* This operator dereferences a pointer. So if you have an int *, when you apply this operator to it, you get an int with the value stored at the address your int * points to. This is, unfortunately, the same operator used for multiplication when applied to primitive numeric types, but this is a unary operator (takes only one operand, instead of two).
& This operator gives you the address of a variable. So if you have an int and apply & to it, you get an int * whose value is the address in memory where the int variable is stored.
Once you DO graduate to dealing with Objective-C, when you have an Object pointer you can just forget about these. The only operator applied to Object pointers is the message pass, []. You cannot dereference an Object pointer because, as we discussed earlier, there are no plain Objects in Objective-C. You cannot have an NSObject, only an NSObject *. You CAN get an address of an Object *, but then you just have an Object **, which is pretty rarely used. It comes up, normally with NSError values, but don't worry about that right now.
Please spend a few days getting used to pointers in plain C. Write a few programs, print out the pointers with the %p format specifier for the printf family, pass them to functions, print the pointer's value and the value stored at the address they hold, etc. Declare an int, and an int * and assign the address of the int using & to the int *, then change the int with an assignment statement, then display the value pointed to but the int *, etc.
This will click. It may take an hour, it may take a few days, it may take a few weeks. But this is critical to the understanding of how memory is used by your program, where your variables are being stored, and how to effectively program and deal with APIs you come across that expect to be passed things by reference (using a pointer).
Cromulent mentioned function pointers, which are great, but I wouldn't worry much about those for now. Focus on pointers to primitive types in plain C now, then deal with some Objects in Objective-C, and tackle function pointers when you need them. His point is good, but you should bite off a small chunk at a time if you're already a bit perplexed.
Good Luck!
-Lee