有没有比使用多个返回语句更好的方法在c中返回值?

有没有比使用多个返回语句更好的方法在c中返回值?,c,C,在getFieldSignExtendedint,int,int中,if-else语句中包含if-else语句。我将int result作为这个函数的全局变量。根据程序控制的流向,我希望此函数返回result2 起初,我在这个函数的底部有一个return语句,它不起作用,我发现C中的作用域与Java中的不同。因此我返回1;在函数的底部,在if-else块中有8条return-result2语句 是否有更好的方式组织此功能?我不想嵌套if-else块,我希望返回语句尽可能少 这是家庭作业,但已经评

在getFieldSignExtendedint,int,int中,if-else语句中包含if-else语句。我将int result作为这个函数的全局变量。根据程序控制的流向,我希望此函数返回result2

起初,我在这个函数的底部有一个return语句,它不起作用,我发现C中的作用域与Java中的不同。因此我返回1;在函数的底部,在if-else块中有8条return-result2语句

是否有更好的方式组织此功能?我不想嵌套if-else块,我希望返回语句尽可能少

这是家庭作业,但已经评分了,我只是在纠正一些出现的错误

getFieldSignExtendedint,int,int从hi到lo(包括hi和lo)的值中获取一个位字段,hi和lo可以是==到彼此,等等。sign基于测试符号位对其进行扩展。所有这些代码都处理2的补码

如果您发现任何其他重大的C约定错误,我将很高兴纠正它们

提前谢谢

int getFieldSignExtended (int value, int hi, int lo) {
    unsigned int result = 0;
    int result2 = 0;
    unsigned int mask1 = 0xffffffff;
    int numberOfOnes = 0;

    if((hi == 31) && (lo == 0)) {
            result2 = value;
            return result2;
    }

    if((lo == 31) && (hi == 0)) {
            result2 = value;
            return result2;
    }
    else if(hi < lo) {
        // Compute size of mask (number of ones).
        numberOfOnes = lo-hi+1;
        mask1 = mask1 << (32-numberOfOnes);
        mask1 = mask1 >> (32-numberOfOnes);
        mask1 = mask1 << hi;
        result = value & mask1;
        result = result >> hi;
        if(result & (0x1 << (numberOfOnes-1))){
            // if negative
            int maskMinus = (0x1 << numberOfOnes);
            maskMinus = maskMinus -1;
            maskMinus = ~maskMinus;     
            result2 = maskMinus | result;
        }
    } else if(lo < hi) {
        // The number of ones are at the 'far right' side of a 32 bit number.
        numberOfOnes = hi-lo+1;
        mask1 = mask1 >> (32-numberOfOnes);
        mask1 = mask1 << lo;
        result = value & mask1;
        result = result >> lo;
        if(result & (0x1 << (numberOfOnes-1))){
            //if negative
            int maskMinus = (0x1 << numberOfOnes);
            maskMinus = maskMinus -1;
            maskMinus = ~maskMinus;     
            result2 = maskMinus | result;
            return result2;
        }
    }else{
        // hi == lo
        unsigned int mask2 = 0x1;

        // Move mask2 left.
        mask2 = mask2 << hi;
        result = mask2 & value;
        result = result >> hi;
        if(result == 0x1){
            result2 = 0xffffffff;
            return result2;
        }
        else{
            result2 = 0x0;
            return result2;
        }   
    }   

    return 1;
}

您不需要多个return语句,因为您的函数目前正在工作。只需将result2初始化为1,并返回result2;在函数的末尾


或者,与其分配给result2,然后直接返回,为什么不直接执行例如返回值;或返回maskMinus |结果;等等。

您不需要多个返回语句,因为您的函数目前正在工作。只需将result2初始化为1,并返回result2;在函数的末尾

或者,与其分配给result2,然后直接返回,为什么不直接执行例如返回值;或返回maskMinus |结果;等等。

结果和结果2不是函数的全局变量,而是局部变量。问题不在于C中的作用域与Java中的作用域不同,而是函数中的某些分支无法分配result2。具体而言,分支机构中没有指定

printf(" result2 %08x \n",result2);
如果您在Java中声明了一个没有值的变量,编译器会在赋值之前查找使用该变量的代码路径,如果存在,则会发出警告;在C语言中,你必须自己注意这些情况

如果将return result2放在底部,并确保所有代码路径都为result2分配了正确的值,那么代码将使用单个return语句,就像setField一样。

result和result2不是函数的全局变量,而是局部变量。问题不在于C中的作用域与Java中的作用域不同,而是函数中的某些分支无法分配result2。具体而言,分支机构中没有指定

printf(" result2 %08x \n",result2);
如果您在Java中声明了一个没有值的变量,编译器会在赋值之前查找使用该变量的代码路径,如果存在,则会发出警告;在C语言中,你必须自己注意这些情况


如果将return result2放在底部,并确保所有代码路径都为result2分配了正确的值,那么代码将使用单个return语句,就像设置字段一样。

一般的答案是留出一个变量来存储返回值,例如。,返回值,并在当前返回值的位置为其指定返回值。您可能还必须调整控制流,因为现在您没有在这些位置使用值退出函数

然后,在函数的底部可以返回一次ret_val的值,即

一次就足够了


查看您的算法并重新排列您的代码,也许将部分工作委托给函数可能是另一种帮助简化/澄清代码的方法,从而消除了多次或过多判断调用返回的需要。

一般的答案是留出一个变量来存储返回值,例如。,返回值,并在当前返回值的位置为其指定返回值。您可能还必须调整控制流,因为现在您没有在这些位置使用值退出函数

然后,在函数的底部可以返回一次ret_val的值,即

一次就足够了


查看您的算法并重新排列您的代码,也许将部分工作委托给函数可能是另一种帮助简化/澄清代码的方法,从而消除了对多次或过多判断调用返回的需要。

您可以使用goto语句,在单点上可以返回result2值。如果解释得很好

您可以使用goto语句,并且在单点上可以返回result2值。如果解释得很好,很抱歉读了太多,我很久没有用c做任何事情了,但是你可以创建一个小函数,将lo和hi交换,将hi设置为较大的值,将lo设置为较低的值, 那么你会
我不需要这么多的块,它们基本上都在做相同的事情

对不起,阅读太多了,我很久没有用c做任何事情了,但是你可以创建一个小函数,交换lo和hi,并将hi设置为更大的值,lo设置为更低的值, 那么你就不需要那么多的块了,它们基本上都在做同样的事情,只要看看getFieldSignExtended函数,问题就很简单了。你现在只有两个地方可以返回。。。让我们稍微简化一下,让你明白我的意思:

if (A)
  do something
if (B)
  do the same thing
else if (C)
  do something else
else if (D)
  do something else
else
  do something else 
所以你真正需要做的就是把A和B结合起来,通过这样做,你的函数中只有一个流,它不能下降到if和else if,只有其中一个。因此,如果您这样做:

if(((hi == 31) && (lo == 0)) || ((lo == 31) && (hi == 0))){
    result2 = value;
}else if(hi < lo){  
...
// the rest as is
然后在每个地方返回结果2;只需删除该行,并在结尾处,而不是返回1;只返回结果2

现在这个函数只有一个return语句。

看看getFieldSignExtended函数,我认为问题很简单。你现在只有两个地方可以返回。。。让我们稍微简化一下,让你明白我的意思:

if (A)
  do something
if (B)
  do the same thing
else if (C)
  do something else
else if (D)
  do something else
else
  do something else 
所以你真正需要做的就是把A和B结合起来,通过这样做,你的函数中只有一个流,它不能下降到if和else if,只有其中一个。因此,如果您这样做:

if(((hi == 31) && (lo == 0)) || ((lo == 31) && (hi == 0))){
    result2 = value;
}else if(hi < lo){  
...
// the rest as is
然后在每个地方返回结果2;只需删除该行,并在结尾处,而不是返回1;只返回结果2



现在这个函数只有一个返回语句。

每个函数一个返回语句的概念可以追溯到结构化编程的概念。这个概念是关于有一个退出的例行程序。看:人们仍然在争论这个话题。就我个人而言,我倾向于认为它在今天的意义不大。看:哦,天哪,你的函数太长了!将它们切割成更小的功能部件。你在开始时还用了一个拼写错误;而不是{.@jsobo:我已经通读了这篇文章,但是每个函数只有一个返回没有任何好处。我想知道在过去,这个原则背后的原因是什么?值得注意的是,有多少人愿意查看这样的代码!为什么不只发布getFieldSignExtended函数,至少删除所有调试printf cruft?你自己也仔细看过代码了吗?表达式lo==31&&hi==0在if子句中使用完全相同的语句进行了两次测试。numberOfOnes变量在函数中的不同位置被初始化为完全相同的值。这些只是一些你可以轻松修复的示例,让其他用户关注您真正的问题,而不必首先清理。每个函数一个返回语句的概念可以追溯到结构化编程的概念。这个概念是关于一个例程的一个出口。请看:人们仍在争论这个话题。我个人倾向于认为它在今天不那么重要。请看:哦,我的天,你的乐趣动作太长了!把它们减少到更小的功能部分。而且你在开始时用;而不是{.@jsobo:我已经通读了这篇文章,但是每个函数只有一个返回没有任何好处。我想知道在过去,这个原则背后的原因是什么?值得注意的是,有多少人愿意查看这样的代码!为什么不只发布getFieldSignExtended函数,至少删除所有调试printf cruft?你自己也仔细看过代码了吗?表达式lo==31&&hi==0在if子句中使用完全相同的语句进行了两次测试。numberOfOnes变量在函数中的不同位置被初始化为完全相同的值。这些只是一些你可以轻松修复的示例,让其他用户关注您真正的问题,而不必首先清理。如果您可能使用未初始化的变量,任何像样的C编译器也会给您一个警告。@Shahbaz这是真的,但在Java中这是一个错误,而不是警告。如果您可能使用未初始化的变量,任何像样的C编译器也会给您一个警告。@Shahbaz这是真的,但在Java中,这是一个错误,而不是警告。当然,goto语句通常是不受欢迎的,尤其是在学术用途中。@Eregrith这不是无条件的不,但在家庭作业的上下文中,它肯定是:我还没有遇到一位教授,他会在学生的家庭作业中看到八个goto,却什么也不说:嗯,如果教授禁止的话,这一定是有原因的。我个人觉得它们对于代码读取来说很糟糕,因为流不是真正可读的,但是从编程的角度来说,它们没有什么问题。在C语言中,goto一直用于错误处理。这是唯一明智的方法。goto是一个危险的工具,同意,但它也非常有用。电锯也是危险的在力学基础课程中,没有教授允许他的学生使用电锯,但这并不意味着任何地方都不应该使用电锯。当然,goto语句通常是不受欢迎的,尤其是
特别是在学术用途上。@Eregrith这不是无条件的不,但在家庭作业的背景下,它肯定是:我还没有遇到一位教授,他会在学生的家庭作业中看到八个goto,却什么也不说:嗯,如果教授们禁止,那一定有原因。就我个人而言,我觉得它们对于代码读取来说很糟糕,因为流不是真正可读的,但是从编程的角度来说,它们并没有什么问题。在C语言中,goto一直用于错误处理。这是唯一明智的方法。goto是一个危险的工具,大家都同意,但它也非常有用。电锯也是危险的,没有一位教授允许他的学生在力学基础课程上使用电锯,但这并不意味着任何地方都不应该使用电锯。我最终没有按照你的建议完全交换hi和lo,而是再次调用getFieldSignExtended,递归地使用hi和lo切换。现在一切正常。我没有完全按照您的建议交换hi和lo,而是再次调用getFieldSignExtended,递归地切换hi和lo。现在一切都好了。