Pointers on C——6 Pointers.14

来源:互联网 发布:淘宝网代卖怎么做的 编辑:程序博客网 时间:2024/06/18 07:43

6.13.2 Relational Operations

Relational operations on pointers are also constrained. It is possible to compare two pointer values with the relational operators

对指针执行关系运算也是有限制的。用下列关系操作符对两个指针值进行比较是可能的:


< <= > >=


CAUTION!

only if they both point to elements of the same array. Depending on which operator you choose, the comparison will tell you which pointer points earlier or later in the array. The results of comparing arbitrary pointers are not defined by the Standard. 

不过前提是它们都指向同一个数组中的元素。根据你所使用的操作符,比较表达式将告诉你哪个指针指向数组中更前或更后的元素。标准并未定义如果两个任意的指针进行比较会产生什么结果。


However, you may test for equality or inequality between any pointers, because the results of such comparisons do not depend on where the compiler has chosen to allocate data—the pointers either refer to the same address or to different ones.

然而,你可以在两个任意的指针间执行相等或不相等测试,因为这类比较的结果和编译器选择在何处存储数据并无关系一一指针要么指向同一个地址,要么指向不同的地址。


Letʹs look again at the loop to clear the elements of an array.

让我们再观察一个循环,它用于清除一个数组中所有的元素。


#define N_VALUES 5

float values[N_VALUES];

float *vp;

for( vp = &values[0]; vp < &values[N_VALUES]; )

*vp++ = 0;


The for statement uses a relational test to terminate the loop. The test is legal because both vp and the pointer constant point to elements of the same array. (Actually, the pointer constant points one beyond the end of file array, and when the last comparison is made so does vp, but indirection is not performed so weʹre safe.) Using != instead of< would also work, because both expressions will be false when vp attains its final value.

for 语句使用了一个关系测试来决定是否结束循环。这个测试是合法的,因为vp和指针常量都指向同一数组中的元素(事实上,这个指针常量所指向的是数组最后一个元素后面的那个内存位置,虽然在最后一次比较时, vp 也指向了这个位置,但由于我们此时未对vp 执行间接访问操作,所以它是安全的)。使用!=操作符代替〈操作符也是可行的,因为如果vp未到达它的最后一个值,这个表达式的结果总是假的。

Now consider this loop:


for( vp = &values[N_VALUES]; vp > &values[0]; )

*--vp = 0


It performs the same job as the previous loop except that the elements are cleared in the opposite order. We initialize vp to point just beyond the right end of the array, but the pointer is decremented just before the indirection occurs. We stop the loop when vp points to the first element of the array, but this occurs after the first element has already been cleared.

它和前面那个循环所执行的任务相同,但数组元素将以相反的次序清除。我们让vp 指向数组最后那个元素后面的内存位置,但在对它进行间接访问之前先执行自减操作。当vp 指向数组第1 个元素时,循环便告终止,不过这发生在第1 个数组元素被清除之后。


Some might object to the expression *--vp on the grounds of readability. But look what happens to this loop when it is ʺsimplified:ʺ

有些人可能会反对像*--vp 这样的表达式,觉得它的可读性较差。但是,如果对其进行"简化",看看这个循环会发生什么:


for( vp = &values[N_VALUES-1]; vp > &values[0]; vp-- )

*vp = 0;


Now vp is initialized to point to the last element of the array and is decremented in the adjustment step of the for statement. There is a problem with this loop—do you see it?

现在vp指向数组最后一个元素,它的自减操作放在for 语旬的调整部分进行。这个循环存在一个问题,你能发现它吗?


After the first element in the array is cleared, vp is decremented again, and the nextcomparison is supposed to terminate the loop. But here is where the problem occurs:the comparison vp >= &values[0] is undefined because vp has moved outside of the bounds of the array. The Standard allows for a comparison with a pointer that points just beyond the right side of an array but not for one that points just beyond the left side.

在数组第1 个元素被清除之后, vp 的值还将减去1,而接下去的一次比较运算是用于结束循环的。但这就是问题所在:比较表达式vp>=&values[0] 的值是未定义的,因为vp 移到了数组的边界之外。标准允许指向数纽元素的指针与指向数组最后一个元素后面的那个内存位置的指针进行比较,但不允许与指向数组第1 个元素之前的那个内存位直的指针进行比较。


In practice, this loop will work properly on most ANSI C implementations.Nevertheless, it should be avoided because the Standard does not guarantee that it will work, and sooner or later you are bound to run across a machine on which it fails. Such are the problems that give nightmares to programmers responsible for portable code.

实际上,在绝大多数C 编译器中,这个循环将顺利完成任务。然而,你还是应该避免使用它,因为标准并不保证它可行。你迟早可能遇到一台这个循环将失败的机器。对于负责可移植代码的程序员而言,这类问题简直是个恶梦。


上一章 Pointers on C——6 Pointers.13

原创粉丝点击