假设我按照以下方式做某事:
然后我想循环遍历这些元素,最基本的方法是:
但也有可能是
或者反过来
我的问题是,如果我想避免使用i并做如下操作:
或者反过来说:
似乎在避免使用i的循环中存在非常微小的错误行为的可能性;对于第一个循环,如果p + length == 0,即我们在可能的
也许这些情况并不真实发生,但如果这是未定义行为,那么也许使用i进行循环会更好,尽管看起来稍微不太优雅...
编辑:根据Fe2O3的评论,我想起我确实想以稍微不同的方式提问。换句话说,我想要的不是一个
size_t length = 1000;
char* p = malloc(length);
然后我想循环遍历这些元素,最基本的方法是:
for (size_t i = 0; i < length; ++i) {
p[i] = ...; // or p[length - 1 - i] = ...
}
但也有可能是
char* q = p;
for (size_t i = 0; i < length; ++i) {
*q = ...;
++q;
}
或者反过来
char* q = p + (length - 1);
for (size_t i = 0; i < length; ++i) {
*q = ...;
--q;
}
我的问题是,如果我想避免使用i并做如下操作:
char* const final = p + (length - 1);
for (char* q = p; q <= final; ++q) {
*q = ...;
}
或者反过来说:
char* const final = p + (length - 1);
for (char* q = final; q >= p; --q) {
*q = ...;
}
似乎在避免使用i的循环中存在非常微小的错误行为的可能性;对于第一个循环,如果p + length == 0,即我们在可能的
size_t
限制的最后一点刚好分配了内存并发生了溢出...对于第二个循环,如果p == 0,即我们在内存的开头刚好分配了内存...在这两种情况下,循环将无法在需要时结束...也许这些情况并不真实发生,但如果这是未定义行为,那么也许使用i进行循环会更好,尽管看起来稍微不太优雅...
编辑:根据Fe2O3的评论,我想起我确实想以稍微不同的方式提问。换句话说,我想要的不是一个
char
数组,而是一个某种结构类型的元素数组,所以这个结构可能相对较大,比如大小为3000
。那么,只要p
小于3000
,第二个循环就会失败,不一定要等于0
。而且,只要final
的大小达到最大值减去3000
就足够了...当然,3000
可以更大...
p + length
作为指针(例如用于指针比较)始终是正确的... 但是如果您对其进行解引用,则是不正确的:*(p + length)
是无效的! - undefined0
不等于NULL
的机器上没有实际测试过你的代码,那么它很可能会在其他方面失败,比如short
只有23位。可移植的代码并不会在每个地方都完全可移植。 - undefined