0

i+1次の番号が現在の番号と同じかどうかを確認するために使用しても安全かどうかを自問しています...例:

int search(int el, int* a, int n) {

if(a == NULL && n<0)
{
    return NULL;
}

for(int i=0; i<n; i++)
{
    if((a[i] == el )&& (a[i+1] != el)) // here I check next element
    {
        return i; // if I find it, return a position.
    }
}

return -1; // else return -1
}

length の配列がある場合、配列の4a[i+1]さが渡されますが、プログラムは引き続き機能します。

4

5 に答える 5

1

いいえ、範囲外の要素にアクセスすることはUndefined Behaviorです。

あなたのプログラムは「動いているように見える」かもしれませんが、何も期待することはできません。あなたのマシンで動作し、別のマシンでクラッシュする可能性があります。または、今はすべてのマシンで動作する可能性がありますが、明日は動作しません. 添え字演算子を使用する前に、インデックスが範囲外かどうかを確認する必要があります。

範囲外の要素にアクセスしないように、サイクルを変更することを検討してください。

for (int i = 0; i < n - 1; i++)
//                  ^^^^^

次に、特殊なケースとして、配列の最後の要素を個別に処理する必要があります。

于 2013-03-17T14:38:16.473 に答える
0

それは正しくありませんi。最後の値 ( ) に到達するn-1と、存在しない要素の値をチェックします (C 標準では、最後の要素の 1 つ前の要素へのポインターを使用できますが、逆参照することはできません)。

次のようにコードを修正できます。

 if((a[i] == el ) && ((i == n-1) || (a[i+1] != el)))
于 2013-03-17T14:39:26.273 に答える
0

いいえ。

int main(void)
{
    char pumpkin[8];
    int a[4];
    int i, p;

    a[0] = 3760;
    a[1] = 100001;
    a[2] = 595959;
    a[3] = 1886221680;

    pumpkin[0] = 'p';
    pumpkin[1] = 'u';
    pumpkin[2] = 'm';
    pumpkin[3] = 'p';

    for (i = 0; i < 4; i++) {
        p = search(a[i], a, 4);

        if (p >= 0)
            printf("Found it at position %d: %d.\n", p, a[i]);
        else
            printf("Value not found.\n");
    }


    return 0;
}

私のマシンでは:

$ gcc -std=c11 -o boundserror boundserror.c
$ ./boundserror 
Found it at position 0: 3760.
Found it at position 1: 100001.
Found it at position 2: 595959.
Value not found.

どうしたの ?コンパイラは、a[3] と、a[4] が存在する場合にある場所の両方に、値 1886221680 を書き込みました。あなたのマシンで動作するプログラムについて: 私のマシンのコンセプトでの動作について読んでください。

http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html

于 2013-03-17T15:10:09.757 に答える
0

nが配列の最後の要素である場合i + 1、この場合は安全です。nが配列内の要素の数である場合i + 1、ほとんどの場合は機能しているように見えますが、安全ではありません

その場合、配列の境界外の要素にアクセスしているため、誤った結果が得られたり、プログラムがクラッシュしたりする可能性があります。ただし、ほとんどの場合は機能しているように見えるため、問題が発生した場合のデバッグが非常に困難になります。

于 2013-03-17T14:40:16.697 に答える
0

あなたが何を求めているのか私にははっきりしません。配列へのアクセスは高価ですが、 と の両方へのアクセスはa[i]O a[i+1](N) の複雑さのままです。できないことは、に基づく複雑さを追加することi(たとえば、0 から への追加のループi)、または変更i(たとえば、いくつかの条件に基づいて減少させること) です。

他の人がすでに指摘しているように、問題は、最後の要素が存在しないデータと比較されることです。エラーが発生してクラッシュする可能性があるか、プログラムが動作しているように見えて、ほとんどの場合実際に動作します。 - その未知の、おそらくランダムな最後と 1 つの項目が比較をトリガーし、予期しない結果をもたらす時まで。

配列のサイズが少なくとも 1 であることを確認し (これは特殊なケースで、単一の要素に対して比較を実行することはできません!)、 までループする必要がありn-1ます。または、以前の値を一時変数に保存することもできます。プラットフォームに応じて、これは (おそらくはるかに高速な) レジスターまたは (おそらくはるかに低速な) スタックの場所になります。ほとんどの場合、あなたが行ったように、次の要素と比較するという私の意図を述べ、コンパイラーにそれを整理させます。

于 2013-03-17T14:46:57.307 に答える