关于取地址符 &
1.&只能对变量取地址,不能对没有地址的东⻄取地址,&(i++)是不对的
//64位架构
#include<cstdio>
int main(){
int i=6;
int *p=&i;
printf("%x\n",p);//63fe44
printf("%p\n",&i);//000000000063fe44
printf("%p\n",p);//000000000063fe44
return 0;
}
//64位架构
#include<cstdio>
int main(){
int i=0;
int j;
printf("%p\n",&i);//000000000063fe4c
printf("%p\n",&j);//000000000063fe48
return 0;
}
2.数组 (&a=a)
//64位架构
#include<cstdio>
int main(){
int a[10];
printf("%p\n",&a);//000000000063fe20
printf("%p\n",a);//000000000063fe20
printf("%p\n",&a[0]);//000000000063fe20
printf("%p\n",&a[1]);//000000000063fe24
return 0;
}
指针
指针就是保存地址的变量常常用p表示 (pointer) “指针变量的值”=“这个指针所指向的对象的地址”
int* p=&i; int *p=&i;
【从p开始,先与*结合,故p是一个指针,再与int结合,说明指针所指向的内容为int型所以p是一个返回整型数据的指针】
int* p,q; *p是一个int,而q只是一个int型变量
给指针赋值使用取地址符(&),如p = &a;每次需要访问指针所指向的内容时,使用解引用符号*进行访问。如:printf(“%d”,*p);
1.作为参数的指针
//64位架构
#include<cstdio>
void f(int *p);
int main(){
int i=6;
printf("&i=%p\n",&i);//&i=000000000063fe4c
f(&i);
return 0;
}
void f(int *p){
printf("p=%p\n",p);//p=000000000063fe4c
}
2.访问那个地址上的变量 *
//64位架构
#include<cstdio>
void f(int *p);
int main(){
int i=6;
printf("&i=%p\n",&i);//&i=000000000063fe4c
f(&i);
printf("i=%d\n",i);//i=26 !!!
return 0;
}
void f(int *p){
printf("p=%p\n",p);//p=000000000063fe4c
printf("*p=%d\n",*p);//*p=6
*p=26;//访问外面的i变量
}
“指针变量的值”=“这个指针所指向的对象的地址”
int y; int *yPtr=&y;
- &*yPtr -> &(*yPtr) -> &(y) -> yPtr
- *&yPtr -> *(&yPtr) -> *(yPtr的地址) -> 得到yPtr地址上的变量 -> yPtr
3.指针的应用场景
#include<cstdio>
void swap(int *pa,int *pb);
int main(){
int a=5;
int b=6;
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);//a=6,b=5
return 0;
}
void swap(int *pa,int *pb){
int t=*pa;
*pa=*pb;
*pb=t;
}
- 函数返回多个值,某些值就只能通过指针返回
- 传⼊的参数实际上是需要保存带回的结果的变量
例如找一个数组中的最大值和最小值
#include<cstdio>
void minmax(int a[],int len,int *max,int *min);
int main(){
int a[]={1,2,3,4,11,23};
int min,max;
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min=%d,max=%d\n",min,max);//min=1,max=23
return 0;
}
void minmax(int a[],int len,int *min,int *max){
*min=*max=a[0];
for(int i=1;i<len;i++){
if(a[i]<*min){
*min=a[i];
}
if(a[i]>*max){
*max=a[i];
}
}
}
- 函数返回运算的状态,结果通过指针返回
- 常⽤的套路是让函数返回特殊的不属于有效范围内的值来表⽰出错: -1或0(在⽂件操作会看到⼤量的例⼦)
- 但是当任何数值都是有效的可能结果时,就得分开返回了
- 后续的语⾔(C++,Java)采⽤了异常机制来解决这个问题
#include<stdio.h>
int divide(int a,int b,int *result);
int main(){
int a=5;
int b=2;
int c;
if(divide(a,b,&c)){
printf("%d/%d=%d\n",a,b,c);//5/2=2
}
return 0;
}
int divide(int a,int b,int *result){
int ret=1;
if(b==0){
ret=0;
}else{
*result=a/b;
}
return ret;
}
指针与数组
对于一个函数int function(int a);
当调用者调用该函数的时候将传递一个值给a,这个a只是你传递进去的参数的一个副本。而数组传递的时候,会退化为指针,其将数组的首地址复制给形参。
#include<stdio.h>
int f(int a[]){
printf("%lu\n",sizeof(a));
a[0]=111;
}
/*int f(int *a){
printf("%lu\n",sizeof(a));
a[0]=111;
}*/
int main(){
int a[]={1,2,3,4,5,};
printf("main %lu\n",sizeof(a));//20 4*5
f(a); //8,指针
printf("%d\n",a[0]);//111
return 0;
}
#include<stdio.h>
int main(){
int a[]={1,2,3,4,5,};
printf("%d\n",a[0]);//1
printf("%d\n",*a);//1 ,*数组
printf("%p\n",&a[0]);//000000000062FE30
printf("%p\n",a);//000000000062FE30
int x=9;
int *p=&x;
printf("%d\n",*p);//9
printf("%d\n",p[0]);//9,如果我认为p所指的地方当做一个数组
return 0;
}
指针与const
指针是const 所指是const
如果const在*的前面,表示所指的东西不能被修改(前两个),如果const在*的后面,表示指针不能修改