指针运算
一、指针+-整数
int a=5;
float arr[a];
float *p;
for(p=&arr[0];p<&arr[5];)
{
*p++=0;// *p=0 p++
}
二、指针-指针
指针与指针之间是可以相减的
int arr[10]={0};
printf("%d",(&arr[9] - &arr[0]));
打印的结果是9,(中间有9个元素)
指针减去指针,得到的是指针与指针之间元素的个数,高指针减去低指针就是正数,低指针减去高指针指针得到的就是负数。
但不是所有指针之间都能相减,指向同一块内存的指针相减才有意义
int arr[10]=[0];
char arr2[10]=[0];
printf("%d",(&arr[9] - &arr2[0])); //这种写法本质上是没有意义的
那么借助指针相减的这个性质,我们可以利用指针相减来进行一些功能,比如我们可以实现strlen函数的功能
int len = my_strlen("abcdef"); 这个len中存放的是a b c d e f \0
这是使用指针实现的函数
int my_strlen(char* str)
{
int count =0;
while(*str !='\0' )
{
count++;
str++;
}
return count;
}
这是一个用指针相减的办法来实现函数
int my_strlen(char* str)
{
char* strat = str;
while(*str !='\0')
{
str++;
}
return (str -start);
}
那指针能不能相加呢?
其实这是没意义的,指针的本质是地址,地址减去地址可以推算出两个地址的距离,但是地址加地址没有实际的意义。就像是计算距离某个节日还剩多少天,我可以让莫某个节日是某月30日减去我今天的3日得出还剩27天,但是相加就没有什么实际的意义。
我们再来看指针初始化数组的这样一个代码
int arr[5];
int *p;
for(p = &arr[5];p>&arr[0])
{
*--p = 0;
}
按照我们做开始学习的for语句的模板,我们也可以把这个代码写作这样
for(p=&arr[4];p>=&arr[0];p--)
{
*p=0;
}
感觉这个代码比较容易理解
上述这串代码在绝大多数的编译器上都是可以运行的,但是我们应该避免这样子写,因为标准并不保证它可行。
标准规定,允许指向数组元素的指针与指向数组最后一个元素后面呢那个内存位置的比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
意思是,标准指向数组的指针与最后的元素的后面那个指针比较,但是不允许与第一个元素之前的那个指针比较。
这里我们用图来解释一下,标准允许指向这个数组的指针与p2进行比较,但不允许与p3进行比较。