1. 对指针进行数学运算与其他整型数据类型进行数学运算稍有不同。
首先,对指针只有加法和减法运算,其它运算在指针世界里没有意义。但是指针的加法和减法的具体运算根据它所指向的数据的类型的大小的不同而有所不同。
我们知道不同的数据类型在内存中占用的存储空间是不一样的。
例如,对于整型数据,字符char 占用1 的字节(1 byte),短整型short 占用2 个字节,长整型long 占用4个字节。
假设我们有3个指针:
|
而且我们知道他们分别指向内存地址1000, 2000 和3000。
因此如果我们有以下代码:
|
就像你可能想到的,mychar的值将会变为1001。而myshort 的值将会变为2002,mylong的值将会变为3004。
原因是当我们给指针加1时,我们实际是让该指针指向下一个与它被定义的数据类型相同的元素。
因此,它所指向的数据类型的长度字节数将会被加到指针的数值上。以上过程可以由下图表示:
这一点对指针的加法和减法运算都适用。如果我们写以下代码,它们与上面例子的作用一抹一样: mychar = mychar + 1;
myshort = myshort + 1;
mylong = mylong + 1; |
2. 这里需要提醒你的是,递增 (++) 和递减 (--) 操作符比间接引用操作符dereference operator (*)有更高的优先级,因此,以下的表达式有可能引起歧义:
*p++;
*p++ = *q++; |
第一个表达式等同于*(p++) ,它所作的是增加p (它所指向的地址,而不是它存储的数值)。
在第二个表达式中,因为两个递增操作(++) 都是在整个表达式被计算之后进行而不是在之前,
所以*q 的值首先被赋予*p ,然后q 和p 都增加1。它相当于:
*p = *q;
p++; q++; |
3. *p++和*++p的区别
#include <iostream> using namespace std int main(void) { int aa[] = {1, 2, 3, 4}; int *p = aa; int a = *p++; //等价于a = *(p++); 即a = *p; p = p + 1; int b = *++p; //等价于b = *(++p); 即p = p + 1; b = *p; cout<<"a = "<<a<<" , b = "<<b<<'\n'; return 0; }
输出:
a = 1, b = 3
当我们加上()时,就是另一种情况了,(*p)++和++(*p):
#include <stdio.h>
int main(void) { int a = 5; int *p = &a; int b = (*p)++; //等价于b = a++; 即b = a; a = a + 1; int c = ++(*p); //等价于c = ++a; 即a = a + 1; c = a; cout<<"b = "<<b<<" , c = "<<c<<'\n'; cout<<"(*p)++ = "<<(*P)++<<" , ++(*p) = "<<++(*p)<<'\n'; return 0; }
输出:
b = 5 , c = 7
(*p)++ = 8 , ++(*p) = 8
注意对他们进行区别,也要特别注意加上()和不加()的不同含义。