Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
Ok... I understand what pointers are and how they point to a memory location where the variable is stored.
However, I still can't fully get my head wrapped around when the pointer (asterisk) is to be used and when it isn't. It's still seemingly random to me.
Does anyone have any recommendations for good tutorials on the web or book chapters that really go into detail on pointers?
Thanks!
Edit: What I'm really looking for is a detailed guide that is specific to Objective-C either in a deep website tutorial or book chapter(s). I don't think there is enough space here to fully explain it for me.
Being aware that this is tagged as Objective-C..
Take a look at here.
(Un)fortunately, the asterisk * has many different meanings depending on context. So, let's look at the relevant ones. Let us write T for some arbitrary type (say int):
T x; // variable of type x, stored somewhere in memory
T * pt; // a pointer to a variable of type x -- doesn't have a value just yet
pt = &x; // the value of pt is now the address of the variable x
So far so good. We have used the asterisk to designate a new type, namely T*, which is a "pointer to T".
But what do we do with a pointer? We can dereference it to get to the value of the variable at the address pointed to by the pointer:
T y; // another variable of type T
y = *pt; // equivalent to y = x;
*pt = 81; // equivalent to x = 81;
So, if the asterisk is part of the typename, then it designates a pointer type. If it comes before a variable name (which is itself of pointer type), then it dereferences the pointer.
[Clarification:] In C, pointers naturally go hand-in-hand with the "address-of" operator &, which is used to actually obtain a pointer to something. In Obj-C, a pointer is obtained as the result of object allocation (+ initailization): T * pt = [T new];
Beware that Obj-C offers an alternative syntax to the traditional C and C++ pointer syntax, so you may encounter pointers in other guises.[/Clarification]
(The asterisk can also be used as a binary operator of course, so you can have something like this: int x = 5; int * p = &x; int y = *p * *p;.)
Peter Hosey of Growl and Adium has posted a guide to pointers on his blog. He calls it, "Everything you need to know about pointers in C," but that's because he regards the ugly pointer aspects as belonging to C rather than Obj-C. Check it out.
I don't know of any reference beyond the Clang ARC reference that describes all the crazy modifiers you can now put on pointers in Obj-C, though. And that's not a good learning resource if you're already confused.
Assuming that C pointers have no secret to you, basically in Objective-C there are two caveats to avoid:
The NS- prefix does not always denote a class. Sometimes this is only a typedef. You have to check the reference manuals.
Dotted notation introduced in Objective-C 2.0. Despite the fact that every object is a pointer, sometimes instance variables can be accessed by myObj.myVar, instead of (more consistent for newcomers) myObj->myVar.
The ultimate guide to pointers is in Kernighan & Ritchie. They're the same in Objective-C as they are in C.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
They seem to have more or less the same purpose.
they told me that pointers are just memory addresses of data locations so that instead of passing large objects and data, you just pass a number.
but i still can't see difference.
please, explain.
No, they aren't the same since you need access to the pointer to access what it points to.
Unless you make the pointer global, you can't access what it points to from everywhere.
A pointer is a type of variable that stores a memory address. They can have scope just as any other variable. A global variable is a variable with global scope, meaning it can be accessed from anywhere.
Just because a pointer is global, it doesn't mean the data in memory is global. If the data in memory is garbage collected from going out of scope (e.g. from an if statement ending or a function ending), the pointer will now point to re-purposed memory, and the value at that memory address will be unpredictable.
If anything, pointers are generally used as a way to share local variables without creating a global variable. Instead, you only pass the pointer to functions you want to share the value with.
I'm going to assume you're talking about c++. Pointers are not global unless you assign it to a variable that is global. Here is an example in c and should be the same in c++:
#include <stdio.h>
int x = 5; //Global variable
int* x_pointer = &x; //global pointer that holds the address of x
int main() {
int y = 43; //Local variable
int* y_pointer = &y; //local pointer that holds the address of y
return 0;
}
Hope this helps!
Someone has ask the same question before:Objective-C Runtime: What to put for size & alignment for class_addIvar?
But it's not fully resolved.
The functions declaration is as follows:
BOOL class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)
Which is used to add an instance variable to a dynamically created class in Objective-C.
The forth argument, uint8_t alignment, is described in Apple's documentation:
The instance variable's minimum alignment in bytes is 1<<align. The minimum alignment of an instance variable depends on the ivar's type and the machine architecture. For variables of any pointer type, pass log2(sizeof(pointer_type)).
In some tutorials, it's just claimed that if the ivar is pointer type, I should use log2(sizeof(pointer_type)); if the ivar is value type, I should use sizeof(value_type). But why? Can someone explain this in detail?
If you really want to learn where these values come from, you'll need to look at architecture specific ABI references, for OSX and iOS, they can be found here: OS X, iOS.
Each of those documents should have a section titled 'Data Types and Data Alignment', which helps to explain those values for the specific architecture.
In practice, since C11, you can use the _Alignof operator to have the compiler give you the correct value for a specific type (as it already needs to know this in order to generate proper machine code), so you can create a class_addIvar that looks something like this:
class_addIvar(myClass, "someIvar", sizeof(int), log2(_Alignof(int)), #encode(int))
Which should take care of all those gory details of the underlying type for you.
This question already has answers here:
Objective-C and Pointers
(3 answers)
why most of the objects we create in iphone are pointers
(1 answer)
Closed 9 years ago.
I am new to Objective-C and come from a Java background. I have just gone over casting in Objective-C but the book I am using failed to explain the use of the '*'/pointer when casting. Here is the example they gave me:
myFraction = (Fraction *) fraction;
Aren't pointers for specific objects so they have their own unique memory location? So then why must I use a pointer when simply referencing a class? In this case, Fraction.
Thanks I hope this makes sense and I know this is a simple question that I should know and understand but I could find nothing explaining this.
The * symbol has multiple meanings (beside multiplication :):
Dereference (follow) pointers. This code follows pointer stored in pointerToInt and then assigns a value to it.
(*pointerToInt) = 5;
Declares a pointer type. When you write int * it means “reference to an integer”.
int x = 5;
int * xPtr = &x
Now, objects are a kind of structures, but we only manipulate with them via pointers. Never directly. This basically means, that 99% of time when you see * (and it's not multiplication :) it is the second case: a part of type declaration:
NSString * = pointer to NSString structure (you can't use NSString alone)
Fraction * = pointer to Fraction structure and Fraction structure is described in Fraction class
So it's not “pointer to the Fraction class”, but rather “pointer to structure of Fraction class”.
I will go a little further and answer your future question about two **. You may see this usually with NSError arguments that are defined like methodWithError:(NSError **)errorPtr.
Short story: int is to int * as NSError * is to NSError **.
Long story: If we cannot manipulate with objects directly (without pointers to them), the single pointer becomes standard part of declaration. Now what if we want to make indirect access to the object? We use double pointer! First * is required for object, second is for indirection.
NSError *error = nil; // Empty.
NSError **errorPtr = &error; // Reference to our local `error` variable.
[data writeToURL:URL options:kNilOptions error:errorPtr];
// That method uses: (*errorPtr) = [NSError errorWith...];
NSLog(#"Error: %#", error); // Our local error is no longer empty.
I believe pointers are weird when you come from Java. They are a bit of legacy from C, but they are not used in any crazy way.
The * symbol is simply syntax that's used when referring to pointers.
Here, myFraction, and fraction are both variables that hold pointers (they aren't objects themselves – in fact you never have variables that hold Objective-C objects, objects must always be referred to with pointers).
The (Fraction*) syntax describes a cast to a pointer-to-a-Fraction of the expression on its right (in this case the fraction variable).
Remember that a pointer is just a variable that holds a memory location.
In Objective-C, when you have an object, what you really have is a pointer to an object, that is, a variable whose value is the memory address where the object really is.
Casting a pointer to a pointer of another type has no effect at runtime (at least for objects). In fact all your objects could be of type (void *). The casting helps the compiler to know what kind of object the pointer is pointing to, and generate errors or warnings.
If these two little paragraphs don't make much sense to you right now, consider reading some basic information or tutorials on pointers. Understanding pointers can be challenging for a beginner or from someone transitioning form the Java world.
...failed to explain the use of the '*'/pointer when casting...
Pointers have little to do with casting, other than being part of a type specifier. Consider:
Fraction is a type -- for the sake of argument, let's imagine that it's the name of a class, and that Fraction is a subclass of another class called Number.
Fraction * is a pointer to an instance of the Fraction class. In Objective-C, you always use pointers to refer to objects, so you'll see a lot of variables with types of the form ClassName *.
Casting is simply a matter of telling the compiler that it should treat a variable as a certain type. So, let's say you've got a variable number of type Number * and you know that the object it points to is actually a Fraction. However, you can't use any of the methods that are specific to Fraction because, as far as the compiler is concerned, number is just a Number *. You can use a type cast to tell the compiler: "I know what I'm doing, and number is definitely pointing to an instance of Fraction, so please treat number as a Fraction *." You do it like this:
Fraction *f = (Fraction *)number;
But again, the * doesn't have any special significance in the casting operation beyond the fact that Fraction * is the type to which you're casting number.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to ask that what is that id? I don't understand what this id is. I got this code from a book and it says a generic type that's used to refer to any kind of object. Can anyone help me with this? I read it few times. Still can't get it.
void drawShapes (id shapes[], int count){
for (int i = 0; i < count; i++) {
id shape = shapes[i];
[shape draw];
}
} // drawShapes
id is an alias for an unknown Objective-C object. It can be used to declare any Objective-C object value.
In the example you have it is using an id rather than a specific class so that the code is not dependent on the class of shape.
Strictly speaking id is defined as a pointer to an objc_object struct.
typedef struct objc_object {
Class isa;
} *id;
In practical terms this means any Objective-C object.
However don't confuse this with NSObject *. While in many cases the equivalence may hold, there are classes which do not descend from NSObject but are still valid Objective-C objects (and therefore whose type can be id). One notable example is NSProxy.
In the code you posted, the id stands for the type of items that will be stored in a C static Array. In particular, the id type indicates any Objective-C object.
Anyway, I would not recommend to use C static arrays in Objective-C to contains objects of unknown type, when you can achieve the same result by using an instance of NSArray.
id means "a reference to some random Objective-C object of unknown class" an example is when you make an at property for a uibutton sometimes it will come up as id but setting it as uibutton will help xcode fill in blanks for you while your typing because now xcode knows exactly what this object is. in your situation shape could be a string or a number or something else if you were just looking at that line of code though passing anything into it could give another line a error later on.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
objective c difference between id and void *
why most of the objects we create in iphone are pointers
According to Stanford university course, 2010/2011
Lecture 3
The guy made something strange there (at least for me), which is that
NSString *digit = sender.titlelabel.text;
Why is digit a pointer?
The type of your digit is id, which is just basically just a C pointer to a certain struct. All references to objects in Objective-C have this primitive type, regardless of the Class of the object. So the answer to your question is, unfortunately, because that's the way Objective-C works.
So whether you're declaring an NSString*, or an UITableViewController*, or MyClass*, your variable has type id. This is the primary means by which the language implements polymorphism. So, for example, the following declarations are equivalent:
NSString *digit;
id digit;
And it's true of method prototypes as well. These are equivalent:
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath;
A variable of type id is not an object itself, it is a pointer to an object. It is the handle with which you manipulate an object. Objective-C does all of the class compatibility work at runtime.
Hope this helps. Any questions?
Updates
That's right: int, float, double, char, void, and the pointer combinations, are all C primitive types. You can and will still use these quite a bit, and they are just what they are in a C program. But Objective-C adds the id type as a way to bridge the gap between the primitive typing of C and the very high-level typing of objects by the Objective-C system. id itself is typedef'd as a pointer to a simple struct in objc.h. At the level of the compiler and the language itself, there really isn't too much meaning to the type. For example, you'll almost never declare an array of ids, certainly never perform any arithmetic with them.
In fact, it's not too far a stretch to say that Objective-C is just plain vanilla C with some added syntax (particularly, the square-bracket notation for method invocation), a few extra primitive types (id, IMP, SEL), and a big runtime library. It's this runtime library that handles all things Object-Oriented.
Anyway, to answer your question, when you're actually programming, you will most often (99% of the time) just use class names to declare your variables - NSString *, NSData *, UITableViewController *, and so on. And the compiler will know what you're talking about, and issue a warning if you write code that clearly tries to put an NSString* where an NSData* is expected. But the actual meaning of those types really exists only at runtime.
I've digressed a little, but I'm not sure where your understanding is failing you, so I thought I'd just explain things a bit. You might want to read Apple's The Objective-C Programming Language to get a feel for the language.
NSString is an Objective-C class and all object references in Objective-C are pointers. I would suggest reading through some of the documentation such as Learning Objective-C A Primer:
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.
It's not a digit, it's the "text" from the label, which is (I'm guessing) a string of integers and such to express the time.
So, all NSString types are declared as pointers in Obj-c.
sender.titlelabel.text;
Returns a NSString *
Remember, it's the same as:
NSString *str = [sender.titlelabel getText];
Because text is too. Or more preceisly, because the getText message returns a pointer.
You can find an intersting about why it has to be a pointer:
NSString and Pointers
I Hope it will help you to understand it in a Objective-C way.