扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
一:基础认知:
Point_Type* Point_Name = & (var_Type var)
指针类型* 指针名 = & 变量名(变量和指针必须为同一数据类型,因为是按数据类型的不同来划分内存大小的)
int a=12;
int* p=NULL;
p=&a;
printf(*p);
其中:
&(取址符):p=&a 是返回a的地址赋值给指针变量p
* :*p 是访问并返回指针变量p所存储的地址(a的地址)里面的值(a的值)
例如:把int型指针p指向int型变量var:
其中,&(取址符)的作用是取var的地址;而指针p是一个存储变量地址的指针变量;在指针p前面加一个‘ * ’则是访问指针p存储的变量地址所在的地址存储的值(即访问var的值)
输出一个指针变量保存的内容(也就是地址)用 %p :
var把自己的地址赋给p, 所以p(int指针型变量)的内存地址上存储的是var变量的地址;
*p是p存储的变量(var)地址存储的值(12);
所以:p==&var ;
*p==var;
图解:
二、指针和数组:
int* p=NULL (假设指针p是int型的指针,赋初始值为NULL(常量0))
(1)p++:指针p的值加4(因为p是Int型指针,所以内存单位是4个单位),即在指针p本身的地址原本所存储的变量的地址上加4,所以p++是指指针p向后移动4个内存单位
(在int数组里面表现为访问下一个元素)
(1)p--:指针p的值减4(因为p是Int型指针,所以内存单位是4个单位),即在指针p本身的地址原本所存储的变量的地址上减4,所以p++是指指针p向前移动4个内存单位
(在int数组里面表现为访问上一个元素)
例如:
#include#define M 3
int main()
{
int i = 0;
int group[] = {12,23,34};
int* p = group; //p的值默认为group[0]的地址,即p指向group[0]
while (p<= &(group[M-1])) //指针p的值(p所指向的变量的地址)小于等于group[2]的地址:即p的值从group[0]的地址移动到group[2]的地址,步长为4(int)
{
printf("\ngroup[%d]=%d\t&group[%d]=%p\tp=%p\t,*p=%d\t&p(指针变量p本身的地址)=%p", i, group[i],i,&group[i],p,*p,&p);
p++;//指针往后移动4个存储单位(int型)
i++;
}
return 0;
}
结果:
可以看到:group[i]==*p ;&group[i]==p ;&p一直没有变
且:&group[i]-&group[i-1]==4 其中 i 属于[1,2] (p一次移动4给内存单位)
上述代码图解:
三、指针和函数:
(1)引用调用&传值调用:
a、当指针作为函数的参数时,实现引用调用,引用调用就相当于把你家的地址告诉了别人,那么别人就可以在你家偷东西或放东西(修改变量的存储地址上存储的数据),比如本来你家只有一个苹果,但是被A(知道你家地址的人,相当于存储了变量地址的指针变量)换成了香蕉(进行了修改操作),那你再访问你家(地址),就只能看见香蕉了(修改后的数据),所以你只能拿香蕉(修改后的数据)去进行其他操作。
b、当一个基本类型的变量作为函数的参数时,实现传值调用,传值调用相当于赋值(a=b),把b的value的副本给a,a和b除了当前的value相等,没有其他联系。
#includevoid swap1(int* a,int* b)
{
int i = 0;
i = *a;
*a = *b;
*b = i;
printf("\nswap1().a(int*)的地址:%p\tswap1().b(int*)的地址:%p\t",&a,&b);
}
void swap2(int a,int b)
{
int i = 0;
i = a;
a = b;
b = i;
printf("\nswap2().a(int)的地址:%p\tswap2().b(int)的地址:%p\t", &a, &b);
}
int main()
{
int a = 23, b = 48;
printf("\na的地址:%p\tb的地址:%p",&a,&b);
printf("\n\n\n");
swap2(a, b);
printf("\n传值调用:a=%d,b=%d\t",a,b);
printf("\n\n\n");
swap1(&a,&b);
printf("\n引用调用:a=%d,b=%d\t",a,b);
printf("\n\n\n");
return 0;
}
结果:
void swap1(int* a,int* b)图解:
四、指针的指针
(1)概念
int a=12;
int* p=&a; //p是指向int型变量的指针变量,所以p是指向变量a的指针,p指向a的地址(int型指针p存储a的地址)
int** pp=&p; //pp是指向int型指针的指针变量,所以pp是指针p的指针,pp指向p的地址(int型指针的指针pp存储p的地址)
(2)例子
#includeint main()
{
int a = 12;
int* p = &a; //把a的地址赋值给int型指针p
int** pp = &p; //把指针p地址赋值给int型指针的指针pp
printf("\na的地址:%p\ta的值:%d\np的地址:%p\tp的值:%p\npp的地址:%p\tpp的值:%p",&a,a,&p,p,&pp,pp);//输出地址用:%p
return 0;
}
结果:
可以看到:
指针p存储的值(value)是a的地址(p指向a);
指针的指针pp存储的值(value)是指针p的地址(pp指向p);
图解:
(3)*
访问并返回一个指针(p)所指向的变量的value:*p
访问并返回一个指针的指针(pp)所指向的指针(p)所指向的变量的value:**pp
(哈哈哈哈哈,有点绕口,哈哈哈哈哈)
如下例:
#includeint main()
{
int a = 12;
int* p = &a; //把a的地址赋值给int型指针p
int** pp = &p; //把指针p地址赋值给int型指针的指针pp
//printf("\na的地址:%p\ta的值:%d\np的地址:%p\tp的值:%p\npp的地址:%p\tpp的值:%p",&a,a,&p,p,&pp,pp);//输出地址用:%p
printf("\n\n\na==%d\t*p==%d\t**pp==%d\n",a,*p,**pp);
return 0;
}
结果:
理论上来讲:
*p是根据p存储的变量(a)的地址来访问该变量(a),并返回该变量地址上存储的数据(12)
**pp:第一个‘*’是 *pp,是根据pp存储的指针变量(p)的地址来访问该指针变量(p),并返回该指针变量(p)的地址上存储的地址(a的地址);第二个‘*’是 *(*pp)相当于 *(p),即根据p存储的变量(a)的地址来访问该变量(a),并返回该变量地址上存储的数据(12)
也可以再一次用这张图解释:
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流