在if语句中分配fopen的结果

时间:2012-04-29 21:12:39

标签: c if-statement variable-assignment

我目前正在学习C,并想知道以下两段代码是否表现不同,或者它是否只是一种风格。

查看一些来源,他们有以下代码:

...
FILE * pFile;
pFile = fopen ("myfile.txt","r");
if (pFile == NULL)
{ some code }
...

虽然我的教授在他的笔记中有以下代码:

...
FILE * pFile
if ((pFile = fopen("myfile.txt","r")) == NULL)
{ some code }
...

只是想知道这是否只是不同程序员的风格偏好,或者将返回/设置行放在if statmeent中是否有优势。

7 个答案:

答案 0 :(得分:5)

没有区别。更有经验的程序员有时会使用第二种形式,只是为了保存一行,但它们基本相同。第二个往往是更多的“UNIX-y”,其中大多数函数调用在继续之前检查错误(而不是成功)。

答案 1 :(得分:1)

它们是相同的,因为(pFile = fopen("myfile.txt", "r"))返回pFile,但我个人更喜欢第一个,因为它更明确。

答案 2 :(得分:1)

这两种变体是相同的。它不会影响性能。但是,我认为第一个变体更好,因为它使事情更加清晰。

答案 3 :(得分:1)

两个程序都是等效的。

有些人喜欢第一种风格,说它更具可读性,有些人喜欢第二种风格,说它更紧凑。

有关信息,请注意在某些编码指南(MISRA为1)中,禁止使用第二种格式。 MISRA禁止在if语句的控制表达式中使用赋值运算符。

答案 4 :(得分:0)

性能没有差别,但第二种显然更可取。

第一个分开尝试打开文件,以便测试是否成功打开文件。

第二个打开文件并测试单个操作是否成功,这正是你不仅应该如何编码它,还应该如何考虑它。您根本不应将它们视为两个单独的操作。除非您检查是否正确打开文件,否则打开文件的操作不会完成。

将开放和测试视为两个单独的操作是懒惰编码,导致草率思维。不要这样做。

答案 5 :(得分:0)

如上所述,两个部分明显相同。然而,我更喜欢第一个,因为它倾向于避免赋值运算符=和相等运算符==之间的混淆。考虑一种情况,其中有一个函数 foo(arg)返回一个int。你会写一些类似的东西:

int y;

if ((y = foo(x)) == 0) {
    ... some code ...
}

现在,假设您将赋值运算符与相等混淆(在if表达式BTW中非常常见):

int y;

if ((y == foo(x)) == 0) {
    ... some code ...
}

由于表达式(y == foo(x))的类型是int,因此编译器将上述内容视为合法的C代码。这显然会在您的代码中产生错误。

现在,让我们考虑第一个选项:

int y;

y = foo(x);
if (y == 0) {
    ... some code ...
}

显然,现在你不太可能将作业与平等混淆。此外,即使您将 y == foo(x); 写为语句,编译器也会发出警告。

答案 6 :(得分:0)

虽然现有的答案非常好,但我还有一些关于如何解决C中的某些内容是否是性能问题的问题。

首先,快速检查方法是使用gcc -O3编译两个版本的代码,并比较生成的.o文件。如果它们是相同的,那么当然不会有任何性能差异(至少不会与您正在使用的当前编译器/版本不同)。

话虽如此,问题的一个更概念性的方法是问自己2个问题:

  1. 这两段代码是否为所有可能的有效输入变量值定义了完全相同的行为,或者只为您期望的输入定义了相同的行为(甚至只是类似的行为)?

  2. 如果他们定义了完全相同的行为,您认为编译器很容易看到这个吗?

  3. 如果是这样,那么“不应该”是性能差异,因为编译器“应该”将它们编译为它认为是实现所描述的行为的最有效方式。当然有时编译器可能非常愚蠢,所以如果真的很重要,你可能需要检查。

    在您的情况下,两个版本的代码都定义了完全相同的行为,我认为您很难找到以不同方式编译它们的编译器,除非完全禁用优化。