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

不。

首先,它不应该编译,至少在编译器符合标准的情况下是这样。|对于像and之类的按位运算符,指针不是有效的操作数&

其次,即使您的编译器允许您将指针视为整数,您也会面临平台不兼容的风险;有些 C 实现完全不能互换。您可能会假设任何这样的实现也必然是一致的,但假设很少是安全的......

第三,即使假设 ORing 两个指针一起工作,并得到你可以比较的东西NULL,你已经改变了测试的意义:(from|to)只有NULL两者都 fopen失败时才会如此;如果其中只有一个成功,则结果将非零并且您的代码将失败。

于 2012-06-29T04:00:52.297 回答
5

不。

根据标准,对于T *xT *y在 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,这是一个“假”值,该表达式的!from意思是“如果from是空指针,则为真,否则为假”。它读起来也很好:“如果不是来自,或者不是到,那么处理错误”

同样,人们编写代码喜欢if (from)检查指针是否为非 NULL。

PS 我知道很多人喜欢FILE*在声明指针时使用表达式,但我不喜欢这种形式,因为它是谎言。当您声明FILE *from这意味着“表达式*from具有类型FILE”。将*右边放在 the 之后是可行的,FILE但这使它看起来意味着“表达式from具有指向指针的类型FILE”。它没有,这里有一个例子:

FILE* from, to;

from类型为“pointer-to- FILE”。什么类型to?为什么它很旧FILE,而不是任何类型的指针。如果您在一行上声明这些,您需要使用的表达式是:

FILE *from, *to;

这意味着“表达式*from是 type FILE,而表达式*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 回答