我还在学习指针。我知道如何切换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 */
我知道可以改为:
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 */
现在,我的问题(如果它将编译)是,如果这是安全的,或者实际定义为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 */
答案 0 :(得分:6)
没有
首先,它不应该编译,至少在编译器符合标准时不应该编译。指针不是|
和&
等按位运算符的有效操作数。
其次,即使您的编译器允许您将指针视为整数,也存在平台不兼容的风险;有C实现,它们根本不可互换。您可能认为任何此类实现都必须符合要求,但假设很少是安全的......
第三,即使假设ORing两个指针在一起工作,并为你提供一些可以与NULL
进行比较的东西,你已经改变了测试的意义:(from|to)
只会{{1}如果两个 NULL
都失败了;如果只有其中一个成功,结果将是非零的,您的代码将失败。
答案 1 :(得分:5)
没有
对于C中的T *x
和T *y
,根据标准,表达式x|y
毫无意义。它不应该编译。从n1256§6.5.12¶2“按位包含OR运算符”:
每个操作数都应具有整数类型。
这表示 x|y
是错误,故事的结尾。这同样适用于所有其他按位运算符:&
|
^
~
<<
>>
全部仅可用整数(注意“整数”包括字符和bools)。
但是,如果您想节省工作量,那么在指针上使用逻辑运算符是完全有效的。
// 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
更好,取决于您。你最好能够同时阅读这两种风格,因为这两种风格都很常见。
答案 2 :(得分:1)
不要尝试使用按位运算符和指针来玩游戏。
如果您只是想要一种更简洁的方式来编写表达式,这是一种非常常见和惯用的方法:
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
是空指针,则为true,否则为false。”它也读得很好: “如果不是来自或不来,则处理错误”
同样,人们编写类似if (from)
的代码来检查指针是否为非NULL。
P.S。我知道很多人喜欢在声明指针时使用像FILE*
这样的表达式,但我不喜欢这种形式,因为它是一个谎言。当您声明FILE *from
时,这意味着“表达式*from
具有类型FILE
”。它可以将*
放在FILE
之后,但这使得它看起来像“表达式from
具有类型指针 - FILE
”。它没有,这是一个例子:
FILE* from, to;
from
的类型为“指向 - FILE
”。什么类型to
?为什么它是普通的FILE
,而不是任何类型的指针。如果要在一行中声明这些表达式,则需要使用的表达式为:
FILE *from, *to;
这意味着“表达式*from
的类型为FILE
,而表达式*to
的类型为FILE
。”一旦你习惯了,它看起来就好了。
你可以写这个,但它很吵。
FILE* from, *to;
呸!
答案 3 :(得分:0)
from
和to
是指针,你不能对它们进行任何按位操作。但是,<stdint.h>
提供intptr_t
,它是整数类型并且保证保持指针,因此首先将指针转换为它们是有效的。但是,这很难看,所以我会坚持使用更易阅读的版本。
答案 4 :(得分:0)
指针上不允许按位操作。
你应该避免这种运动。