2

ポインターについて学習しています。このコードを考えると:

FILE* from = fopen("in.txt", "r");
FILE* to = fopen("out.txt", "w");
if (from == NULL || to == NULL)
{
    printf("failed to open files!\n");
    return;
}

if条件をこの有効な (定義された) 動作に変更していますか?

FILE* from = fopen("in.txt", "r");
FILE* to = fopen("out.txt", "w");
if ((from | to) == NULL)
{
    printf("failed to open files!\n");
    return;
}
4

5 に答える 5

6

いいえ。

まず、少なくともコンパイラが標準に準拠している場合は、コンパイルすべきではありません。|ポインターは、 や などのビット演算子の有効なオペランドではありません&

第 2 に、たとえコンパイラがポインタを整数として扱うことを許可していたとしても、プラットフォームの非互換性を危険にさらすことになります。まったく交換できない C 実装があります。そのような実装も必ず準拠していると仮定するかもしれませんが、仮定が安全であることはめったにありません...

第 3 に、2 つのポインターの OR が機能し、 と比較できる何かが得られると仮定しても、テストNULLの意味が変わり(from|to)ます。そのうちの 1 つだけが成功した場合、結果はゼロ以外になり、コードは失敗します。NULL fopen

于 2012-06-29T04:00:52.297 に答える
5

いいえ。

For T *xand T *yin C では、x|y標準によると、式は無意味です。コンパイルしないでください。n1256 §6.5.12 ¶2「ビット単位の包括的 OR 演算子」から:

各オペランドは整数型でなければなりません。

これ x|yは、エラー、話の終わりであることを意味します。同じことが他のすべてのビット演算子にも当てはまります。& | ^ ~ << >>すべて整数でのみ使用できます (「整数」には文字とブール値が含まれることに注意してください)。

ただし、入力の手間を省きたい場合は、ポインターで論理演算子を使用することは完全に有効です。

// x == NULL is exactly semantically equivalent to !x
// These two are exactly the same
if (x == NULL || y == NULL) ...
if (!x || !y) ...

// In a logical expression, x != NULL is exactly semantically equivalent to x
// These two are exactly the same
if (x != NULL && y != NULL) ...
if (x && y) ...

x == NULL良いと思うか、良いと思うかはあなた次第です!x。両方のスタイルが共通しているため、両方を読めるようにした方がよいでしょう。

于 2012-06-29T04:06:59.970 に答える
2

ビット単位の演算子とポインターを使用してゲームをプレイしようとしないでください。

より簡潔な式の書き方を探しているだけなら、これは非常に一般的で慣用的な方法です。

    FILE* from = fopen("in.txt", "r");
    FILE* to = fopen("out.txt", "w");
    if (!from || !to) // note the use of the ! operator
    {
        printf("failed to open files!\n");
        return;
    }
    ...
} /* end of function */

!演算子は論理 NOT 演算子です。ヌル ポインターの値は常に 0 であり、これは "false" 値であるため、この式!fromは "がヌル ポインターの場合は true from、それ以外の場合は false` を意味します。"if not from, or not to, thenエラーを処理する」

同様に、if (from)ポインターが NULL でないかどうかをチェックするようなコードを書く人もいます。

PS ポインターを宣言するときのような式を使用するのが好きな人が多いことは知っていFILE*ますが、この形式は嘘なので嫌いです。これを宣言FILE *fromすると、「式*fromには型があります」という意味になりますFILE*の後に右を置くと機能しFILEますが、これは「式のfrom型がポインタへの型を持つ」ことを意味するように見えますFILE。そうではありません。例を次に示します。

FILE* from, to;

fromタイプは「pointer-to- FILE」です。は何型toですか?なぜそれは普通の古いものFILEであり、どんな種類のポインターでもありません。これらを 1 行で宣言する場合、使用する必要がある式は次のとおりです。

FILE *from, *to;

これは、「式*fromは typeFILEであり、式*toはtype である」ことを意味しFILEます。慣れるとこんな感じです。

あなたはこれを書くことができますが、それは厄介です。

FILE* from, *to;

うん!

于 2012-06-29T05:12:14.707 に答える
0

fromおよびtoはポインターであるため、それらに対してビット単位の操作を行うことはできません。ただし、これ<stdint.h>intptr_t整数型であり、ポインターを保持することが保証されているため、ポインターを最初にそれらにキャストすることは有効です。ただし、これは醜いので、より読みやすいバージョンに固執します。

于 2012-06-29T04:08:17.450 に答える
0

ポインターでは、ビット単位の操作は許可されていません。

そのような運動は避けるべきです。

于 2012-06-29T07:49:36.257 に答える