什么是指针?
指针就是存放计算机内存地址的变量
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
地址和指针的区别
地址是常量 指针是变量
数组和指针
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
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
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