1

getFieldSignExtended(int,int,int)if-elseステートメント内にif-elseステートメントがあります。intこの関数のグローバル変数として結果があります。プログラム制御が流れる場所に応じて、この関数がを返すようにしresult2ます。

C最初は、この関数の下部に1つのreturnステートメントがありましたが、それは機能しませんでしたが、のスコープはののようではないことがわかりましたJava。したがってreturn 1;、私は関数の下部にあり、ブロックreturn result2内に8つのステートメントがあります。if-else

この機能を整理するためのより良い方法はありますか?if-elseブロックをネストしたくないので、returnステートメントをできるだけ少なくしたいと思います。

これは宿題ですが、すでに採点されており、発生したいくつかのエラーを修正しています。

getFieldSignExtended(int,int,int)値から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;
}
4

6 に答える 6

2

およびは「関数のグローバル変数」ではなく、ローカル変数ですresultresult2問題は、「CのスコープはJavaのスコープとは異なる」ということではなく、関数の一部のブランチが割り当てに失敗することresult2です。具体的には、ブランチには割り当てがありません。

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

Javaで値のない変数を宣言すると、コンパイラは割り当ての前にこの変数を使用するコードパスを探し、存在する場合は警告します。Cでは、これらの状況を自分で監視する必要があります。

一番下に配置return result2し、すべてのコードパスにresult2正しい値が割り当てられていることを確認すると、コードは1つのreturnステートメントで機能しますsetField

于 2012-09-11T12:08:00.863 に答える
1

return関数が現在機能しているので、複数のステートメントは必要ありません。関数の最後に初期化result21て実行するだけです。return result2;

または、割り当ててから直接戻る代わりに、 egやなどresult2を実行してみませんか。return value;return maskMinus | result;

于 2012-09-11T12:06:15.987 に答える
1

一般的な答えは、戻り値(たとえばret_val)を格納する変数を確保し、現在値を設定している場所に戻り値を割り当てることreturnです。これらの場所で値を使用して関数を終了していないため、制御フローを調整する必要がある場合もあります。

次に、関数の「下部」で、値を1回ret_val返すことができます。つまり、

 return ret_val;

上記の変更で1回で十分です。

アルゴリズムを調べてコードを再配置する場合、作業の一部を関数に委任することは、コードを単純化/明確化して、複数の(または過度の判断呼び出し)リターンの必要性を排除するのに役立つ別のアプローチかもしれません。

于 2012-09-11T12:09:19.347 に答える
0

gotoステートメントを使用でき、単一のポイントでresult2値を返すことができます。ここでうまく説明されれば

于 2012-09-11T12:09:48.553 に答える
0

読みすぎて申し訳ありませんが、私は何年もの間cで何もしませんでしたが、loとhiを入れ替える小さな関数を作成し、hiを大きい値に設定し、loを小さい値に設定すると、それほど多くのブロックは必要ありません。基本的に同じことをする

于 2012-09-11T12:10:37.370 に答える
0

関数を見るだけで、getFieldSignExtended私が見ている問題は非常に単純です。今すぐ戻ることができる場所は2つだけです...少し簡略化して、私が何を意味するかを示しましょう。

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を組み合わせるだけです。これにより、関数内のフローは1つだけになり、「if」と「elseif」のどちらか一方だけを下げることはできません。したがって、これを行う場合:

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ステートメントが1つだけ作成されました。

于 2012-09-11T12:19:04.513 に答える