【问题标题】:Cannot do a simple function using call by value method in C无法使用 C 中的按值调用方法执行简单函数
【发布时间】:2020-06-25 22:52:59
【问题描述】:

我正在尝试测试我最近学到的这种方法(按值调用),但由于我不知道的原因,代码不起作用,有人可以解释一下为什么吗? (顺便说一下乱七八糟的)

#include <stdio.h>
#include <stdlib.h>

void fact(int i);


int main() {
   int x;

   scanf("%d", x);
   //function called:

   fact(x);

   printf("value of x! = %d", x);

   return 0;
}


//factorial definition:
void fact(int i){
   int j=0;
   for(i=1; j>1; j--){
      i= i * j;
      return;
   }
}

【问题讨论】:

  • 您希望fact 做什么?你永远不会返回一个值,所以ij 的值在函数退出时会丢失。此外,您在fact 的循环的第一次迭代期间立即返回,我怀疑这是预期的行为。
  • 如果你的编译器让你摆脱了像scanf("%d", x); 这样明显的错误,你应该弄清楚如何启用它的警告和错误,以便它可以保护你。一个适当配置的编译器根本不会构建这样的代码。
  • 感谢您的回答。我想我应该返回 'i' 变量。
  • 您不能将 i 用作要相乘的值和 j 循环的限制。我建议您将另一个变量作为您正在计算的值并返回它,而不是 i。 (也可能值得考虑返回 long 而不是 int,因为阶乘会很快变大。)
  • user495758 要明确scanf("%d", x); 不是 错误。不编译将启用所有警告是错误。我们都会犯其他错误。

标签: c factorial pass-by-value unsigned-integer function-definition


【解决方案1】:

如果您使用按值调用函数来使用传递的参数进行计算,那么要在调用者中获取计算结果,该函数必须返回一个值。那就是它的返回类型不应该是void

函数fact的定义没有意义。在 for 循环中,参数 i 被重新分配给 1。循环本身永远不会迭代,因为另一个变量j 设置为0。所以它不能大于1

int j=0;
for(i=1; j>1; j--){

函数可以通过以下方式定义

//factorial definition:
unsigned long long int fact( unsigned int i )
{
    unsigned long long int f = 1;

    while ( i > 1 ) f *= i--;

    return f;
}

阶乘是为无符号自然整数定义的。

在 main 中你需要声明一个 unsigned int 类型的变量,比如

unsigned int x;

scanf的这个电话

scanf("%d", x);

不正确。函数需要通过引用来接受它的整数参数来改变它。

scanf( "%u", &x );

要获得函数fact 的结果,您必须再引入一个变量

unsigned long long int result = fact( x );

要输出它你应该写

printf( "value of %u! = %llu\n", x, result );

这是一个演示程序。

#include <stdio.h>

unsigned long long int fact( unsigned int );

int main(void) 
{
    unsigned int x;

    scanf( "%u", &x );

    unsigned long long int result = fact( x );

    printf( "value of %u! = %llu\n", x, result );

    return 0;
}

//factorial definition:
unsigned long long int fact( unsigned int i )
{
    unsigned long long int f = 1;

    while ( i > 1 ) f *= i--;

    return f;
}

如果输入数字20则函数输出为

value of 20! = 2432902008176640000

注意20unsigned long long int 类型的对象中可以存储其阶乘的最大数。

如果您希望函数通过引用接受其参数并在参数中返回结果,那么您必须将变量 x 声明为具有 unsigned long long int 类型。

这是一个演示程序。

#include <stdio.h>

void fact( unsigned long long int * );

int main(void) 
{
    unsigned long long int x;

    scanf( "%llu", &x );

    printf( "value of %llu! = ", x );
    fact( &x );
    printf( "%llu\n", x );

    return 0;
}

//factorial definition:
void fact( unsigned long long int *x )
{
    unsigned long long int f = 1;

    while ( *x > 1 ) f *= ( *x )--;

    *x = f;
}

如果输入20,那么程序输出将如上所示。

value of 20! = 2432902008176640000

【讨论】:

  • 非常感谢弗拉德!真正乐于助人的男人!
【解决方案2】:

问题一:

scanf("%d", x);

应该是:

scanf("%d", &x);

&amp; 很重要。


问题 2

在函数fact 中,您从j 开始0

int j=0;

您的循环仅在 j&gt;1: 时运行:

for(i=1; j>1; j--){

告诉我:0 曾经 &gt;1??
你的循环永远不会运行。


问题 3:

您希望调用fact(x); 会改变x 的值。
在 C 中,一个函数不能改变它的一个参数;参数是“按副本”传递的。

如果你想改变调用者中的一个对象(变量),你必须传递一个指针给它:

void fact(int* i);

[...]
//function called:
fact(&x);
[...]


//factorial definition:
void fact(int* i){
   int j=0;
   for(*i=1; j>1; j--){
      *i= *i * j;
      return;
   }
}

【讨论】:

  • 因为scanf()是按值调用的,在问题标题中:)
  • 问题3返回在for循环内
  • 嗯,建议将return移出循环。
  • 关于问题2,我试图初始化变量,因为它是本地变量,不认为它会产生问题..
  • @Simson:这不是真正的问题,因为你一开始就不会进入循环(参见问题 2)
【解决方案3】:

Scanf 接受一个指向变量的指针,要从 void 函数返回某些内容,您必须使用指向返回变量的指针而不是其值通过引用来调用它。

【讨论】:

  • 谢谢西蒙!我将使用参考方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 2021-10-07
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
相关资源
最近更新 更多