指针

来源:互联网 发布:甩手掌柜软件 编辑:程序博客网 时间:2024/05/22 13:31

什么是指针?

指针就是存放计算机内存地址的变量

int *p;

变量名字是p 类型是int *

指针占多少个字节?

目前的macbook都是64位系统 所有的指针都是8字节

取值运算符*和取地址运算符& 如下

        int a;        int *pa;        NSLog(@"%i",a);        NSLog(@"%p",pa);        pa=&a;        NSLog(@"%p",pa);        *pa=100;        NSLog(@"%i",a);

2015-04-03 08:59:58.948 Pointer[332:303] 0
2015-04-03 08:59:58.951 Pointer[332:303] 0x0
2015-04-03 08:59:58.952 Pointer[332:303] 0x7fff5fbff8cc
2015-04-03 08:59:58.953 Pointer[332:303] 100

声明了int类型变量a和int *类型变量pa 把a取地址后赋值给指针pa 现在指针pa指向a 指针pa存放的是a的地址而不是a的值 对pa进行取值操作*pa 就是找到地址是pa的内存空间 取*pa个字节 得到的就是a 所以给*pa赋值100就相当于给a赋值100 结果也是如此

地址和指针的区别

地址是常量 指针是变量

数组和指针

1、数组不等于指针 数组是数组元素按序排列的集合 指针是存放地址的变量 数组名就是数组第一个元素的地址 是个常量 是不变的 指针可以存放不同地址 是个变量 是可变的 如下

        int g[10]={};        int *pg=g;        NSLog(@"%i",g[0]);        NSLog(@"%i",*g);        NSLog(@"%i",*pg);        NSLog(@"%p",&g[0]);        NSLog(@"%p",g);        NSLog(@"%p",pg);

2015-04-06 10:59:52.905 Pointer[343:303] 0
2015-04-06 10:59:52.906 Pointer[343:303] 0
2015-04-06 10:59:52.906 Pointer[343:303] 0
2015-04-06 10:59:52.907 Pointer[343:303] 0x7fff5fbff840
2015-04-06 10:59:52.908 Pointer[343:303] 0x7fff5fbff840
2015-04-06 10:59:52.908 Pointer[343:303] 0x7fff5fbff840

可以看到g==&g[0] 既然数组g就是g[0]的地址 那么对g进行取值操作就是g[0] 可以看到*g==g[0] 指针pg指向g[0] 同样得出pg==&g[0] *pg==g[0]

2、指针变量+1 等于指针存放的内存地址+一个指针类型的字节大小 如下

        NSLog(@"%p",&g[1]);        NSLog(@"%p",g+1);        NSLog(@"%p",pg+1);
2015-04-06 10:59:52.909 Pointer[343:303] 0x7fff5fbff8442015-04-06 10:59:52.910 Pointer[343:303] 0x7fff5fbff8442015-04-06 10:59:52.910 Pointer[343:303] 0x7fff5fbff844

这里指针变量是int *类型 所以是4字节 指针的内存地址+4 刚才说过数组就是数组之中第一个元素的地址 也就是g[0]的内存地址+4 那么就是g[1]的内存地址 可以看到pg+1==&g[1] 同样 pg+2==&g[2] pg+3==g[3] … pg+9==&g[9] 总结:指针pg+i==&g[i] pg+i就是数组g第i个元素的地址 通过指针变量和数组名而不是数组下标写一个数组正序和数组逆序 如下

        int i;        for (i=0; i<10; ++i,++pg) {            *pg=i;            NSLog(@"g[%i]=%i",i,g[i]);        }

        int j;        for (i=0,j=9; i<10; ++i,--j) {            *(g+i)=j;            NSLog(@"g[%i]=%i",i,g[i]);        }
2015-04-06 13:55:15.977 Pointer[676:303] g[0]=02015-04-06 13:55:15.978 Pointer[676:303] g[1]=12015-04-06 13:55:15.978 Pointer[676:303] g[2]=22015-04-06 13:55:15.979 Pointer[676:303] g[3]=32015-04-06 13:55:15.980 Pointer[676:303] g[4]=42015-04-06 13:55:15.980 Pointer[676:303] g[5]=52015-04-06 13:55:15.981 Pointer[676:303] g[6]=62015-04-06 13:55:15.981 Pointer[676:303] g[7]=72015-04-06 13:55:15.982 Pointer[676:303] g[8]=82015-04-06 13:55:15.983 Pointer[676:303] g[9]=92015-04-06 13:55:15.983 Pointer[676:303] g[0]=92015-04-06 13:55:15.984 Pointer[676:303] g[1]=82015-04-06 13:55:15.984 Pointer[676:303] g[2]=72015-04-06 13:55:15.985 Pointer[676:303] g[3]=62015-04-06 13:55:15.988 Pointer[676:303] g[4]=52015-04-06 13:55:15.989 Pointer[676:303] g[5]=42015-04-06 13:55:15.989 Pointer[676:303] g[6]=32015-04-06 13:55:15.990 Pointer[676:303] g[7]=22015-04-06 13:55:15.990 Pointer[676:303] g[8]=12015-04-06 13:55:15.991 Pointer[676:303] g[9]=0

这里注意 循环之中不能写++g和--g 因为数组名g是地址常量 不能赋值 必须另外定义一个变量来帮助g完成自增自减操作 而指针变量pg就可以通过++pg完成相对应数组每个元素地址的操作

3、指针也可以像数组一样使用中括号 pg[i]表示*(pg+i) 同样g[i]=*(g+i)  当指针pg指向数组g 其实质都是*(&g[0]+i) 如下

        pg=g;        for (i=0; i<10; ++i) {            pg[i]=i;            NSLog(@"g[%i]=%i",i,g[i]);        }
2015-04-07 10:35:32.113 Pointer[399:303] g[0]=0
2015-04-07 10:35:32.124 Pointer[399:303] g[1]=1
2015-04-07 10:35:32.127 Pointer[399:303] g[2]=2
2015-04-07 10:35:32.128 Pointer[399:303] g[3]=3
2015-04-07 10:35:32.131 Pointer[399:303] g[4]=4
2015-04-07 10:35:32.132 Pointer[399:303] g[5]=5
2015-04-07 10:35:32.134 Pointer[399:303] g[6]=6
2015-04-07 10:35:32.135 Pointer[399:303] g[7]=7
2015-04-07 10:35:32.135 Pointer[399:303] g[8]=8
2015-04-07 10:35:32.137 Pointer[399:303] g[9]=9

4、中括号有个特点 就是pg[i]和i[pg]都是表示一个意思 都是*(pg+i) 如下

        for (i=0; i<10; ++i) {            i[pg]=i;            NSLog(@"g[%i]=%i",i,g[i]);        }
2015-04-07 11:00:40.466 Pointer[447:303] g[0]=0
2015-04-07 11:00:40.467 Pointer[447:303] g[1]=1
2015-04-07 11:00:40.468 Pointer[447:303] g[2]=2
2015-04-07 11:00:40.469 Pointer[447:303] g[3]=3
2015-04-07 11:00:40.470 Pointer[447:303] g[4]=4
2015-04-07 11:00:40.471 Pointer[447:303] g[5]=5
2015-04-07 11:00:40.471 Pointer[447:303] g[6]=6
2015-04-07 11:00:40.473 Pointer[447:303] g[7]=7
2015-04-07 11:00:40.473 Pointer[447:303] g[8]=8
2015-04-07 11:00:40.474 Pointer[447:303] g[9]=9

5、常量指针又作*前const:const int *ph和int const *ph const修饰*ph ph可改变 *ph不可改变 如下

        int h=100;        int l=200;        const int *ph=&h;        int const *qh=&h;        NSLog(@"%i %i",*ph,*qh);        ph=&l;        qh=&l;        NSLog(@"%i %i",*ph,*qh);//        *ph=300;//        *qh=300;        l=300;        NSLog(@"%i %i",*ph,*qh);

2015-04-07 15:01:16.694 Pointer[915:303] 100 100
2015-04-07 15:01:16.695 Pointer[915:303] 200 200
2015-04-07 15:01:16.696 Pointer[915:303] 300 300

这里我们可以改变ph和qh的指向 但是不能通过*ph和*qh改变指向的对象的值 要改变对象的值只能通过给对象赋值来改变 不能通过指针来改变

6、指针常量又作*后const :int *const pm const修饰pm *pm可改变 pm不可改变 如下

        int m=400;        int *const pm=&m;        NSLog(@"%i",*pm);        *pm=300;        NSLog(@"%i",*pm);//        pm=&l;

2015-04-07 15:01:16.697 Pointer[915:303] 400
2015-04-07 15:01:16.698 Pointer[915:303] 300

这里我们可以通过*pm改变指向的对象的值 但是不能改变pm的指向

7、指向常量的指针常量:const int *const pn const既修饰*pn又修饰pn 那么pn和*pn都不可改变 如下

        int n=500;        const int *const pn=&n;        NSLog(@"%i",*pn);//        *pn=300;//        pn=&l;
2015-04-07 15:01:16.698 Pointer[915:303] 500

0 0