1

getFieldSignExtended(int,int,int)中,我在if-else语句中有if-else语句。我将int结果作为此函数的全局变量。根据程序控制流向的位置,我希望此函数返回result2.

起初我在这个函数的底部有一个 return 语句,它不起作用,我发现范围 inC不像 in Java。因此,我return 1;位于函数的底部,并且块return result2中有 8 条语句if-else

有没有更好的方法来组织这个功能?我不想嵌套if-else块,我想要尽可能少的return语句。

这是家庭作业,但它已经评分,我只是更正一些出现的错误。

getFieldSignExtended(int,int,int)从值从 hi 到 lo (包括 hi 和 lo 可以是 == 等)获取一个位域并对其进行符号扩展(基于测试符号位)。所有这些代码都处理 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;
}
4

6 回答 6

2

resultresult2不是“函数的全局变量”,它们是局部变量。问题不在于“C 中的范围与 Java 中的不同”,而是函数中的某些分支无法分配result2。具体来说,分支中没有分配

printf(" result2 %08x \n",result2);

如果您在 Java 中声明了一个没有值的变量,编译器会在赋值之前查找使用该变量的代码路径,如果有就会提醒您;在 C 语言中,您必须自己注意这些情况。

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

于 2012-09-11T12:08:00.863 回答
1

您不需要多个return语句,而不是您的函数目前有效。只需初始化result2并在函数结束时执行1return result2;

或者不是分配给result2然后直接返回,为什么不只是做例如return value;return maskMinus | result;等等。

于 2012-09-11T12:06:15.987 回答
1

一般的答案是留出一个变量来存储您的返回值(例如,ret_val)并将您的返回值分配给您当前正在return输入值的位置。您可能还必须调整您的控制流,因为现在您没有在这些位置退出具有值的函数。

然后,在函数的“底部”,您可以返回一次,其值为ret_val. IE,

 return ret_val;

对于上述更改,一次就足够了。

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

于 2012-09-11T12:09:19.347 回答
0

只看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

然后在您return result2;删除该行的每个地方,最后而不是return 1;仅仅return result2;

现在您只有一个用于此函数的 return 语句。

于 2012-09-11T12:19:04.513 回答
0

您可以使用 goto 语句,并且可以在单点返回 result2 值。如果在这里很好地解释

于 2012-09-11T12:09:48.553 回答
0

抱歉阅读过多,我已经很久没有在 c 中做任何事情了,但是你可以创建交换 lo 和 hi 的小函数,并将 hi 设置为更大的值,并将 lo 设置为更低,那么你就不需要这么多块了基本上做同样的事情

于 2012-09-11T12:10:37.370 回答