J'ai un type de tableau personnalisé défini comme dans le code et un pointeur vers ce type de tableau également défini. J'essaie de trouver une corrélation entre le type de tableau personnalisé et un pointeur vers le type de tableau personnalisé. Comment attribuer une valeur au pointeur du type de tableau personnalisé afin de pouvoir parcourir le tableau à l'aide du pointeur?
#include<stdio.h> typedef int array_type[3]; typedef array_type* ptr_array_type; int main() { array_type a = {2,3,4}; ptr_array_type ptr; ptr = a; printf("%d\n",*ptr); }
Je sais que le nom du tableau contient le pointeur vers le premier élément. Je reçois toujours une impression invalide: -50204788 au lieu de 2.
Je reçois également un avertissement:
avertissement: affectation à 'ptr_array_type' {aka 'int (*) [3]'} à partir d'un type de pointeur incompatible ' int * '[-Wincompatible-pointer-types] ptr = a;
Quelqu'un pourrait-il m'indiquer la bonne manière d'attribuer une valeur appropriée au pointeur afin que je puisse parcourir le tableau.
3 Réponses :
ptr
est un pointeur vers int [3]
; a
est un int [3]
. Bien que je n'aime pas les types de pointeurs typedef
en général, si vous insistez sur cette approche, voici comment vous pouvez déréférencer le premier élément de a
de ptr
:
ptr = &a; printf("%d\n", **ptr);
Merci pour la réponse, pourriez-vous expliquer la solution un peu plus en détail. Merci d'avance.
Dans le code, je ne comprends pas le premier typedef pour le type de tableau. Comment cela peut-il être écrit sans dactylographier?
Comment attribuer une valeur au pointeur du type de tableau personnalisé afin que je peut-il parcourir le tableau en utilisant le pointeur?
Étant donné le
array_type
défini parprintf("%d\n", *p++); printf("%d\n", *p++); printf("%d\n", *p++);, le type de pointeur auquel vous pouvez attribuer un
array_type
estint *
:assert(*p == 2);Vous pouvez (apparemment) attribuer un objet de
array_type
à un pointeur de typeptr_array_element :
array_type a = {2, 3, 4}; ptr_array_element p = a;Ceci fait, vous pouvez accéder au premier élément du tableau via l'opérateur de dérférence.
typedef int *ptr_array_element;Et vous pouvez généralement l'utiliser un peu comme un itérateur C ++:
typedef int array_type[3];MAIS NE PAS.
Utilisez les typedefs avec parcimonie , où ils cachent des détails non pertinents, améliorent considérablement la clarté du code, ou similaire. Évitez d'utiliser des typedefs qui obscurcissent les détails pertinents , tels que le fait que les objets de ce type sont des pointeurs ou des tableaux, à moins que, éventuellement, ces détails soient parfaitement clairs dans les noms de type, ou à moins que les masquer ne soit intentionnel et inoffensif. Il est rarement inoffensif de masquer la nature du tableau ou du pointeur.
ptr_array_type
alias int (*) [3]
, et non int *
- vous ne pourrez pas l'utiliser pour parcourir array_type . Vous pourriez l'utiliser pour parcourir un tableau de array_type
, comme ceci:
array_type *arr = new_array_type( 1, 2, 3 ); // even this is leaky since it assumes we know // the array element type is integral array_type_iterator *itr = new_array_type_iterator( arr ); array_element_type target; begin_iterator( &itr ); while( next_iterator( &itr ) ) { get_data_from_iterator( itr, &target ); write_array_element_to( stdout, target ); } free_array_type_iterator( itr ); free_array_type( arr );
Si vous le souhaitez pour pouvoir parcourir un tableau de T
avec un pointeur, alors le type de ce pointeur doit être T *
. Vous devez donc changer vos typedefs en quelque chose comme
typedef int array_type[3]; // probably want to replace int with another typedef int *ptr_array_type; // typedef to abstract out the type ... array_type a = {1, 2, 3}; // yuck! don't do this! a is not obviously an array, // so an array initializer looks wrong in this context ptr_my_type p = a; printf( "%d", *p );
Cependant ...
Si vous utilisez typedef code > pour faire abstraction des détails d'implémentation pour un type, vous devez alors abstraire tous les détails d'implémentation pour ce type, y compris des choses comme le déréférencement et l'indexation. Vous voudrez créer une API complète, telle que:
array_type arr[3]; ptr_array_type ptr = arr; while ( size_t i = 0; i < 3; i++ ) do_something_with( ptr[i] );
Les abstractions partielles ou qui fuient conduisent simplement à un code déroutant à utiliser et à maintenir. Si l'utilisateur d'un type doit être conscient du "array-ness" ou du "pointer-ness" de ce type pour l'utiliser correctement, alors ne cachez pas ces qualités derrière un typedef sans fournir des remplacements pour le [ ]
et les opérateurs unaires *
également. Fournissez également un moyen d'abstraire les E / S - ne forcez pas l'utilisateur à savoir s'il doit utiliser % d
ou % f
ou % s dans une instruction
printf
s'ils ne fonctionnent pas avec un type primitif.
Ne cachez pas la nature du pointeur derrière un typedef. C'est beaucoup plus enclin à dérouter (les gens) qu'à aider.
Vous affectez le type
T
à la variableT *
. Ceux-ci sont incompatibles. Et le fait queT
soit un tableau ne le change pas.Le type de
* ptr
estint [3]
. Cela se décompose en un pointeur vers le premier élément, ce qui n'est pas du tout équivalent à la valeur de du premier élément.Le code provient en fait d'un projet autosar où les types sont définis comme cela, et maintenant j'essaie de comprendre comment ils sont affectés.