我刚刚编写了一个示例代码来试用它。令人惊讶的是,我没有得到任何编译失败。根据C,我们应该声明,然后初始化或使用。请解释一下。
#include <stdio.h>
int main(void) {
int a = a = 1; //Why it compiles??
printf("%d",a);
return 0;
}
上面的代码编译成功并输出1.请解释并提供标准的任何输入,允许这样做。
答案 0 :(得分:3)
定义
<ion-content class="cards-bg">
<ion-list>
<ion-item *ngFor="let item of (items | async)?.slice().reverse()" text-wrap>
<ion-card *ngIf="item.type === 1" tappable (click)="navigate(item.id)" class="cards-bg">
<img src="assets/imgs/chpt2017.jpeg"/>
<ion-card-content>
<ion-card-title>
{{item.titre}}
</ion-card-title>
<p>
{{item.titre2}}
</p>
</ion-card-content>
</ion-card>
<ion-card *ngIf="item.type === 2" class="cards-bg">
<ion-card-content>
<ion-card-title>
{{item.titre}}
</ion-card-title>
</ion-card-content>
<div class='applet'>
[Event "Nationale Clubcompetitie KNDB 2013/2014"]
[Site ""]
[White "Quentin"]
[Black "Mélanie"]
[Result "0-2"]
[GameType "20"]
[Round "8"]
[Date "2014.01.11"]
[WhiteTime ""]
[BlackTime ""]
[WhiteUrl "http://toernooibase.kndb.nl/opvraag/liddetailp.php?SpId=1069"]
[BlackUrl "http://toernooibase.kndb.nl/opvraag/liddetailp.php?SpId=3073"]
[WhitePhotoUrl "http://toernooibase.kndb.nl/Afbeeldingen/Spelers/1069.jpg"]
[BlackPhotoUrl "http://toernooibase.kndb.nl/Afbeeldingen/Spelers/3073.jpg"]
[WhiteFlagUrl "http://toernooibase.kndb.nl/Clublogos/CEMA - De Vaste Zet Geleen.gif"]
[BlackFlagUrl "http://toernooibase.kndb.nl/Clublogos/WSDV Wageningen.gif"]
[WhiteRating "1026"]
[BlackRating "3208"]
1. 34-30 20-25 2. 31-27 25x34 3. 39x30 17-21 4. 44-39 21-26 5. 50-44 11-17 6. 30-25 19-24 7. 27-21 16x27 8. 32x21 14-20 9. 25x14 10x19 10. 21-16 5-10 11. 37-31 26x37 12. 41x32 6-11 13. 40-34 10-14 14. 44-40 18-23 15. 34-29 23x34 16. 40x20 15x24 17. 49-44 12-18 18. 47-41 8-12 19. 41-37 4-10 20. 46-41 10-15 21. 44-40 18-23 22. 32-28 23x32 23. 37x28 12-18 24. 39-34 7-12 25. 16x7 2x11 26. 41-37 14-20 27. 37-32 1-7 28. 42-37 9-14 29. 37-31 3-9 30. 34-29 20-25 31. 29x20 15x24 32. 43-39 11-16 33. 31-26 18-22 34. 32-27 22x31 35. 36x27 24-29 36. 33x24 19x30 37. 35x24 16-21 38. 27x16 7-11 39. 16x18 13x35 40. 24-20 25-30 41. 20-15 30-34 42. 38-33 9-13 43. 48-42 13-19 44. 42-37 19-24 45. 33-28 35-40 46. 26-21 17x26 47. 28-22 40-44
</div>
</ion-card>
</ion-item>
</ion-list>
</ion-content>
等于
int a = a = 1;
并且 大致 等同于
int a = (a = 1);
在初始化中使用int a;
a = (a = 1);
时,它已经被定义,它存在并且可以被分配给。更重要的是,因为它已经定义,所以它可以用作自己初始化的源。
答案 1 :(得分:3)
除{&#34;副作用&#34;将值a = 1
分配给1
- 结果值,即赋值后a
的值(例如,参见cppreference/assignment):
赋值也返回与lhs中存储的值相同的值(所以 可以使用诸如a = b = c之类的表达式。
因此,如果您编写a
,则输出将为int a; printf("%d",(a=1))
。
如果你知道1
中的链分配,那么这相当于int a; a = a = 1
,而{ - 1}}的结果是int a; a = (a=1)
,(a=1)
的结果1}}也是1
。
答案 2 :(得分:1)
在这种情况下,C标准没有定义行为,不是因为关于未序列效应或显式语句的规则,而是因为它无法解决这种情况。
2011年(非官方草案N1570)第6.7条第1款向我们展示了声明的总体语法。在这个语法中,int a = a = 1;
是一个
声明,其中:
int
是一个声明说明符,它仅由类型说明符 int
组成。a = a = 1
是 init-declarator ,其中a
是声明符,a = 1
是初始值设定项。 声明符仅包含标识符 a
。6.7.6 3将完整声明符定义为不属于另一个声明符的声明符,并且它表示完整声明符的结尾是序列点。但是,这些不是我们分析所必需的。
6.7.9 8说“初始化程序指定存储在对象中的初始值。”
6.7.9 11说“标量的初始化器应该是单个表达式,可选地用括号括起来。对象的初始值是表达式的初始值(转换后);与简单赋值相同的类型约束和转换适用,将标量的类型作为其声明类型的非限定版本。“
因此,一方面,初始值设定值(值为1)指定存储在a
中的初始值。另一方面,表达式a = 1
具有在a
中存储1的副作用。我没有在C标准中看到任何先发生过的事情。关于表达式中的排序的规则仅适用于初始化器的评估;他们没有告诉我们给a
“初始值”的顺序以及分配给它的副作用。
可以合理地得出结论:无论a
是初始值1还是赋值1,它都以值1结束,因此定义了行为。但是,该标准使得以未顺序的方式修改对象值两次的未定义行为,即使写入的值相同也是如此。该规则的显式语句在6.5 2中,适用于表达式,因此不适用于初始化和表达式之间存在冲突的情况。但是,我们可能会将标准的精神解释为:
因此,标准未能以保证实现将产生定义行为的方式指定行为。
此外,我们可以考虑int a = 2 + (a = 1)
。在这种情况下,初始值设定项的值为3,但副作用将1分配给a
。对于这个声明,标准没有说明哪个值占优势(除了人们可能从字面上解释“初始值”,因此暗示必须首先分配3,因此副作用必须晚于)。