Pointeurs C vs pointeurs Objective-C

Je viens d’un milieu Objective-C et j’essaie d’élargir mes connaissances en C. Une chose m’a cependant confondue, c’est la différence entre les indicateurs en C et Obj-C. Comme vous pouvez le voir dans les exemples ci-dessous, les choses semblent se comporter un peu différemment entre les deux langues, et je me demandais si vous pouviez nous aider à expliquer pourquoi.

Le code C fonctionne bien:

void myFunction() { int x, *pointerX; pointerX = &x; *pointerX = 5; // Prints: "x is 5" printf("x is: %i", x); } 

Le code Obj-C échoue:

 - (void)myMethod { NSSsortingng *ssortingng = @"Caramel coffee", *ssortingngPointer; ssortingngPointer = &ssortingng; // Warning: Assignemnt from incompatible pointer type *ssortingngPointer = @"Chocolate milkshake"; // Exception: Incompatible types in assignment NSLog(@"ssortingng is: %@", ssortingng); } 

Question: Pourquoi ne puis-je pas affecter ssortingngPointer à l’adresse mémoire de ssortingng ( ssortingngPointer = &ssortingng; ) et pourquoi puis-je effectuer *pointerX = 5; sous C, mais je ne peux pas effectuer *ssortingngPointer = @"Chocolate milkshake"; sous Objective-C?

Je réalise qu’Obj-C traite des objects et que C ne le fait pas, mais je n’arrive pas à comprendre les détails en coulisse expliquant pourquoi cela ne fonctionne pas dans Obj-C. Toute aide est grandement appréciée. Merci! 🙂

Dans votre premier exemple, x et pointerX ont des types différents ( (int) et (int *) respectivement). Dans votre deuxième exemple, ssortingng et ssortingngPointer ont le même type ( NSSsortingng * ). Essayez plutôt:

 NSSsortingng *ssortingng = @"Caramel coffee", **ssortingngPointer; 

Votre NSSsortingng *ssortingng est elle-même un pointeur. Par conséquent, pour y pointer, vous devez déclarer ssortingngPointer tant que pointeur sur un pointeur. C’est-à-dire, déclarez ssortingngPointer comme ceci:

 NSSsortingng **ssortingngPointer; 

Alors tout devrait fonctionner. Notez que la même sémantique de pointeur s’applique en C et en Objective-C.

Le fait est que, lorsque vous créez un object, vous le manipulez toujours via un pointeur qui lui est atsortingbué, d’où (NSSsortingng *).

Essayez de faire la même chose en C (travailler avec une chaîne), cela devient peut-être plus clair:

 void myFunction() { char *ssortingng = "this is a C ssortingng!"; char **ptr=&ssortingng; // Prints: "this is ac ssortingng" printf("ptr points to %s: \n", *ptr); } 

Comme vous pouvez le constater, les pointeurs fonctionnent exactement de la même manière que dans object-c. Gardez à l’esprit qu’il existe très peu de primitives dans objective-c (int est le plus évident). La plupart du temps, vous créez un pointeur de type object X (par exemple, NSSsortingng), puis allouez un bloc de mémoire (via [[Object alloc] init]) et assignez l’adresse de début de ce bloc à votre pointeur. Exactement comme nous l’avons fait en C avec notre chaîne.

&ssortingng a le type NSSsortingng ** , alors que ssortingngPointer a le type NSSsortingng * , d’où l’avertissement. Ensuite, vous essayez d’affecter une instance de NSSsortingng (de type NSSsortingng * ) à une variable de type NSSsortingng , d’où l’erreur.

C’est toujours une bonne idée de définir chaque variable sur sa propre ligne. Le moment où vous réécrivez votre code objective-с initial comme

 NSSsortingng* ssortingng = @"Caramel coffee"; NSSsortingng* ssortingngPointer; 

beaucoup de choses deviennent claires.

La question est de savoir si vos chaînes sont constantes ou non.
Le premier exemple fonctionnerait probablement.
Même dans les compilateurs C non objectives, les chaînes littérales peuvent être placées dans la mémoire const via les options de l’éditeur de liens / compilateur.

Sur cette ligne: ssortingngPointer = & ssortingng; Vous copiez l’adresse du pointeur dans la chaîne poitner. Clairement incompatible.

Et sur cette ligne:
* ssortingngPointer = @ “Milkshake au chocolat”;

Vous essayez d’écrire une chaîne dans le pointeur (le pointeur est une adresse de 4 octets). Pas une bonne idée de copier une chaîne entière dessus.

Qu’essayez-vous de faire?

Je ne sais pas si cela fonctionnera comme prévu.

Vous semblez prendre des concepts de C et les appliquer aux cours Cocoa, je pensais que vous appreniez C. Avez-vous déjà vu quelque part dans le code prenant Objective-C l’adresse d’un object?

Les classes Cocoa sont implémentées à l’aide de Class clusters ce qui signifie qu’elles partagent la même interface, mais vous obtiendrez une classe étendue spécifique que vous manipulerez.

Dans votre cas, vous prenez l’adresse de la classe qui étend éventuellement NSSsortingng et vous l’atsortingbuez au pointeur sur NSSsortingng .

Exemple:

 NSSsortingng * str = @"Caramel coffee"; NSSsortingng * str2 = [NSSsortingng ssortingngWithSsortingng:@"all"]; NSLog(@"%@", [[str class] className]); NSLog(@"%@", [[str class] className]); 

Sortie (GNUStep linux):

 2009-12-08 10:49:29.149 x[25446] GSCInlineSsortingng 2009-12-08 10:49:29.149 x[25446] NSConstantSsortingng 

… en dehors des problèmes évidents de définition de pointeur signalés par d’autres.