- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在C语言中,如果像这样初始化一个数组:
int a[5] = {1,2};
然后数组中所有未显式初始化的元素都将隐式初始化为零。
但是,如果我像这样初始化一个数组:
int a[5]={a[2]=1};
printf("%d %d %d %d %d\n", a[0], a[1],a[2], a[3], a[4]);
输出:
1 0 1 0 0
我不明白,为什么a[0]
打印1
而不是0
?这是未定义的行为吗?
注意:这个问题是在采访中提出的。
最佳答案
TL;DR:我认为 int a[5]={a[2]=1};
的行为没有明确定义,至少在 C99 中是这样。
有趣的是,对我来说唯一有意义的是您所询问的部分:a[0]
设置为 1
因为赋值运算符返回分配的值。其他一切都不清楚。
如果代码是 int a[5] = { [2] = 1 }
,一切都会很简单:这是一个指定的初始化器设置 a[2]
code> 为 1
,其他所有内容为 0
。但是对于 { a[2] = 1 }
我们有一个包含赋值表达式的非指定初始化器,我们就掉进了兔子洞。
这是我迄今为止发现的内容:
a
必须是局部变量。
6.7.8 Initialization
- All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
a[2] = 1
不是常量表达式,因此 a
必须具有自动存储功能。
a
在其自己的初始化范围内。
6.2.1 Scopes of identifiers
- Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator.
声明符是a[5]
,因此变量在它们自己的初始化范围内。
a
在其自身的初始化中处于事件状态。
6.2.4 Storage durations of objects
An object whose identifier is declared with no linkage and without the storage-class specifier
static
has automatic storage duration.For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.
a[2]=1
之后有一个序列点。
6.8 Statements and blocks
- A full expression is an expression that is not part of another expression or of a declarator. Each of the following is a full expression: an initializer; the expression in an expression statement; the controlling expression of a selection statement (
if
orswitch
); the controlling expression of awhile
ordo
statement; each of the (optional) expressions of afor
statement; the (optional) expression in areturn
statement. The end of a full expression is a sequence point.
请注意,例如在 int foo[] = { 1, 2, 3 }
中,{ 1, 2, 3 }
部分是一个用大括号括起来的初始化器列表,每个初始化器都有一个其后的序列点。
初始化按初始值设定项列表顺序执行。
6.7.8 Initialization
- Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. [...]
- The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject; all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.
但是,初始化表达式不一定按顺序求值。
6.7.8 Initialization
- The order in which any side effects occur among the initialization list expressions is unspecified.
但是,这仍然留下了一些悬而未决的问题:
序列点是否相关?基本规则是:
6.5 Expressions
- Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
a[2] = 1
是一个表达式,但初始化不是。
这与附件 J 略有矛盾:
J.2 Undefined behavior
- Between two sequence points, an object is modified more than once, or is modified and the prior value is read other than to determine the value to be stored (6.5).
附件 J 表示任何修改都有效,而不仅仅是表达式的修改。但鉴于附件不规范,我们或许可以忽略它。
子对象初始化如何相对于初始值设定项表达式排序?是否首先评估所有初始值设定项(按某种顺序),然后用结果初始化子对象(按初始值设定项列表顺序)?或者它们可以交错吗?
我认为int a[5] = { a[2] = 1 }
执行如下:
a
的存储空间是在进入其包含 block 时分配的。目前内容尚未确定。a[2] = 1
),后跟一个序列点。这会将 1
存储在 a[2]
中并返回 1
。1
用于初始化 a[0]
(第一个初始化器初始化第一个子对象)。但是这里事情变得模糊,因为其余元素 (a[1]
, a[2]
, a[3]
, a[4]
) 应该被初始化为 0
,但不清楚何时:它是否发生在 a[2] = 1
之前评价?如果是这样,a[2] = 1
将“获胜”并覆盖 a[2]
,但该赋值是否会具有未定义的行为,因为零之间没有序列点初始化和赋值表达式?序列点是否相关(见上文)?或者在评估所有初始化器之后是否会发生零初始化?如果是这样,a[2]
最终应该是 0
。
因为 C 标准没有明确定义这里发生的情况,所以我相信该行为是未定义的(由于遗漏)。
关于C 中数组初始化的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52307474/
我有一个程序可以打开一个窗口并快速改变背景颜色并随机弹出矩形和椭圆形。我的代码有效,但我不知道为什么,因为我没有在我的代码中调用 repaint() 函数。当我使用我个人的 update() 函数包含
var allRapidSpells = $$('input[value^=RSW]'); 谁能告诉我这是做什么的? 最佳答案 我敢猜测您正在使用 MooTools ,一个 JavaScript 框架
我有一个抽象父类,它有多个子类。我希望 child 能够拥有一个对于该 child 的每个实例都相同的变量。我不想将构造函数传递给 child 来告诉它它的名字,因为当它可以被硬编码时,这看起来很愚蠢
我刚刚在 Git 存储库上做了一些糟糕的事情,我不知道如何解决这个问题。我什至不知道我是怎么把它弄成这样的……! 在存储库(托管在 git hub 上)上,有 3 个我感兴趣的分支:master、br
我是 GIT 的新手,在理解提交日志图时遇到问题。 我感觉每条平行线都是一个分支。虽然我的源代码只有 2 个分支。我在下面提供的提交日志图中看到 3-4 条平行线(Microsoft Team Ser
我是 WPF 的新手,ScrollViewer 让我很沮丧。要么我只是没有“得到”它,要么它是一种有限的控制。 这是我的挫折: 水平滚动错误 水平滚动条仅在列表底部可见(我必须滚动到底部才能看到) 坏
那么 $('table.selectable td.capable input:text') 比 $('table.selectable td input:text') 更好吗?换句话说,指定一个类会
我刚刚完成了计算机图形学类(class),我们必须对光线追踪器进行编程。尽管所有结果都是正确的,但我对 OpenMP 的使用感到困惑(顺便说一句,这不是类(class)的一部分)。我有这个循环(C++
与 PatternSynonyms ( explicitly bidirectional form ),pattern-to-expr 方程实际上形成了一个函数,但拼写为大写(假设您最终得到正确类型的
我是 javascript/coffeescript 新手。 有人可以解释一下为什么这个 CoffeeScript/JavaScript 会毫无延迟地快速通过吗?我对第一种情况的想法是,它是对 upd
如果我调用document.getElementsByClassName('cl'),我会得到一个 HTMLCollection。它似乎包含 Element 对象而不是 HTMLElement 对象,
这是我本月的 azure payasyougo 使用费用。 我很难理解为什么我要为标准中型应用服务付费,我认为它会包含在计算时间中?我只运行一个云服务,这对于一个没有做太多事情的云服务来说似乎有点陡峭
除了the issue I am already having之外,我还在I saw a video on it之后安装了HBase(尚未安装)之前,还安装了Zookeeper。在安装它时,我遇到了许
我正在将 XSLT 与 regexp:match exslt 函数一起使用。上述函数采用 JavaScript Regex 模式。因此,我尝试匹配一组数字 1 到 3 OR 5 到 7 OR 9 到
我想知道为什么这段代码会给出消息:SyntaxError:意外的标记其他。 var compare = function(choice1,choice2){ if(choice1===choice2)
我尝试使用复选框和 JQuery 过滤日历上的事件, $(document).ready(function () { $('.scrollable-menu :checkbox').click(f
假设我们有一个用户想要一个名为:“test/lasdhjal.txt”,无论如何。现在,如果我将其放入新的文件(输入)中;对象里面,它会认为 test/是一个文件夹,而它是名称的一部分。我能做什么呢?
问题是 stash 的更改不会留在我 stash 它们的分支中。其他分支存储将被覆盖示例: 我愿意: git checkout iss4 // made some changes gi
我是一个 java 新手,并且在 StackOverflow 错误/在类之间访问文件的能力方面遇到了一个非常令人困惑的问题。我知道根本原因可能是我进行了一些递归调用,但修复它的语法却让我无法理解。我认
public X createData(int n) { int[] values = new int[n]; Random rand = new Random(); for
我是一名优秀的程序员,十分优秀!