0
votes

Comment utiliser le pointeur vers le tableau bidimensionnel C

Comment modifier une valeur dans un tableau avec un pointeur en C?

int *Pointer
int array[2][2];
Pointer[1][1]= 6;

J'ai essayé ceci:

int *pointer;
int array[3][1];

mais lors de la compilation , J'obtiens une erreur de segmentation. Que faire?


2 commentaires

Montrez-le simplement. pointer = & array [2] [0]


Concernant «lors de la compilation»: Le code int * Pointer / int array [2] [2]; / Pointer [1] [1] = 6; < / code> n'obtient pas d'erreur de segmentation car il ne se compile pas, pour plusieurs raisons. Lorsque vous posez des questions sur le code dans Stack Overflow, copiez et collez le code exact . De simples erreurs typographiques peuvent empêcher les lecteurs de savoir quels sont réellement les problèmes et empêcher tout le monde de vous aider. De telles erreurs sont également susceptibles de vous faire baisser les votes, car elles rendent la question floue et peuvent également rendre les réponses inutiles.


5 Réponses :


1
votes

Vous pouvez accéder à n'importe quel élément avec cette syntaxe: array [x] [y] .

De la même manière, vous pouvez affecter votre pointeur à n'importe quel élément avec cette syntaxe: p = & array [x] [y] .


En C, vous pouvez souvent traiter les tableaux et les pointeurs comme "équivalents". Voici une bonne explication:

https://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c

Cependant, vous ne peut pas traiter un simple pointeur comme un tableau 2D. Voici un exemple de code:

/*
 * Sample output:
 *
 * array=0x7ffc463d0860
 * 1 2 3
 * 4 5 6
 * 7 8 9
 * p=0x7ffc463d0860
 * 0x7ffc463d0864:1 0x7ffc463d0868:2 0x7ffc463d086c:3
 * 0x7ffc463d0870:4 0x7ffc463d0874:5 0x7ffc463d0878:6
 * 0x7ffc463d087c:7 0x7ffc463d0880:8 0x7ffc463d0884:9
 */
#include <stdio.h>

int main()
{
  int i, j, *p;
  int array[3][3] = {
    {1,2,3},
    {4,5,6},
    {7,8,9}
  };

  // Dereference 2-D array using indexes
  printf("array=%p\n", array);
  for (i=0; i < 3; i++) {
    for (j=0; j < 3; j++)
      printf ("%d ", array[i][j]);
    printf ("\n");
  }

  // Dereference 2-D array using pointer
  p = &array[0][0];
  printf("p=%p\n", p);
  for (i=0; i < 3; i++) {
    for (j=0; j < 3; j++)
      printf ("%p:%d ", p, *p++);
    printf ("\n");
  }

  /* Compile error: subscripted value p[0][0] is neither array nor pointer nor vector
      p = &array[0][0];
      printf("p=%p, p[0]=%p, p[0][0]=%p\n", p, &p[0], &p[0][0]);
   */

  return 0;
}


2 commentaires

Supprimer l'astérisque


J'ai utilisé ce que vous avez suggéré et travaillé, le pointeur pointe vers le premier emplacement mémoire du tableau, mais je ne peux pas le modifier: pointer [1] [2] = 69; le programme plante simplement



1
votes

Étant donné un tableau int Array [Rows] [Columns] , pour créer un pointeur vers un élément spécifique Array [r] [c] , définissez int * Pointer = & Array [r] [c]; .

Ensuite, vous pouvez accéder à cet élément en utilisant * Pointer dans une expression, y compris en attribuant à * Pointer pour attribuer des valeurs à cet élément. Vous pouvez également faire référence à l'élément comme Pointer [0] , et vous pouvez faire référence à d'autres éléments dans la même ligne comme Pointer [y] , où y < / code> est tel que 0 ≤ y + c < Colonnes , ie , Pointer [y] reste dans la même ligne du tableau.

Vous pouvez également utiliser Pointer [y] pour faire référence aux éléments du tableau dans d'autres lignes tant qu'aucun des juristes de la langue ne vous voit le faire. (En d'autres termes, ce comportement n'est techniquement pas défini par le standard C, mais de nombreux compilateurs le permettent.) Par exemple , après Pointer = & Array [r] [c]; , Pointer [2 * Columns + 3] fera référence à l'élément Array [r + 2] [c + 3] .

Pour créer un pointeur que vous pouvez utiliser pour accéder aux éléments du tableau en utilisant deux dimensions, définissez int (* Pointer) [Columns] = & Array [r]; .

Ensuite, Pointer [x] [y] fera référence à l'élément Array [r + x] [y] . En particulier, après int (* Pointer) [Columns] = & Array [0]; ou int (* Pointer) [Columns] = Array; , Pointer [ x] [y] et Array [x] [y] feront référence au même élément.


5 commentaires

Pas seulement des juristes de langage, mais vous ne devez pas non plus laisser le compilateur le voir ... étant donné la quantité de code de vérification de plage dans les compilateurs récents ...


@AnttiHaapala: C'est une pratique courante dans le traitement du signal et d'autres logiciels qui gèrent les matrices. Étant donné un tableau bidimensionnel de foo , on passe un sous-tableau en passant un pointeur sur le foo à l'origine du sous-tableau avec les dimensions du sous-tableau et le nombre de colonnes dans le tableau conteneur. Donc, pour des raisons pratiques, les compilateurs doivent prendre en charge cela. Je ne l’ai pas par écrit, mais je me souviens que les développeurs de compilateurs d’Apple le soutiennent.


mais dans ce cas, il est toujours possible d'utiliser un pointeur VLA!


@AnttiHaapala: Si j'ai un float A [100] [100] et que je veux passer le sous-tableau 50 × 50 à partir de A [50] [50] , je le ferais besoin de prendre & A [50] [50] et de le lancer pour le passer en tant que float (*) [100] . Cela n'est pas non plus défini avec des interprétations pédantes de la norme C. Et toute API de changement de solution ne fonctionnera pas avec la grande quantité de logiciels matriciels existants.


En effet, vous auriez à passer la colonne 50 en argument avec un pointeur de ligne.



1
votes

Convertissez le tableau 2D en tableau 1D pour le transmettre à un pointeur, Et puis, vous êtes prêt à accéder au tableau avec un pointeur. Vous pouvez également utiliser cette méthode pour transmettre un tableau 2D à une fonction.

#include <stdio.h>

int main()
{
    int arr[2][2];
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            arr[i][j] = (2 * i) + j;
        }
    }
    int *Pointer = (int *)arr; // Type conversion
    /*
    &arr[0][0] = Pointer + 0
    &arr[0][1] = Pointer + 1
    &arr[1][2] = Pointer + 2
    &arr[2][2] = Pointer + 3

    Dereference Pointer to access variable behind the address
    *(Pointer + 0) = arr[0][0]
    *(Pointer + 1) = arr[0][1]
    *(Pointer + 2) = arr[1][2]
    *(Pointer + 3) = arr[2][2]

    */
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            printf("%d ", *(Pointer + (2 * i) + j)); // Accessing array with pointer
        }
        printf("\n");
    }
    return 0;
}


1 commentaires

Je n'ai pas compris ce que vous dites.



0
votes

Utilisation de la fonction wv_matalloc de https://www.ratrabbit.nl/ ratrabbit / content / sw / matalloc / introduction , vous pouvez écrire le code suivant:

cc -o main main.c wv_matalloc.c

Compiler avec:

#include <stdio.h>
#include "wv_matalloc.h"
int main()
{
   double **matrix;
   int m = 3;
   int n = 4;
   // allocate m*n matrix:
   matrix = wv_matalloc(sizeof(double),0,2,m,n);

   // example of usage:
   int i,j;
   for (i=0; i<m; i++)
      for (j=0; j<n; j++)
        matrix[i][j] = i*j;
   printf("2 3: %f\n",matrix[2][3]);
}

p >


0 commentaires

0
votes

1.

Vous n'avez jamais attribué de valeur à Pointer dans votre exemple. Ainsi, tenter d'accéder au tableau par Pointer appelle un comportement indéfini.

Vous devez attribuer Pointer par l'adresse du premier élément de array si le pointeur doit être une référence:

array[2][2] (by pointer) = 6
array[2][2] (by array istelf) = 6

2.

Vous ne pouvez pas utiliser la notation 2D ( p [1] [1] ) pour un pointeur vers int . Il s'agit d'une violation de la syntaxe C.


3.

Étant donné que les lignes de tableaux 2D statiques sont allouées ultérieurement en mémoire, vous pouvez également compter le nombre d'éléments du tableau jusqu'au élément de désir. Vous devez soustraire le décompte de 1 puisque l'indexation commence à 0 , et non à 1.

Comment ça marche?

Chaque ligne de array contient 2 éléments. a [1] [1] (le premier élément de la deuxième ligne) est directement stocké après les deux premiers.

Remarque: ce n'est pas la meilleure approche. Mais il convient de noter à côté de toutes les autres réponses comme solution possible .

#include <stdio.h>

int main (void)
{   
   int *Pointer;
   static int array[2][2];

   Pointer = *array;

   Pointer[2] = 6;

   printf("array[1][1] (by pointer) = %d\n", Pointer[3]);
   printf("array[1][1] (by array istelf) = %d\n", array[1][1]);
}

Résultat:

Pointer = *array;

Notes annexes:

  • Pour adresser le premier élément de la deuxième ligne par array [1] [2] appelle un comportement indéfini. Vous ne devriez pas utiliser cette méthode.

  • " mais lors de la compilation, j'obtiens une erreur de segmentation. "

Les erreurs de segmentation ne se produisent pas au moment de la compilation. Ils se produisent au moment de l'exécution. Cela vous donne juste une impression parce que votre implémentation exécute probablement immédiatement le programme après la compilation.


0 commentaires