|
对指针进行算术运算与对常规整数类型进行算术运算略有不同。首先,只允许加法和减法运算;其他的在指针的世界里是没有意义的。但是,加法和减法对指针的行为略有不同,具体取决于它们所指向的数据类型的大小。
当引入基本数据类型时,我们看到类型具有不同的大小。例如:总是有 1 个字节的大小,通常大于这个大小,甚至更大;这些的确切大小取决于系统。例如,假设在一个给定的系统中,需要 1 个字节,需要 2 个字节,需要 4 个字节。
假设现在我们在此编译器中定义了三个指针:charshortintlongcharshortlong
char *mychar;
short *myshort;
long *mylong;
并且我们知道它们分别指向内存位置 、 和 。
因此,如果我们写:100020003000
++mychar;
++myshort;
++mylong;
mychar,正如人们所期望的那样,将包含值 1001。但不是很明显,它将包含值 2002,并且将包含 3004,即使它们各自只递增一次。原因是,当将一个添加到指针时,指针将指向同一类型的以下元素,因此,它所指向的类型的大小(以字节为单位)将添加到指针中。
这在向指针添加和减去任何数字时都适用。如果我们写的话,情况会完全相同:myshortmylong
mychar = mychar + 1;
myshort = myshort + 1;
mylong = mylong + 1;
关于递增 () 和递减 () 运算符,它们都可以用作表达式的前缀或后缀,但行为略有不同:作为前缀,增量发生在计算表达式之前,而作为后缀,增量发生在表达式计算之后。这也适用于递增和递减指针的表达式,这些表达式可以成为更复杂的表达式的一部分,这些表达式还包括取消引用运算符 ()。记住运算符优先级规则,我们可以回想一下,后缀运算符(如递增和递减)的优先级高于前缀运算符,如取消引用运算符()。因此,以下表达式:++--**
*p++
等效于 。它的作用是增加 的值(所以它现在指向下一个元素),但由于用作后缀,整个表达式被计算为指针最初指向的值(它在递增之前指向的地址)。
从本质上讲,这些是取消引用运算符与增量运算符的前缀和后缀版本的四种可能组合(同样也适用于递减运算符):*(p++)p++
*p++ // same as *(p++): increment pointer, and dereference unincremented address
*++p // same as *(++p): increment pointer, and dereference incremented address
++*p // same as ++(*p): dereference pointer, and increment the value it points to
(*p)++ // dereference pointer, and post-increment the value it points to
涉及这些运算符的典型(但不是那么简单)的语句是:
*p++ = *q++;
因为 的优先级高于 和 ,所以都是递增的,但是由于两个增量运算符 () 都用作后缀而不是前缀,因此分配给的值在两者之前,并且是递增的。然后两者都递增。它大致相当于:++*pq++*p*qpq
*p = *q;
++p;
++q;
与往常一样,括号通过增加表达式的易读性来减少混淆。
|
|