指针算术

Col*_*son 2 c null pointers null-pointer

我还在学习指针.我知道如何切换if语句等.在我正在使用的书中,我得到了这个例子:

    FILE* from = fopen("in.txt", "r");
    FILE* to = fopen("out.txt", "w");
    if (from != NULL && to != NULL)
    {
        ...
    }
    else
    {
        printf("failed to open files!\n");
    }
} /* end of function */
Run Code Online (Sandbox Code Playgroud)

我知道可以改成这个:

    FILE* from = fopen("in.txt", "r");
    FILE* to = fopen("out.txt", "w");
    if (from == NULL || to == NULL)
    {
        printf("failed to open files!\n");
        return;
    }
    ...
} /* end of function */
Run Code Online (Sandbox Code Playgroud)

现在,我的问题(如果它将编译)是,如果这是安全的或实现定义为NULL几乎每个编译器都不同.

    FILE* from = fopen("in.txt", "r");
    FILE* to = fopen("out.txt", "w");
    if ((from & to) == NULL)
    {
        printf("failed to open files!\n");
        return;
    }
    ...
} /* end of function */
Run Code Online (Sandbox Code Playgroud)

Mar*_*eed 6

没有.

首先,它不应该编译,至少在编译器符合标准的情况下不会编译.对于像|和等的按位运算符,指针不是有效的操作数&.

其次,即使您的编译器允许您将指针视为整数,也存在平台不兼容的风险; 有C实现,它们根本不可互换.您可能认为任何此类实现都必然符合要求,但假设很少是安全的......

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

  • @Cole - 使用“&”更糟糕,因为它测试这些值是否有任何共同点。结果接近随机。 (2认同)

Die*_*Epp 5

没有.

根据标准,对于T *xT *y在C中,表达x|y是没有意义的.它不应该编译.从n1256§6.5.122"按位包含OR运算符":

每个操作数应具有整数类型.

这意味着这 x|y是一个错误,故事的结尾.这同样适用于所有其他按位运算符:& | ^ ~ << >>只能在整数上使用(注意"整数"包括字符和bool).

但是,如果您想节省工作量,那么在指针上使用逻辑运算符是完全有效的.

// 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) ...
Run Code Online (Sandbox Code Playgroud)

无论您认为x == NULL更好还是!x更好,都取决于您.你最好能够同时阅读这两种风格,因为这两种风格都很常见.