1
18
我们应该首先检查一下A[5][5]到底是什么。涉及的类型有:
不涉及整数数组[25]。 sizeof语义暗示数组作为一个整体是连续的,这是正确的。Ints的数组[5]必须具有5*sizeof(int),并且递归应用时,[5][5]必须具有5*5*sizeof(int)。没有额外的填充空间。 此外,当将数组作为一个整体提供给具有sizeof的memset、memmove或memcpy时,该数组必须工作。还必须可以使用(char*)在整个数组中迭代。所以一个有效的迭代是:
对(int*)执行相同操作将是未定义的行为,因为如前所述,不涉及int数组[25]。在克里斯托夫的回答中使用联合也是有效的。但还有另一个更为复杂的点,相等运算符: 5.5.9 两个指针比较相等,如果且仅当两个指针都为空指针时,这两个指针都是指向同一对象(包括指向对象的指针和位于其开头的子对象)或函数的指针,这两个指针都是指向同一数组对象的最后一个元素的指针, 或者一个是指向一个数组对象末尾的一个指针,另一个是指向另一个数组对象的开头的指针,该对象恰好紧跟在地址空间中的第一个数组对象之后。 91) 91)两个对象在内存中可能是相邻的,因为它们是较大数组的相邻元素,或者是结构的相邻成员,而它们之间没有填充,或者是因为实现选择将它们放置在一起,即使它们是无关的。如果先前的无效指针操作(如访问数组边界外)产生未定义的行为,则随后的比较也会产生未定义的行为。 这意味着:
I1等于I2。但是,当使用(int*)迭代数组时,它仍然是未定义的行为,因为它最初是从第一个子数组派生的。它不会神奇地将指针转换为第二个子数组。 即使这样做
没用。它比较等于i1和i2,但它不是从任何子数组派生的;它最多是指向单个int或int数组[1]的指针。 我不认为这是标准中的错误。另一种方法是:允许这样做会引入一种特殊情况,即违反数组的类型系统或指针算术规则,或者两者都违反。它可能被认为是一个缺失的定义,但不是一个错误。 因此,即使[5][5]的内存布局与[25]的布局相同,并且可以使用(char*)非常相同的循环对两者进行迭代,如果一个循环用作另一个循环,则允许一个实现爆炸。我不知道它为什么应该或知道任何实现,可能在标准中有一个直到现在才提到的事实,这使得它的行为得到了很好的定义。在那之前,我会认为它是未定义的,并保持在安全的一边。 |
2
11
我在我们的 original discussion .
原则上,你可以通过铸造来解决这个问题。
据我所知,这是符合标准的C99。 |
3
2
如果数组是静态的,就像
|
Community wiki · C中有哪些耗时的操作? 1 年前 |
Community wiki · 将所有处理器电源都投入到任务中 1 年前 |
Community wiki · C++为C添加了什么?[已关闭] 1 年前 |
Community wiki · 打印1到1000,不带循环或条件 1 年前 |