【问题标题】:Incrementation using functions使用函数递增
【发布时间】:2020-11-11 16:53:59
【问题描述】:

我想使用 C 中的函数增加整数的值

所以我首先编写了一个函数 inc,在其中增加整数 v 的值。然后在主函数中我声明了一个新变量 a 并使用 inc(a) 函数递增。

这是我的代码:

#include<stdio.h>
void inc(int v)
{
    v++;
}
int main()
{
    int a;
    scanf("%d",&a);
    inc(a);
    printf("%d",a);
    return 0;
}

但输出与输入值相同。它没有增加。

即如果我将输入作为 45,我期望值 46 作为输出。但是输出仍然是45。我哪里出错了?有人请解释一下。

所以我做了一些研究,发现使用指针时会出现预期的答案,这是代码

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

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

为什么没有指针的方法不正确?

同样在第二种方法中,为什么我们将参数作为地址传递,即 &a。为什么我们不能将它作为一个传递?

我是 C 的新手。所以请帮助我解决我的疑问

【问题讨论】:

  • 你需要一本 C 的书。简短的回答:C 是默认的按值传递。如果未指定指针,则inc 中的v 只是具有相同值的maina 的副本。也就是说,v++ 会在inc 的范围内增加 v,但不会影响其他人。对于指针,(*v)++ 表示“在 v 指向的地方加一个值”。
  • C 和 C++ 是非常不同(但相似)的语言。我建议您不要尝试同时学习两者。先学一个,当你开始学习另一个时,准备好“忘掉”其中的一部分。
  • 您可能想了解将参数传递给函数的方法:按值传递和按引用传递。
  • @RobertSsupportsMonicaCellio 我不认为,因为 OP 似乎完全了解那些与语言无关的概念,只是不知道 C 如何/为什么支持它或不支持它。

标签: c function pointers increment


【解决方案1】:

问题在于默认情况下 c 对函数使用按值传递。这意味着如果您在 main 中以下列方式调用该函数,

int a = 45;
inc(a);

函数只知道值 45 而不是变量 a。因此,它将创建一个新的局部变量(在您的情况下为 int v),该变量存储值 45 并递增。由于该函数对 a 一无所知,特别是不知道 a 在内存中的位置,因此它无法修改它。一般有两种方法可以解决:

  1. 使用返回:

在这种情况下,函数会继续使用传递的参数值来操作本地副本。最后它可以返回函数的所需输出。这将通过以下方式实现:

#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;
}
  1. 将参数作为指针传递:

在第二种情况下,您已经发现,您通过引用传递您的论点。这样,函数就可以知道 a 的内存地址,因此可以直接操作存储在 a 中的值。函数定义void inc(int *v) 中 v 旁边的小星图标定义该函数将地址作为输入。因此,您必须使用 &amp;a 传递 a 的地址,就像您发布的代码中所做的那样。

总结:

您的函数或您实现的任何未来函数可以根据您的需要是上述两种类型之一。然而,作为指导方针,它应该永远不要在传递的地址处操作值并同时返回一些东西。这可能会导致混淆,并导致代码的可读性一般降低。

【讨论】:

    【解决方案2】:

    “为什么没有指针的方法不正确?”

    如果你使用指针参数,你的意图是指向调用者中的一个对象。然后,您可以在被调用函数中修改此对象。这就是所谓的引用传递。在调用者中传递对对象的引用。

    如果不使用指针,只需将变量的值按值传递给函数,这意味着参数的值被分配给函数局部变量。在函数内部,您只能修改此函数局部变量的值,而不能修改调用者中的对象。

    What's the difference between passing by reference vs. passing by value?

    同样在第二种方法中,为什么我们将参数作为地址传递,即&amp;a。为什么我们不能将其传递为a?”

    &amp; 运算符在这种情况下获得了a 的地址,需要将其分配给指针参数。

    指针始终存储要指向的对象的地址,而不是指向对象的值。

    没有地址,指针不代表对象。


    请了解有关指针的更多信息并阅读一本好的 C 入门书籍,例如 Modern C(您可以从那里获得免费副本)。

    您也可以在此处找到此内容和其他内容:

    The Definitive C Book Guide and List

    通常在前几章中解释函数和参数传递。

    【讨论】:

      【解决方案3】:

      您总是将变量、值或引用的副本传递给函数。因此,发送值的副本不会影响main 函数。但是,发送其引用的副本会影响 main 函数,因为您说明了变量在内存中的位置。

      【讨论】:

        【解决方案4】:

        同样在第二种方法中,为什么我们将参数作为地址传递,即 &a。为什么我们不能将它作为一个传递?

        你这里是用指针来操作的,当你把address的值改成那个指针时,原来的值也变了。

        另一方面,当您按值传递变量a 时,它只会复制并在函数调用中增加它,原始值不会发生变化。第一种方法不起作用,因为函数中传递的变量是传值类型。

        编辑: 这个问题现在只在 C 中标记。但是对于额外的信息,有一种方法可以在 C++ 中不使用指针,它被称为传递引用(使用原始副本进行操作变量),可以用函数签名上的 & 符号表示,例如:

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

        【讨论】:

          【解决方案5】:

          简答:

          C 是默认值传递。如果未指定指针,则inc 中的v 只是maina 的副本,具有相同的值。

          也就是说,v++ 会在inc 的范围内增加v,但不会影响其他人。

          对于指针,(*v)++ 表示“在 v 指向的地方加一个值”

          如果您使用 C++,通过引用传递是另一种解决方案。

          【讨论】:

            【解决方案6】:

            Pointer 是一个包含对象地址的变量。指针不携带有关对象内容的信息,但包含有关对象所在位置的信息。

            指针在 C 编程中被广泛使用。 处理数组时经常使用指针。

            可以将计算机内存视为一系列带编号的单字节单元,可以单独或按块访问。

            内存中的每个变量都有自己的地址——它所在的第一个单元格的编号,以及它的值。指针也是分配在内存中的变量。它还有一个地址,它的值是某个其他变量的地址。声明为指针的变量在 RAM 中占用 4 个字节(对于 32 位版本的编译器)。

            与任何变量一样,指针必须声明

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

            看这个例子:

            #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;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-07-08
              • 2011-07-02
              • 1970-01-01
              • 1970-01-01
              • 2020-08-18
              • 1970-01-01
              • 2017-06-24
              • 2018-10-11
              相关资源
              最近更新 更多