nai*_*aen 13 c pointer-arithmetic
我一直在阅读K&R关于C的书,发现C中的指针算法允许访问超出数组末尾的一个元素.我知道C允许用记忆做几乎任何事情,但我只是不明白,这种特性的目的是什么?
小智 21
C不允许访问超出数组末尾的内存.但是,它允许指针指向超出数组末尾的一个元素.区别很重要.
这样就可以了:
char array[N];
char *p;
char *end;
for (p = array, end = array + N; p < end; ++p)
do_something(p);
Run Code Online (Sandbox Code Playgroud)
(这样做*end
会出错.)
这显示了此功能有用的原因:在数组结束后指向(不存在的)元素的指针对于比较(例如循环)非常有用.
从技术上讲,这就是C标准允许的一切.但是,实际上,C实现(编译器和运行时)不会检查是否访问超出数组末尾的内存,无论它是一个元素还是更多元素.必须有边界检查,这将减慢程序执行速度.最适合(系统编程,通用库)的程序C类型的速度往往比安全和安全边界检查所带来的更多.
这意味着C可能不是通用应用程序编程的好工具.
Tod*_*ner 16
通常,表示"结束"位置是有用的,这是一个超出实际分配的位置,因此您可以编写如下代码:
char * end = begin + size;
for (char * curr = begin; curr < /* or != */ end ; ++curr) {
/* do something in the loop */
}
Run Code Online (Sandbox Code Playgroud)
C标准明确说明这个元素是一个有效的内存地址,但解除引用它仍然不是一个好主意.
为什么有这个保证?假设你有一台机器有2 ^ 16字节的内存,地址0000-FFFF,16位指针.假设您创建了一个16字节的数组.内存可以在FFF0分配吗?
连续释放16个字节,但是:
begin + size == FFF0 + 10 (16 in hex) == 10000
Run Code Online (Sandbox Code Playgroud)
由于指针大小,它包装到0000.现在循环条件:
curr < end == FFF0 < 0000 == false
Run Code Online (Sandbox Code Playgroud)
循环不会迭代数组,而是无效.这会破坏很多代码,所以C标准说分配是不允许的.
归档时间: |
|
查看次数: |
11064 次 |
最近记录: |