【问题标题】:If I pass an address of a variable do I have to do a return?如果我传递变量的地址,我是否必须返回?
【发布时间】:2017-03-29 04:00:31
【问题描述】:

如果我有一个根据某些规则递增 global 变量的函数,并且我通过引用传递了一个变量,我是否必须返回或者该变量是否会被更新?这也适用于局部变量吗?例如:

static uint8_t counter = 1;

void add(uint8_t *variable)
{
   if (*variable == 5)
   {
    *variable = 7;

   } else if (*variable == 20)
   {
    *variable = 1;
   } else
   {
    *variable++;
   }
}

我将“添加”函数称为:

void function(void)
{
... some code...
add(&counter);
... some code...
}

【问题讨论】:

  • 也许我做错了,有更好的方法来解决这个问题......
  • 如果你有一个全局变量(但static),并且add函数在同一个翻译单元中,为什么首先要传递一个参数?
  • 看来您实际上是在传递指针的值(而不是通过 ref),尽管这段代码通常没有什么意义。如果变量是全局变量,则不需要传递它。此外,add 中的两个取消引用可能是不必要的。
  • 如果函数的目的是根据参数计算一个值,为什么不将该值作为 return 值返回?这避免了将指针传递给函数,并在函数内部修改它们指向的对象。例如:你喜欢void sin(double *result, double rads):
  • 其他人都提供了很好的指导,您应该听听,但要回答您的问题:不,通过指针更新变量时不需要返回语句。

标签: c pointers global-variables parameter-passing pass-by-reference


【解决方案1】:

此代码适用于任何类型的变量,无论是全局变量还是局部变量,因为对象是通过引用传递的。

然而更好的接口是函数返回它作为参数获得的指针。

uint8_t * add(uint8_t *variable)
{
   if (*variable == 5)
   {
    *variable = 7;

   } else if (*variable == 20)
   {
    *variable = 1;
   } else
   {
    *variable++;
   }

  return variable;
}

在这种情况下,您可以组合函数的调用或将其与等待相同指针的其他函数一起使用。例如

add( add( &counter ) );

SomeOtherFunction( add( &counter ) );

在多线程环境中调用函数且全局变量没有存储类说明符_Thread_local时存在差异。

【讨论】:

    【解决方案2】:

    全局变量在您的文件中具有可见性,因此您将其地址传递给的函数知道它。

    当全局变量在函数中可见时,为什么需要指针?

    你可以改变它的值,改变的值在调用函数中是可见的。

    如果您的问题是针对非全局变量,那么

        void func(int *q);   
    
        int main()
        {
           int a;
           func(&a);
           printf("%d \n",a);
        }
    
        void func(int *q)
        {
           *q = 10;
        }
    

    无需从函数返回任何内容,因为您正在传递变量的地址,并且对位置所做的更改在调用函数中可见

    【讨论】:

      【解决方案3】:

      对于全局(文件范围)变量,您根本不需要将它显式传递给函数。它已经在全局范围内,并且可以从所有函数(块范围)访问,假设您在本地(内部)范围内没有另一个同名的本地标识符。

      也就是说,对于一个中肯的答案,不,您不需要返回更新的值,它已经反映在实际参数中(@ 987654321@) 传递给函数。这对于全局范围和非全局范围变量都是一样的。

      【讨论】:

        【解决方案4】:

        避免使用全局变量。

        如果你必须使用一个全局变量,你根本不需要传递它——你可以直接修改它,即你不需要传递也不需要返回它。

        static uint8_t counter = 1;
        
        void add(void)
        {
           if (counter == 5) {
            counter = 7;
           } else if (counter == 20) {
            counter = 1;
           } else {
            counter++;
           }
        }
        

        如果您使用的现有接口add() 需要同时适用于全局变量和从函数传递的一些局部变量。 那么您现有的函数就可以了,您不需要返回任何内容,因为您是要修改和更新其内容的变量的地址。

        【讨论】:

        • 是的,虽然我使用的是全局变量,但我也希望能够将它与局部变量一起使用。我知道我可以简单地传递一个变量的值并返回一个递增的值,但使用指针似乎更有效。
        • 我确实认为这是一种可能性。这就是我添加最后一段的原因。在这种情况下,您的函数很好,并且适用于局部变量和全局变量。事实上,就函数add() 而言,对象的生命周期是无关紧要的——它只会更新你传递给它的任何东西。但是如果你碰巧有多个线程并且可能将counter 的地址传递给各种函数(或在多个线程中使用counter 的值),请注意数据竞争
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-05
        • 1970-01-01
        • 2021-06-03
        • 2019-01-17
        • 2019-03-29
        相关资源
        最近更新 更多