关于指针有一片文章写的详尽又容易了解:http://blog.chinaunix.net/uid-22889411-id-59688.html
(1)指针和地址的区别
//指针有类型 地址没有类型,需要强制类型转化才能赋值给指针变量
int* p=(int*)0x44fc28
(2)指针使用之前必须要有初始值
void main(){
int* p;
//报空指针异常
printf("%#x",p);
getchar();
}
上文报错处可以这样写
int* p=NULL;
(3)指针变量多次赋值为不同变量的地址
void main(){
int* p=NULL;
printf("%#x",p);
//把200当做一个内存地址赋值给了指针变量(16进制)
p = 200;
//打印指针变量对应的值
printf("%d\n", *p);
getchar();
}
打印输出发现报错
200转成16进制,由于数字比较小,系统本身已经占用了这块内存区域,内存地址已经被分配掉了,然而系统本身内存数据不允许访问!一般情况下,我们不要直接给指针变量赋值为整数。
(4)NDK指针地址,二级指针
int a=100;
int b=200;
int* p1=&a;
//p1保存的是a变量的地址——0x0022FDE0,通过该地址可以查询到a的值是100
printf("p1地址:%#x\n",&p1);
//指针变量也是变量,同样占据了内存空间,同样有地址,因此可以用一个指针指向它
//这就称之为二级指针,
//定义一个二级指针p2,&p1指针的地址
int** p2=&p1;
**p2=1000;
printf("二级指针的地址:%#x",&p2);
//a的值会变成1000,*是取值,&是取地址
//p2保存的数据是p1的地址,*p2上的数据是p1上面的数据
//p1保存的数据是a的地址,所以**p2实际上就是a的值
printf("\na的值:%d",a);
system("pause");
(4)指针运算(赋值运算符和算术运算)
算术运算(+,-,*,/)
void main(){
int ids[]= {22,33,34,44,34,46,22,90};
//打印数组
printf("数组%#x\n",ids);
//数组第一个元素地址
printf("数组第一个元素地址 %#x",&ids[0]);
//两个值相同
system("pause");
}
控制台输出两个值相同
ids是常量指针,存储的是数组的首地址
继续大家会发现,数组在内存中的存储是连续的
我们 看下指针如何运算:
void main(){
int ids[] = { 22, 33, 34, 44, 34, 46, 22, 90 };
//打印数组
printf("数组%#x\n", ids);
//数组第一个元素地址
printf("数组第一个元素地址 %#x\n", &ids[0]);
//两个值相同
int* p = ids;
p++;
printf("地址:%#x值:%d",p,*p);
system("pause");
}
注意,p++后,*p的值变成了33(既数组的第二个元素),地址也变成了第二个元素的地址,因为int类型占4个字节,+1后就相当于+了一个int字节数,就是字节由de8+4=dec;
总结:p++每次向前移动sizeof(数据类型)个字节
下面我使用指针遍历数组
void main(){
int ids[] = { 22, 33, 34, 44, 34, 46, 22, 90 };
//打印数组
printf("数组%#x\n", ids);
//数组第一个元素地址
printf("数组第一个元素地址 %#x\n", &ids[0]);
//两个值相同
int* p = ids;
p++;
printf("地址:%#x值:%d\n",p,*p);
for (; p < ids + 8;p++){
printf("值:%d\n",*p);
}
system("pause");
}
注意:让指针递增或者递减,一般情况下只有在数组遍历的时候才有意义,是基于数组在内存中的象形排列方式;
(5)指针运算(通过使用指针循环给数组赋值)
传统方法赋值
void main(){
int ids[6] ;
int*p = ids;
//传统的写法赋值
int i = 0;
for (; i < 6; i++){
ids[i] = i * 2;
}
//输出
i = 0;
for (; i < 6; i++){
printf("值:%d",ids[i]);
}
system("pause");
}
指针赋值:
void main(){
int ids[6] ;
int*p = ids;
int i = 0;
for (; p < ids + 6;p++){
*p = i * 2;
i++;
}
i = 0;
for (; i < 6; i++){
printf("值:%d",ids[i]);
}
system("pause");
}
运行结果和上次运行结果一样;
(6)指针运算,数组内部的加减
void main(){
int ids[] = {34,5,65,43,66,77,99};
int* p = ids;
p = p + 3;
//*p的值是43
printf("值:%d\n地址:%#x\n",*p,p);
system("pause");
}
(7)指针运算指针大小比较
大小比较,都是在遍历数组的时候运用,其他情况下没用,指针地址相等,并不代表值相等;因为指针有类型
(8)NDK-指针运算-指针与数组的几种写法
int _tmain(int argc, _TCHAR* argv[])
{
int ids[]={52,84,86,92,48,47,15,32};
int i=0;
for(;i<7;i++){
//输出数据
printf("%d %#x\n",ids[i],&ids[i]);
//ids就是常亮指针,就是一个首地址
//ids+0等价于 &ids[0]
//ids+1等价于 &ids[1]
//以此类推……
//ids+i 等价于&ids[i]
//在地址墙面加*就是取值,所以
//*(ids+i) 等价于 ids[i]
printf("%d %#x\n",*(ids+i),ids+i);
}
return 0;
}
(9)指针引用二维数组
int _tmain(int argc, _TCHAR* argv[])
{
//两行三列的二维数组
int ids[2][3]={23,58,4,58,69,79};
//遍历二维数组,外层循环控制行,内存循环控制列
int i=0;
for(;i<2;i++){
int j=0;
for(;j<3;j++){
printf("值:%d,地址:%#x ",ids[i][j],& ids[i][j]);
}
//换行
printf("\n");
}
printf("ids:%#x &ids:%#x *ids:%#x ",ids,&ids,*ids);
getchar();
return 0;
}
大家看下,我们发现ids,&ids,*ids的三个地址是一模一样。注意,地址相同,但并不代表值相同
int _tmain(int argc, _TCHAR* argv[])
{
//两行三列的二维数组
int ids[2][3]={23,58,4,58,69,79};
//遍历二维数组,外层循环控制行,内存循环控制列
int i=0;
for(;i<2;i++){
int j=0;
for(;j<3;j++){
printf("值:%d,地址:%#x ",ids[i][j],& ids[i][j]);
}
//换行
printf("\n");
}
printf("ids:%#x &ids:%#x *ids:%#x\n ",ids,&ids,*ids);
printf("长度%d, 长度%d, 长度%d",sizeof(*ids),sizeof(*&ids),sizeof(**ids));
getchar();
return 0;
}
大家看下打印结果:
大家注意了,长度12说明ids代表行指针(指向一个拥有三个数组的元素),每行3个int类型,每个int类型是4个字节;
长度24说明&ids代表的是一个二维数组指针,24个int类型,每个int类型4个字节;
长度4,说明*ids代表数组的类型,指向该数组的数据类型的指针;如果是double类型的数组,则此处将是8;
再看下下面的代码
int _tmain(int argc, _TCHAR* argv[])
{
//两行三列的二维数组
int ids[2][3]={23,58,4,58,69,79};
//打印结果是第一行的第一个元素23,即ids[0][0]
printf("值:%d",**ids);
getchar();
return 0;
}
我们继续来推导,看下面的代码
int _tmain(int argc, _TCHAR* argv[])
{
//两行三列的二维数组
int ids[2][3]={23,58,4,58,69,79};
//打印第二行,第二列
printf("值:%d\n",ids[1][1]);
//用指针来打印第二行,第二列
printf("值%d",*(*(ids+1)+1));
getchar();
return 0;
}
ids代表行指针:ids+0代表第一行,
ids+1代表第二行,
以此类推,第N行为ids+n;
取某一行的第一个元素的指针:*(ids+i)
第一行第一个元素指针:*(ids+0)
第二行第一个元素指针:*(ids+1)
以此类推:*(ids+i)
ids代表首地址所以
取第一行第一个指针:*ids+0;
取第一行第二个指针:*ids+1;
取第一行第三个指针:*ids+2;
以此类推:*ids+j
把以上两个推理结合下,取第二行第二个元素的指针:
*(ids+1)+1
我们可以得出结论:(ids+i)+j,获取该地址的值为(*(ids+i)+j)