10

コードに次のようなものがあったため、仕事で大きな問題に遭遇しました。

    int foo = -1;
    NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
    if (foo > [bar count]){
        NSLog(@"Wow, that's messed up.");
    } else {
        NSLog(@"Rock on!");
    }

おそらく私がこれを投稿することですでに知っているように、出力は次のとおりです。

「うわー、それはめちゃくちゃです。」

私が収集したものから、目的 C は負の数を「符号付き」int に変換しているため、比較を殺しています。

これに関する他の投稿を見ましたが、それらはすべて問題が何であるかを述べていましたが、この比較を実際に機能させるための簡単な解決策を提案したものはありませんでした. また、深刻な問題を引き起こしているため、コンパイラの警告がないことにショックを受けました。

4

2 に答える 2

11

問題

あなたが経験している問題は、符号付き整数であり、符号なし整数foo-[NSArray count]返すため、符号なし整数fooへの暗黙的な型変換が行われていることです。詳細については、暗黙的な型変換を参照してください。また、C の型変換規則の詳細については、こちらを参照してください。

ソリューション

-[NSArray count]配列は負の数の要素を持つことができないため、符号なしの値を返します。可能な最小値は 0 です。配列のカウントを -1 と比較してもあまり意味がありません。カウントは常に負の数よりも大きくなります (符号の問題はありますが)。

したがって、ここでの正しい解決策、およびこの種の問題を回避する方法は、 の戻り値と一致する型-[NSArray count]、つまりNSUInteger( U はunsignedを表します) を使用することです。

于 2013-04-23T05:07:39.047 に答える
9

これを試して

- (IBAction)btnDoSomething:(id)sender {
        int foo = -1;
        NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
        if ( foo > (signed)[bar count] ) {
            NSLog(@"Wow, that's messed up.");
        } else {
            NSLog(@"Rock on!");
        }
    }

作業

2 つの異なる型の変数を比較している場合、両方の変数のデータ型をより上位の型に暗黙的に変換します。

この例では、
変数 foo はsigned int型で、配列 count はunsigned intであるため、foo のデータ型をunsigned int
に変換すると、 foo の値は配列 count 3 より小さい大きな数になります 。たとえば、配列カウントをsigned intにダウンキャストする必要があります。




問題

配列カウントが signed int の最大制限を超えると、キャスト後に [ -(負の) 最大制限 -> 0 -> + 最大制限] のように丸められますが、これは予期しない結果です。

解決

  • 配列の最大長がわからない場合は、型キャストを避けてください。
  • 制限が確実な場合は、キャストを実行します (配列の最大長は、signed intの最大制限を超えません)。

詳細については、
http://visualcplus.blogspot.in/2006/02/lesson-4-casting-data-types.htmlを確認してください。

于 2013-04-23T04:48:20.770 に答える