Je travaille avec un pointeur sur une structure. Je veux savoir s'il est possible de passer directement à une position spécifique sans utiliser l'opérateur ++
.
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
struct dummy{
int id;
char buffer[10];
};
typedef struct dummy dummy_struct;
int main()
{
int i=0;
dummy_struct *ds = malloc(sizeof(dummy_struct)*ARRAY_SIZE);
dummy_struct *iterator = ds;
for(i=0;i<ARRAY_SIZE;i++)
{
iterator->id = i;
sprintf(iterator->buffer,"%d",i);
iterator++;
}
iterator = ds;
for(i=0;i<ARRAY_SIZE;i++)
{
printf("%d:%s:%p\n",iterator->id,iterator->buffer,iterator);
iterator++;
}
// I want to access directly to 5th position
iterator = ds + (sizeof(dummy_struct)*5);
printf("5th position %d:%s:%p\n",iterator->id,iterator->buffer,iterator);
return 0;
}
Cette déclaration
iterator = ds + (sizeof(dummy_struct)*5);
ne fonctionne pas. J'apprécierai n'importe quelle suggestion.
Eh bien, l'arithmétique de pointeur honore le type de données !!
iterator = ds + 5;
va faire le travail.
Pour élaborer, l'expression ci-dessus produira un pointeur en le déplaçant 5 fois, multiplié par la taille du type pour ds
, en octets. C'est la même chose que &(ds[5])
.
Par souci d’exhaustivité, expliquer pourquoi iterator = ds + (sizeof(dummy_struct)*5);
est erroné, c’est, ici, que vous essayez essentiellement de déplacer le pointeur sur un élément dont l’index est (sizeof(dummy_struct)*5
, ce qui est bien hors limites. Notez s'il vous plaît, cela appelle un comportement non défini !! note ci-dessous
Citer C11
, chapitre §6.5.6/P8
Lorsqu'une expression de type entier est ajoutée ou soustraite à un pointeur, le result a le type de l'opérande de pointeur. Si l'opérande du pointeur pointe vers un élément de un objet tableau, et le tableau est assez grand, le résultat pointe vers un élément décalé par rapport à l'élément d'origine tel que la différence entre les indices du résultat et de l'original les éléments du tableau sont égaux à l'expression entière. En d'autres termes, si l'expression
P
pointe suri
- ème élément d'un objet tableau, les expressions(P)+N
(de manière équivalente,N+(P)
) et(P)-N
(oùN
a la valeurn
) pointez sur, respectivement, les élémentsi+n
- th eti−n
- th de l'objet tableau, à condition qu'ils existent. [....]
et puis, en ce qui concerne le comportement indéfini mentionné ci-dessus,
[....] Si à la fois le pointeur l’opérande et le résultat pointent sur des éléments du même objet de tableau, ou un au-delà du dernier élément de l'objet tableau, l'évaluation ne doit pas produire de dépassement de capacité; sinon, le le comportement est indéfini. Si le résultat pointe un après le dernier élément de l'objet tableau, il ne doit pas être utilisé comme opérande d'un opérateur unaire
*
évalué.
Cela étant dit, la déclaration printf()
est également erronée. Vous avez deux spécificateurs de conversion, mais trois arguments fournis. Ce n'est pas nuisible, mais inutile/sans signification.
À ce sujet, du chapitre §7.21.6.1/P2,
[...] Si le format est épuisé tant qu'il reste des arguments, les arguments en excès sont évalué (comme toujours) mais sont autrement ignorés. [...]
Sur la base de ce cas, vous pouvez directement utiliser
printf("5th position %d:%s:\n",ds[5].id,ds[5].buffer);
Le comportement de
iterator = ds + (sizeof(dummy_struct) * 5);
est undefined si vous définissez un pointeur au-delà du dernier élément du tableau. Vous définissez en fait iterator
à d'autres éléments du tableau que vous ne le pensez, par un facteur de sizeof(dummy_struct)
! Ne fais pas ça.
La langue vous permet d’utiliser la notation iterator = ds + 5;
. Cette arithmétique idiomatique pointeur ajoute 5
beaucoup de sizeof(dummy_struct)
à l'adresse iterator
. En d'autres termes, le compilateur effectue l'ajustement sizeof
pour vous. C'est l'une des raisons pour lesquelles l'arithmétique des pointeurs est si puissante.
Notez enfin que *(ds + 5)
est équivalent à ds[5]
. Je trouve que ce dernier offre plus de clarté lorsque vous travaillez avec des tableaux.
On dirait que vous essayez de faire en sorte que le pointeur iterator
pointe sur l'élément 5th
du tableau ds
. Mais cette déclaration vous donnera un résultat erroné:
iterator = ds + (sizeof(dummy_struct)*5);
Le résultat de sizeof(dummy_struct)*5
donnera la taille totale de tous les éléments de la structure dummy_struct
multipliée par 5, qui sera ajoutée à l'adresse référencée par ds
et assignée à iterator
. Donc, la variable iterator
peut pointer sur un emplacement mémoire que votre programme ne possède pas. Tu as besoin de faire:
iterator = ds + 5;
Ou vous pouvez aussi faire:
iterator = &ds[5];