Comment puis-je modifier un tableau int dans une fonction
Im nouveau avec le langage c et je vais avoir difficile tout en essayant de modifier un tableau sur ma principale fonction à l'aide d'une autre fonction. En plus de voir la solution que j'aimerais aussi obtenir une explication complète de ce qui est mal avec mon code et quelle est l'explication de votre solution.
OK, donc je l'ai fait aussi beaucoup d'essais et d'erreur d'expérimentation, mais sans succès pour résoudre mon problème. Finalement, c'est mon code actuel:
#include <stdio.h>
#define MAX 20
typedef int Values[MAX];
int changeArr(Values *vals2)
{
*vals2[0] = 200;
*vals2[1] = 100;
printf("%d and ", *vals2[0]);
printf("%d\n", *vals2[1]);
return 0;
}
int main (int argc, char *argv[])
{
Values vals;
changeArr(&vals);
printf("%d and ", vals[0]);
printf("%d\n", vals[1]);
return 0;
}
De sortie est:
200 and 100
200 and 0
Au lieu de:
200 and 100
200 and 100
OriginalL'auteur Popokoko | 2012-12-22
Vous devez vous connecter pour publier un commentaire.
Version 1:
Au lieu de passer un pointeur vers le tableau, de passer un pointeur vers le premier élément du tableau.
Version 2:
utiliser des parenthèses pour compenser la priorité.
Le problème dans ton code, c'est que
est
*(vals2[1])
, de sorte qu'il déréférence un pointeur à une unité deValues
après la passé pointeur. Vous n'avez pas accessible mémoire allouée là, donc c'est un comportement indéterminé. Dans la pratique, c'est la même que l'accès àpour un
Mais votre
vals
n'est pas seulement (équivalent à) unint arr[1][MAX];
, de sorte que vous accédez en dehors des limites. Mais si rien de pire arrive,*vals2[1] = 100;
danschangeArr
jeux devals[MAX]
dansmain
à 100. Il peut écraser quelque chose de crucial, si.Dans
int changeArr(Values *vals2)
vous passez un pointeur vers un tableau deMAX
int
s, resp le premier tableau dans un tableau deValues
. Puisvals2[1]
est le deuxième tableau, tableau deValues
(qui n'existe pas ici), et*vals2[1] == vals2[1][0]
la premièreint
dans le second tableau. Vous souhaitez modifier des éléments de la première (et la seule) de la matrice de dans la pointe-à bloc de mémoire, si vous souhaitez accéder àvals2[0][1]
, ou, de manière équivalente(*vals2)[1]
.Une image:
dans
changeArr
, le pointeurvals2
points de la matricevals
. Puisque c'est un pointeur vers unint[MAX]
,vals2+1
points à unint[MAX]
à un décalage deMAX*sizeof(int)
octets après le début devals
(qui est juste derrière la fin devals
).vals2[1]
, ou, de manière équivalente*(vals2 + 1)
, est ce tableau juste aprèsvals
(qui n'existe pas).Vous souhaitez modifier
vals[1]
, qui est situé dans le tableauvals2[0]
, à un décalage de1*sizeof(int)
octets, de sorte que vous devezvals2[0][1]
ou, de manière équivalente(*vals2)[1]
.Dans ce cas, lorsque vous voulez
fscanf
dans lei
-ème élément du tableau, vous pouvez prendre son adresse,fscanf("%d", &(*vals2)[i]);
ou vous pouvez éviter la référence implicite par[i]
et passerfscanf("%d", (*vals2)+i)
. Mais je préfère prendre l'adresse,fscanf("%d", &object);
de manière uniforme, indépendamment de savoir si l'objet est un ordinaireint
variable ou un élément de tableau.Merci Daniel! C'est certainement la meilleure explication iv e a reçu plus de ce site web. Comme un étudiant qui est nouveau avec le C, je suis sûr que ce post pourra aider beaucoup d'autres. De toute façon, si u m'a laissé sans voix, je vais profiter de cette occasion demander: (1) en théorie, il n'existe aucune différence à partir de la version 1 à la version 2 codes? (2) est-il un moyen facile pour faire une boucle de telles valeurs de tableau jusqu'à ce que le dernier indice qui a été affecté (en d'autres termes, disons que le tableau est de taille 10 et seulement 3 ont été assignés et je veux boucle seulement ces trois éléments) ?
(1) Oui, il y a une différence. Dans la version 1, la fonction reçoit un
int*
, il ne sait pas comment grand que le tableau qu'il des points dans l'est, et le type ne peut pas le document comment grand un tableau est prévu. Dans la version 2, la fonction reçoit unint (*)[20]
, de sorte qu'il sait précisément combien d'éléments*vals2
a - mais il ne sait pas un bloc de combien deint[20]
l'argumentvals2
lui-même. Pour quoi la fonction, je pense que la version 1 est plus approprié, mais ce serait mieux de passer également un argument size, de sorte que la fonction n'a pas d'accéder à des éléments qui n'existent pas.(2) en fait, vous devez avoir une taille argument/retour/paramètre de dire à celui qui le reçoit combien il y a d'éléments à considérer. Dans certains cas, vous pouvez marquer la fin avec une sentinelle de la valeur (comme on le fait pour les C de chaînes avec l'0-terminator, mais en général, 0 est une entrée valide dans un
char[]
, de sorte que vous ne pouvez pas l'utiliser pour d'autres utilisations des tableaux de caractères), mais un paramètre de taille est plus universellement applicable.OriginalL'auteur Daniel Fischer