12
votes

Calculer la longueur du tableau en C en utilisant la fonction

Je veux faire une fonction qui calcule la taille de la matrice transcédée.

Je vais transmettre un tableau comme entrée et cela devrait renvoyer sa longueur. Je veux une fonction xxx p> la longueur doit être de 5 car il contient 5 éléments bien que sa taille est 8 (Même 8 fera que 5 serait excellent)

J'ai essayé ceci: xxx

ceci ne fonctionnera pas comme " Tailleof (tableau ) "va raturer la taille du pointeur d'int. Ce " taille de " ne fonctionne que si vous êtes dans la même fonction.

En fait, je suis de retour à C après beaucoup de jours de C #, je ne me souviens donc pas (et manque < code> array.length () )

Cordialement!


2 commentaires

Votre tableau myARRAY contient 8 éléments. 5 d'entre eux ont été explicitement initialisés avec 1, 2, 3, 0 et 5 respectivement; Les 3 autres ont été implicitement initialisés avec 0.


Ouais je sais ... mais y a-t-il une méthode pour obtenir le compte 5?


9 Réponses :


11
votes

Vous ne pouvez pas faire cela une fois que le tableau est décrit à un pointeur - vous obtiendrez toujours la taille du pointeur.

Ce que vous devez faire est soit:

  • Utilisez une valeur sentinelle si possible, comme NULL pour les pointeurs ou -1 pour des nombres positifs.
  • Calculez-le quand il s'agit toujours d'une matrice et passez cette taille à toutes les fonctions.
  • Même chose que ci-dessus, mais en utilisant Funky Macro Magic, quelque chose comme: #define Arrsz (a) (tailleOf (a) / sizeof (* a)) . .
  • Créez votre propre type de données abstrait qui maintient la longueur d'élément dans une structure, de sorte que vous avez un moyen d'obtenir votre flay.length () . < / li>

2 commentaires

Ce n'est pas obligatoire de passer le pointeur .... Toute méthode en passant fonctionnerait.


@SwanandPurankar: Je ne sais pas ce que vous voulez dire exactement, mais en C, Void FOO (int [] Art) et VOID FOO (int * PTR) est un et le même. Ainsi, une matrice transmise à une fonction toujours se désintègre à un pointeur (au premier élément de la matrice).



1
votes

en C, vous ne pouvez pas car car la matrice se désintègre dans un pointeur (au premier élément) lorsqu'il est passé à une fonction.

Cependant, en C ++, vous pouvez utiliser Déduction sur l'argument de modèle pour atteindre le même.


2 commentaires

J'espère que vous utiliseriez en C ++. ;-)


@Devsolar: Oui! Voir mon article LinkedIn avec: P



1
votes

Vous devez transmettre la longueur sous forme de paramètre supplémentaire (comme Strncpy .

De petites variations de ces techniques existent, comme en regroupant la longueur avec le pointeur dans sa propre classe ou en utilisant un marqueur différent pour la longueur de la matrice, mais ils sont fondamentalement vos seuls choix.


2 commentaires

Mais vous connaissez la longueur, vous l'avez écrit!


Okey .... J'ai compris ce que vous attendez que je passe de moi ... Mais comment cela aiderait-t-il, je ne pouvais pas comprendre!



31
votes

Vous ne pouvez pas calculer la taille d'un tableau lorsque tout ce que vous avez est un pointeur.

Le seul moyen de faire cette "fonction de type" "est de définir une macro: p> xxx

Ceci est livré avec toutes les réserves habituelles des macros, bien sûr. p>

EDIT: strong> (Les commentaires ci-dessous appartiennent vraiment à la réponse ...) p>

  1. vous ne peut pas strud> déterminer le nombre d'éléments initialisés em> dans un tableau, sauf si vous initialisez tous les éléments à une valeur "invalide" en premier et à compter les valeurs "valides" manuellement. Si votre matrice a été définie comme ayant 8 éléments, pour le compilateur, il dispose de 8 éléments, que vous soyez initialisé seulement 5 d'entre eux. LI>
  2. vous ne peut pas strud> déterminer la taille d'un tableau dans une fonction à laquelle ce tableau a été transmis en tant que paramètre. Pas directement, pas à travers une macro, pas de quelque manière que ce soit. Vous pouvez SEULEMENT STRUT> déterminer la taille d'un tableau dans la portée, il a été déclaré dans em>. Li> ol>

    L'impossibilité de déterminer la taille de la matrice dans une fonction appelée peut être comprise une fois que vous réalisez que Tailleof () CODE> est un Compile-Time em> opérateur fort>. Il pourrait regarder em> comme un appel de fonction d'exécution, mais ce n'est pas le cas: le compilateur em> détermine la taille des opérandes et les insère sous forme de constantes. P>

    Dans la portée, le tableau est déclaré, le compilateur a les informations qu'il s'agit en réalité d'une matrice et combien d'éléments il a. p>

    dans une fonction à laquelle le tableau est passé, tout le compilateur voit est un pointeur. (Considérez que la fonction pourrait être appelée avec de nombreux différents tableaux em> et rappelez-vous que Tailleof () code> est un opérateur de compilation em>. P >

    Vous pouvez passer à C ++ et utiliser code>. Vous pouvez définir un vecteur structurer code> plus des fonctions qui manipulent cela, mais ce n'est pas vraiment confortable: p>

    #include <stdlib.h>
    
    typedef struct
    {
        int *  _data;
        size_t _size;
    } int_vector;
    
    int_vector * create_int_vector( size_t size )
    {
        int_vector * _vec = malloc( sizeof( int_vector ) );
        if ( _vec != NULL )
        {
            _vec._size = size;
            _vec._data = (int *)malloc( size * sizeof( int ) );
        }
        return _vec;
    }
    
    void destroy_int_vector( int_vector * _vec )
    {
        free( _vec->_data );
        free( _vec );
    }
    
    int main()
    {
        int_vector * myVector = create_int_vector( 8 );
        if ( myVector != NULL && myVector->_data != NULL )
        {
            myVector->_data[0] = ...;
            destroy_int_vector( myVector );
        }
        else if ( myVector != NULL )
        {
            free( myVector );
        }
        return 0;
    }
    


6 commentaires

Merci! C'est bon mais je serais plus heureux avec la fonction!


@Swanand Purankar: Je peux comprendre cela, mais c'est tout simplement impossible à faire dans C.


@Swanand purankar: Je viens de voir votre commentaire sous votre question ... Notez que cette macro pas ne vous donne pas 5 dans votre exemple, mais 8. Il n'y a aucun moyen pour C de dire quoi / comment De nombreux éléments de réseau ont été attribués (sauf si vous insérez manuellement des valeurs spéciales pour des éléments non initialisés et que vous effectuez également un comptage manuel de valeurs non spéciales). C elle-même ne peut que vous dire la taille globale de la matrice.


@DevSolar: J'ai essayé cette macro, mais le problème est que je ne peux pas utiliser cette macro dans les fonctions auxquelles un tableau est passé par le pointeur! De l'aide??


@DevSolar: merci encore !! Je dois utiliser c pour ma demande afin que vous ayez dit, je dois coder mon chemin autour des limitations! Merci beaucoup!!


Vous devriez ajouter plus d'une parenthèse autour de votre macro #define array_length (tableau) (tailleOf (tableau) / Tiplazof (tableau [0])) Sinon, vous pourriez obtenir des résultats étranges lorsque vous utilisez dans le contexte d'une équation plus importante.



2
votes

Qu'est-ce que vous demandez simplement ne peut pas être fait.

Au moment de l'exécution, les seules informations mises à la disposition du programme sur un tableau sont l'adresse de son premier élément. Même la taille des éléments n'est déduite que du contexte de type dans lequel le tableau est utilisé.


0 commentaires

1
votes
int getArraySize(void *x)
{
    char *p = (char *)x;
    char i = 0;
    char dynamic_char = 0xfd;
    char static_char = 0xcc;

    while(1)
    {
        if(p[i]==dynamic_char || p[i]==static_char)
            break;
        i++;
    }
    return i;
}

int _tmain(int argc, _TCHAR* argv[])
{   
    void *ptr = NULL;
    int array[]={1,2,3,4,5,6,7,8,9,0};
    char *str;
    int totalBytes;

    ptr = (char *)malloc(sizeof(int)*3);
    str = (char *)malloc(10);

    totalBytes = getArraySize(ptr);
    printf("ptr = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(int)));

    totalBytes = getArraySize(array);
    printf("array = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(int)));

    totalBytes = getArraySize(str);
    printf("str = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(char)));
    return 0;
}

2 commentaires

Pouvez-vous expliquer pourquoi "0xfd" et "0xcc" ??


Cela ne fonctionne que dans le mode de débogage de MS Visual C ++, et seulement (car i est un caractère) pour les tailles <256 où aucun élément n'est un 0xfd . Down-voting, car la réponse ne fonctionne pas en général et ne documente même pas quand elle peut ou ne pas fonctionner. Voir Cette réponse pour certains numéros magiques utilisés par Visual C ++



-3
votes

Taille d'un tableau en C est:

int a[]={10,2,22,31,1,2,44,21,5,8};

printf("Size : %d",sizeof(a)/sizeof(int));


3 commentaires

Une fois que vous passez A à une fonction de paramètre, cette astuce ne fonctionne pas, car tailleOf () est une fonction de compilation.


Cela ne répond pas à la question. Comme il y a déjà des réponses qui font, je vous recommanderais de supprimer celui-ci. Si quelque chose, cette réponse proposée vous identifiera en tant que développeur qui manque d'événement les compétences les plus élémentaires.


@ MD-SHAHRIAR Je cherchais une fonction qui fera cette tâche.



0
votes

est très tard. Mais j'ai trouvé une solution de contournement pour ce problème. Je sais que ce n'est pas la solution appropriée mais peut fonctionner si vous ne voulez pas traverser une gamme de nombres entiers.

Vérification '\ 0' ne fonctionnera pas ici

Tout d'abord, mettez n'importe quel caractère dans la matrice au moment de l'initialisation xxx

puis après la vérification des valeurs suivantes "x ' Xxx

laissez-moi savoir s'il est d'une utilisation.


0 commentaires

1
votes

impossible. Vous devez passer la taille de la matrice de la fonction, vous appelez cette fonction de. Lorsque vous passez la matrice à la fonction, seule l'adresse de départ n'est pas transmise à l'ensemble de la taille et lorsque vous calculez la taille de la matrice, le compilateur ne sait pas combien de taille / mémoire, ce pointeur a été attribué par le compilateur. Donc, l'appel final est que vous devez passer la taille de la matrice pendant que vous appelez cette fonction.


0 commentaires