web-dev-qa-db-fra.com

Utilisation de typedef c ++ / utilisation d'un alias de type

Je lis le livre d'introduction C++ et je ne comprends absolument pas une ligne:

 using int_array = int[4]; 
 typedef int int_array[4]; // This line
 for (int_array *p = ia; p != ia + 3; ++p) {
      for (int *q = *p; q != *p + 4; ++q)
          cout << *q << ' '; cout << endl;
 }

Ok typedef est identique à using. Est-ce que ça veut dire que int[4][4] est maintenant int et comment comprendre cela? Et quel type est int_array dans for boucle?

Merci

13
Somethone

TL; DR

Les deux font exactement la même chose: Définir int_array comme alias d'un tableau de 4 ints

Comprendre la syntaxe

using a une belle notation A = B qui est généralement beaucoup plus facile à comprendre.

using alias = type;

La notation de typedef n'est pas tout à fait en arrière. Pour un simple typedef

typedef type alias;

mais les typedefs plus compliqués ont tendance à s'étendre. Je soupçonne que la syntaxe a été modelée sur la façon dont on définirait une variable, mais je ne trouve pas où j'ai emballé ma copie de l'ancien livre de programmation KR C et je ne peux pas le rechercher pour le moment.

int int_array[4];

définirait int_array pour être un tableau de 4 ints. Frapper typedef sur le devant

typedef int int_array[4];

fait du int_array un alias de type au lieu d'une variable.

Un autre exemple,

int * intp;

Définit intp comme pointeur vers un int.

typedef int * intp;

Définit intp comme un alias du pointeur de type vers un int.

Cela devient laid avec des types de données plus compliqués car le nom de l'alias typedefed peut être enterré quelque part au milieu de la définition. Un pointeur de fonction typedefed par exemple:

typedef void (*funcp)(param_t param1, param_t param2, ...);

vs utiliser

using funcp = void (*)(param_t param1, param_t param2, ...);

Création d'un tableau 2D

Si vous voulez un tableau 2D, vous pouvez

using int_array2D = int[4][4];

ou vous pouvez définir un tableau de int_array

using int_array2D = int_array[4];

Et bien sûr, cela signifie que vous pouvez

using int_array3D = int_array2D[4];

et continuez jusqu'à ce que les vaches rentrent à la maison ou que vous ayez emballé tellement de dimensions que le cerveau de The Doctor fond.

10
user4581301

Cette ligne ne fait rien car elle est redondante

Les lignes

using int_array = int[4];

et

typedef int int_array[4];

faire la même chose. Voir référence pour en utilisant et typedef . Vous pouvez laisser de côté l'un ou l'autre et le comportement est le même. Ce n'est pas une erreur d'avoir deux déclarations différentes, car elles ne sont pas en conflit (elles font exactement la même chose).

La première façon de le faire (en utilisant le mot clé using) a été introduite avec C++ 11 et est à mon avis plus facile à lire, donc je la préfère à la version typedef.

3
plats1

Les deux alias de type sont identiques:


Tapez alias, modèle d'alias (depuis C++ 11) :
L'alias de type est un nom qui fait référence à un type précédemment défini (similaire à typedef ):

using identifier attr(optional) = type-id ; 

vous pouvez donc utiliser:

typedef int int_array[4];

ou vous pouvez simplement utiliser (c'est la même chose que ci-dessus):

using int_array = int[4];

Lorsque vous devez adresser la mémoire avec des étapes 4*sizeof(int), par ex. si la taille du système int est de 4 octets, la taille du pas de mémoire est de 4 * 4 = 16 octets. même vous pouvez utiliser int_array *p; dans ce cas ++p avance p d'un pas de mémoire, par ex. 16 octets. voir:


1- échantillon de travail avec using int_array = int[4];:

#include <iostream>
using std::cout; using std::endl;

int main()
{
    int ia[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

    // a range for to manage the iteration
    // use type alias
    using int_array = int[4];
    for (int_array& p : ia)
        for (int q : p)
            cout << q << " ";
    cout << endl;

    // ordinary for loop using subscripts
    for (size_t i = 0; i != 3; ++i)
        for (size_t j = 0; j != 4; ++j)
            cout << ia[i][j] << " ";
    cout << endl;

    // using pointers.
    // use type alias
    for (int_array* p = ia; p != ia + 3; ++p)
        for (int *q = *p; q != *p + 4; ++q)
            cout << *q << " ";
    cout << endl;

    return 0;
}

sortie 1:

0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11

2- échantillon de travail utilisant typedef int int_array[4];:

#include <iostream>
using std::cout; using std::endl;

int main()
{
    int ia[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

    // a range for to manage the iteration
    // use type alias
    typedef int int_array[4];
    for (int_array& p : ia)
        for (int q : p)
            cout << q << " ";
    cout << endl;

    // ordinary for loop using subscripts
    for (size_t i = 0; i != 3; ++i)
        for (size_t j = 0; j != 4; ++j)
            cout << ia[i][j] << " ";
    cout << endl;

    // using pointers.
    // use type alias
    for (int_array* p = ia; p != ia + 3; ++p)
        for (int *q = *p; q != *p + 4; ++q)
            cout << *q << " ";
    cout << endl;

    return 0;
}

sortie 2 (identique):

0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11

réf: https://github.com/Mooophy/Cpp-Primer/blob/master/ch03/ex3_44.cpp
note: utilisez -std=c++11 pour compiler/lier.


3- juste pour la démo (extrait):
une utilisation réelle dans le système embarqué:

extern const char kpd2ascii[6][6] PROGMEM;
typedef const char cint8a6_t[6];
cint8a6_t *p;
p = kpd2ascii;
kpdBuffer = pgm_read_byte(&p[row][col - 1]);

J'espère que ça aide.

1
A.R