1
votes

Incrémentation à l'aide de fonctions

Je veux incrémenter la valeur d'un entier en utilisant des fonctions en C.

J'ai donc d'abord écrit une fonction inc où j'ai incrémenté la valeur de l'entier v. Ensuite, dans la fonction principale, j'ai déclaré un nouvelle variable a et incrémentée en utilisant la fonction inc (a).

Voici mon code:

#include<stdio.h>
void inc(int *v) {
    (*v)++;
}

int main() {
    int a;
    scanf("%d", &a);
    inc(&a);
    printf("%d", a);
    return 0;
}  

Mais la sortie est la même que la valeur d'entrée. Ce n'est pas une incrémentation.

c'est-à-dire si je donne l'entrée 45, j'attends la valeur 46 comme sortie. Mais la sortie est toujours de 45. Où est-ce que je vais mal? Quelqu'un s'il vous plaît expliquer.

J'ai donc fait quelques recherches et j'ai trouvé que la réponse attendue arrive lorsque des pointeurs sont utilisés et voici le code pour cela

#include<stdio.h>
void inc(int v)
{
    v++;
}
int main()
{
    int a;
    scanf("%d",&a);
    inc(a);
    printf("%d",a);
    return 0;
}
Pourquoi la méthode sans pointeurs n'est-elle pas correcte?

Aussi dans la deuxième méthode, pourquoi passons-nous l'argument comme adresse ie & a. Pourquoi ne pouvons-nous pas le passer comme un?

Je suis un débutant en C. Alors s'il vous plaît, aidez-moi avec mes doutes


11 commentaires

Vous avez besoin d'un livre pour C. Réponse courte: C est le passage par valeur par défaut. Si le pointeur n'est pas spécifié, un v dans inc est juste une copie de a dans main avec la même valeur . Autrement dit, v ++ augmenterait v dans la portée de inc mais n'en affecterait aucun autre. Pour le pointeur, (* v) ++ signifie "ajouter une valeur à l'endroit où v pointe vers".


C et C ++ sont des langages très différents (mais similaires). Je vous recommande de ne pas essayer d'apprendre les deux en même temps. Apprenez-en un d'abord et soyez prêt à en «désapprendre» une partie lorsque vous commencez à apprendre l'autre.


Vous voudrez lire sur les façons de passer un argument à une fonction: passer par valeur et passer par référence.


Est-ce que cela répond à votre question? Quelle est la différence entre passer par référence et passer par valeur?


@RobertSsupportsMonicaCellio Je ne pense pas, car OP semble être au courant exactement de ces concepts indépendants du langage et ne comprend tout simplement pas comment / pourquoi C le prend ou ne le prend pas en charge.


@Yunnosch j'ai posté une réponse. N'hésitez pas à suggérer de modifier si ma description n'est pas claire.


@Yunnosch OP demande " Pourquoi la méthode sans pointeurs n'est-elle pas correcte? " ce qui est une indication pour moi qu'il ne comprend même pas le concept. D'où le duplicata proposé.


@RobertSsupportsMonicaCellio Cette dupe est indépendante du langage, cependant, et alors qu'elle explique les différences entre les deux méthodes, ici l'OP pose spécifiquement des questions sur C, où le passage par "référence" est obtenu en passant un pointeur par valeur < / i>. Il y a peut-être une meilleure dupe quelque part.


@Bob__ Eh bien, d'accord. Il y a bien sûr partout une dupe pour C. Nous devons la trouver.


Est-ce que cela répond à votre question? passant par référence en C


Uniquement mon avis: Le total des bonnes réponses ici ET liées dans les commentaires répond à la question. J'utiliserai probablement cela comme dupe pour des questions similaires. À mon avis, aucun des doublons proposés ne couvre ma compréhension de cette question. Je ne le mentionne qu'au cas où vous vous demanderiez pourquoi mon vote serré n'est pas là ...


6 Réponses :


1
votes

Vous transmettez toujours une copie de votre variable, valeur ou référence à la fonction. Ainsi, l'envoi d'une copie de la valeur n'affectera pas la fonction main . Cependant, l'envoi d'une copie de sa référence affectera la fonction main car vous dites où se trouve votre variable dans la mémoire.


0 commentaires

1
votes

Toujours dans la deuxième méthode, pourquoi passons-nous l'argument comme adresse, c'est-à-dire & a. Pourquoi ne pouvons-nous pas le faire passer pour un?

Vous êtes ici en train de manipuler avec un pointeur, lorsque vous changez la valeur d'adresse en ce pointeur, la valeur d'origine est également modifiée.

En revanche, lorsque vous passez la variable un par valeur, il fera juste une copie et l'incrémentera dans l'appel de fonction, aucune modification ne se produira dans la valeur d'origine. La première méthode ne fonctionne pas car la variable passée dans la fonction était de type passe-par-valeur.

Modifier: Cette question n'est désormais balisée qu'en C. Mais pour plus information, il existe une méthode pour le faire sans pointeurs en C ++, elle est appelée pass-by-reference (manipule avec la copie originale des variables) qui pourrait être représentée par une esperluette sur la signature de la fonction, quelque chose comme:

void changeRealValue(int& value) {
// _____________________^________
    value++; // original value is incremented now
}

0 commentaires

0
votes

Pointer est une variable contenant l'adresse d'un objet. Le pointeur ne porte pas d'informations sur le contenu de l'objet, mais contient des informations sur l'emplacement de l'objet.

Les pointeurs sont largement utilisés dans la programmation C. Les pointeurs sont souvent utilisés lorsque vous travaillez avec des tableaux.

La mémoire de l'ordinateur peut être considérée comme une séquence de cellules numérotées à un octet auxquelles on peut accéder individuellement ou par blocs.

Chaque variable dans la mémoire a sa propre adresse - le numéro de la première cellule où elle se trouve, ainsi que sa valeur. Un pointeur est également une variable allouée en mémoire. Il a également une adresse et sa valeur est l'adresse d'une autre variable. Une variable déclarée comme un pointeur occupe 4 octets en RAM (dans le cas d'une version 32 bits du compilateur).

Un pointeur, comme toute variable, doit être déclaré .

#include <stdio.h>
#include <stdlib.h>
int main()
{
  int a, *b;
  system("chcp 1251");
  system("cls");
  a = 134;
  b = &a;
  // %x = display the number in hexadecimal form
  printf("\n The value of the variable a is %d = %x hex.", a,a);
  printf("\n The address of the variable a is %x hex.", &a);
  printf("\n Data at pointer address b are equal %d = %x hex.", *b,*b);
  printf("\n The value of b pointer is %x hex.", b);
  printf("\n Location address of pointer b is %x hex.", &b);
  getchar();
  return 0;
}

Regardez cet exemple:

сhar c;   // variable
char *p; // pointer
p = &c;  // p = address of c


0 commentaires

2
votes

Le problème est que par défaut, c utilise le passage par valeur pour les fonctions. Cela signifie que si vous appelez la fonction de la manière suivante dans votre main,

#include<stdio.h>
void inc(int v)
{
    v++;
    return v
}

int main()
{
    int a;
    scanf("%d",&a);
    a = inc(a);
    printf("%d",a);
    return 0;
}

la fonction ne connaît que la valeur 45 mais pas la variable a. Il va donc créer une nouvelle variable locale (int v dans votre cas) qui stocke la valeur 45 et s'incrémente. Puisque la fonction ne sait rien de a, en particulier pas où a est situé en mémoire, elle ne peut pas le modifier. Il existe généralement deux façons de résoudre ce problème:

  1. Utilisation des retours:

Dans ce cas, la fonction continue de manipuler une copie locale avec les valeurs des arguments passés. En fin de compte, il peut renvoyer la sortie souhaitée de la fonction. Cela serait mis en œuvre de la manière suivante:

int a = 45;
inc(a);
  1. Passer l'argument comme pointeur:

Dans le second cas, que vous avez déjà trouvé, vous passez votre argument par référence. De cette façon, la fonction apprend à connaître l'adresse mémoire de a et peut donc manipuler directement la valeur stockée à a. La petite icône en forme d'étoile à côté de v dans la définition de la fonction void inc (int * v) définit que la fonction prend une adresse comme entrée. Par conséquent, vous devez passer l'adresse d'un en utilisant & a comme cela est fait dans le code que vous avez publié.

Résumé:

Votre fonction, ou tout futur les fonctions que vous implémentez peuvent être de l'un des deux types ci-dessus selon vos besoins. Il doit cependant, à titre indicatif, ne jamais manipuler les valeurs aux adresses passées et renvoyer quelque chose en même temps. Cela peut prêter à confusion et entraîner un code moins lisible en général.


0 commentaires

1
votes

"Pourquoi la méthode sans pointeurs n'est-elle pas correcte?"

Si vous utilisez un paramètre de pointeur, votre intention est de pointer vers un objet dans l'appelant. Vous pouvez ensuite modifier cet objet dans la fonction appelée. C'est ce que l'on appelle le passe par référence . Vous passez une référence à un objet dans l'appelant.

Si vous n'utilisez pas de pointeur, vous passez simplement la valeur de la variable par valeur à la fonction, ce qui signifie que la valeur de l'argument est affectée à une variable locale de fonction. À l'intérieur de la fonction, vous ne pouvez modifier que la valeur de cette variable locale de la fonction, mais pas un objet dans l'appelant.

Quelle est la différence entre passer par référence et passer par valeur?

Toujours dans la deuxième méthode, pourquoi passons-nous l'argument comme adresse, c'est-à-dire & a . Pourquoi ne pouvons-nous pas le passer comme a ? "

L'opérateur & gagne dans ce cas l'adresse de a , qui doit être affectée au paramètre pointeur.

Un pointeur stocke toujours l'adresse d'un objet vers lequel pointer, pas une valeur de l'objet pointé.

Sans adresse, le pointeur ne désigne pas un objet.

Veuillez en savoir plus sur les pointeurs et lire un bon livre de départ en C comme C moderne (vous pouvez obtenez-en une copie gratuite ici).

Ceci et d'autres que vous pouvez également trouver ici:

Le guide et la liste des livres C définitifs

Il est généralement expliqué dans les premiers chapitres sur les fonctions et le passage d'arguments.


0 commentaires

1
votes

Réponse courte:

C est le passage par valeur par défaut. Si le pointeur n'est pas spécifié, un v dans inc est juste une copie de a dans main avec la même valeur .

Autrement dit, v ++ augmenterait v dans la portée de inc mais n'en affecterait aucun autre.

Pour le pointeur, (* v) ++ signifie "ajouter une valeur à l'endroit où v pointe vers"

Si vous utilisez C ++, la transmission par référence est une autre solution.


0 commentaires