指针的计算
关于指针的计算
主要涉及到了指针的加法和减法
指针的加法主要是对标数组
例如
int main() {
int arr[] = { 1,2,3 };
int* p = arr;
printf("%d", *(p+1));
}
这里运行程序打印的就会是数组arr的第二个元素2
再来看指针的减法,也就是两个指针相减
int main() {
int arr[] = { 1,2,3 };
int* p = arr;
int* q = &arr[1];
printf("%d", q-p);
}
这里我们输出指针q-指针p的结果
我们可以看到结果输出了一,结合指针的加法,其实很好理解,指针p=arr,也就是arr首元素的地址,而指针q=&arr[1],也就是数组第二个元素的地址,就相当于是p+1-p,结果就是他们之间相差的格子数,也就是1
随便这里谈到空指针和野指针
野指针也就是悬挂指针
其定义方式如下
int *p;
*p=10;
这样定义很可能会因发系统报错,这是因为如果没有给指针初始化的话,有可能指针会访问到没有权限访问的地址,这样就会引发报错
还有一个就是空指针
int*p=0x00000000;
实际上在一个4G的内存空间中,前面1G为内核所占用,因此这里不能访问到
*&对于指针的操作
例如:int a=10;int *p=&a;
*&a,&*p,*&p这几个字符分别代表什么意思呢
*&a:因为*和&都是自右向左结合的单目运算符,因此这里的意思对a的地址进行解引用,a的地址也就是p,所这里的意思就是对p进行解引用,那就是a变量本身。
&*p;也就是对p解引用之后再取地址,对p解引用也就是a,再取地址也就是p本身。
*&p;也就是对p的地址进行解引用,p的地址也就是指向p的指针变量,再解引用就是p本身。
从这里不难看出在针对指针操作时,*和&相结合就会抵消掉。
const与指针的结合
这里相对就比较重要,在学习const与指针结合之前,我们先来了解一下const,其实在之前我们就接触了const
比如在定义变量时:const int a=4;
这时候就定义了一个常变量,也就是是这里a的值是不允许改变的
在指针定义中 这里也是一样的
我们看几个具体例子:
int a=0;int b=1;
int *p=&a;
*p=1;(1
p=&b;(2
const int *p=&a;
*p=1;(3
p=&b;(4
int *const s=&a;
*s=1;(5
s=&b;(6
我们来判断1~6中那些语句是错误的,第一,对指针变量p进行解引用改变a中的值这个是正确的。
第个,将指针变量p改变为b的地址,也是正确的。
第个,用const修饰了*p,也就等于说*p是常量不能更改,那么再想对他进行解引用去改变a的值就是错误的。
第四,虽然*p不能更改,但是p的指向是可以更改的,所以这里是正确的
第五,用const修饰了s,也就可以看作s为常量不可更改,那么对于它的解引用就不受影响,所以这里是正确的。
第六,既然s不能改变,那么s的指向也不可以改变,所以这里是错误的。
以上是正常情况,按如果a再特殊一点,例如
const int a=1;const int b=2;
那么关于他们的指针应该如何处理
这里我们直接给出结论:
既然a,b为常变量,那么关于a,b的各种类型的,直接或者间接的修改都是不正确的
其次在定义指针变量指向他们时,也要用const修饰指针,因为如果时普通类型的指针定义他们,那必然就可以用解引用的方法改值,但是a,b的值又是不能修改的,这里就出现了冲突,因此定义时应该
const int *p=&a;
其它的归规律和上面的相同
另外,定义指针指向字符串时,应该用const修饰
char crr[]="i am a student";
const char*p=crr;