Considérons l'exemple suivant:

#include <stdio.h>

void change_byte(int *byte);

int main()
{
    int byte = 0;
    change_byte(&byte);
    printf("Byte : %d \r\n", byte);
}

void change_byte(int *byte)
{
    *byte= 5;
}

Je modifie simplement la valeur d'un entier dans une fonction en passant l'entier comme un pointeur sur la fonction. Il donne:

Byte : 5

Tout va bien.


Je veux généraliser la fonction de modifier un tableau d'entier au lieu d'un entier. Voici le code:

#include <stdio.h>
#define SIZE_ARRAY 10

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    for(int i = 0 ; i < size ; i++)
    {
        array[i] = 5;
    }
}

Il donne:

Array : 5 5 5 5 5 5 5 5 5 5 

J'aime bien parce que cela ne fait pas de recours dynamique, mais j'ai du mal à comprendre comment cela fonctionne. D'après ce que je comprends, la matrice est convertie en un pointeur lors de la saisie de la fonction Change_array. Mais quand je changais la valeur de l'octet dans l'exemple précédent, je faisais * byte = 5. Ici, je fais un tableau [I] = 5 et pas * Array [i] = 5.


Enfin, je souhaite modifier l'exemple précédent pour modifier la matrice basée sur un tableau global:

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    array = global_array;
}

Il donne:

Array : 0 0 0 0 0 0 0 0 0 0   

Pourquoi est-ce tellement? Qu'est-ce que je dois changer pour le faire fonctionner?

Merci.

1
user10923145 30 mars 2021 à 10:02

2 réponses

Meilleure réponse

Considérez votre premier programme.

#include <stdio.h>

void change_byte(int *byte);

int main()
{
    int byte = 0;
    change_byte(&byte);
    printf("Byte : %d \r\n", byte);
}

void change_byte(int *byte)
{
    *byte= 5;
}

Dans ce programme, l'objet byte est transmis à la fonction change_byte par référence via un pointeur à celui-ci.

change_byte(&byte);

Dans C Passage par référence, c'est transmettre un objet indirectement à travers un pointeur TP.

Donc la déséroférience du pointeur byte déclarée par paramètre de fonction

void change_byte(int *byte);

Vous obtenez un accès direct à l'objet pointu byte du type int défini dans la principale.

Maintenant considérons votre deuxième programme

#include <stdio.h>
#define SIZE_ARRAY 10

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    for(int i = 0 ; i < size ; i++)
    {
        array[i] = 5;
    }
}

Dans Main, vous avez déclaré un tableau entier

int array[SIZE_ARRAY] = {0};

Les concepteurs de tableau utilisés dans les expressions avec des exceptions rares sont convertis en pointeurs à leurs premiers éléments.

Ainsi cet appel

change_array(array, SIZE_ARRAY);

Est équivalent à

change_array( &array[0], SIZE_ARRAY);

Donc la déséroférance du pointeur dans la fonction que vous pouvez modifier le premier élément de la matrice définie dans la principale.

Mais les éléments de tableau sont stockés dans une ampleur de la mémoire continue. Ainsi, à l'aide de l'arithmétique du pointeur et d'avoir un pointeur sur le premier élément d'une matrice, vous pouvez accéder à tous les éléments du tableau.

En fait, tous les éléments du tableau array sont passés à la fonction change_array par référence via un pointeur sur le premier élément du tableau.

Par exemple, la boucle dans la fonction que vous pouvez réécrire comme

    for(int i = 0 ; i < size ; i++)
    {
        *( array + i ) = 5;
    }

Considérons maintenant votre troisième programme.

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array(int *array, int size);

int main()
{
    int array[SIZE_ARRAY] = {0};
    change_array(array, SIZE_ARRAY);
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array[i]);
    }
}

void change_array(int *array, int size)
{
    array = global_array;
}

Comme il a été signalé déjà, le tableau array est passé à la fonction change_array est converti en un pointeur à son premier élément.

Vous pouvez imaginer que l'appel de la fonction et sa définition de la manière suivante (je renommerai le premier paramètre de fonction pour éviter le nom d'ambiguïté).

change_array(array, SIZE_ARRAY);

//...

void change_array( /* int *parm_array, int size */)
{
    int * parm_array = array;
    int size = SIZE_ARRAY;

    parm_array = global_array;
}

Ce sont les paramètres de fonction sont ses variables locales. Le paramètre parm_array est vivant jusqu'à ce que la fonction arrête son exécution.

Ainsi cette déclaration

    parm_array = global_array;

Attribuez le pointeur au premier élément du tableau global global_array à la variable locale parm_array de la fonction. Cette affectation ne touche de quelque manière que ce soit le tableau array défini dans la principale. Il ne modifie que la variable locale parm_array déclarée dans la fonction change_array.

Pour atteindre l'attendu de votre part, vous pouvez définir en principal un pointeur initialisé par le tableau array. Et dans la fonction change_array, vous pouvez réaffirmer le pointeur avec le tableau global_array le transmettre à la fonction par référence de la même manière que vous avez passé l'objet byte dans votre premier programme.

Voici un programme démonstratif.

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array( int **array_ptr );

int main()
{
    int array[SIZE_ARRAY] = {0};
    int *array_ptr = array;
    
    change_array( &array_ptr );
    
    printf("Array : ");
    for(int i = 0 ; i < SIZE_ARRAY ; i++)
    {
        printf("%d ", array_ptr[i]);
    }
}

void change_array( int **array_ptr )
{
    *array_ptr = global_array;
}

La sortie du programme est '

Array : 5 5 5 5 5 5 5 5 5 5 
0
Vlad from Moscow 30 mars 2021 à 17:26

Pour une meilleure compréhension (et une meilleure exercice), modifiez votre fonction

void change_array(int *array, int size)
{
    array = global_array;
}

À

void change_array(int *array, int size)
{
    array = global_array;
    for (int i=0; i < size; ++i)
        printf("%d ", array[i]);
}

Demandez-vous, quelle est la sortie 'signifie'.

0
Erdal Küçük 30 mars 2021 à 07:42