指针是C和C++的重点,也是后面学习数据结构的基础,因此深刻理解指针的概念很重要。但是指针的概念比较抽象,难于理解,而且一些复杂的程序中都是离不开指针的,如果不能理解指针,那么就不能理解较为复杂的程序了,作者结合了自己学习C++的经验,对指针,指针变量,地址作如下阐述。
1.什么是指针:
程序中最离不开的就是变量,而变量相当于是一个容器,是用来存放数据的,变量是存放在内存中的。在C++ 中定义变量的形式是: 数据类型 + 变量名,这里的变量名实际上是一个符号地址,在程序编译时,操作系统将为每个变量在内存中分配内存,所以每个变量都有一个在内存中的地址,即物理地址,并将变量的符号地址(变量名)和物理地址关联起来,所以,我们在程序中对变量名的操作,编译时编译器都会将变量名转换为变量在内存中的物理地址,从而实现了对内存中指定地址区域的数据的操作,这就是变量的实现原理。变量在内存中的地址又称作指针,我们说“变量的地址” 就等价于 “变量的指针”,但是指针和指针变量是不一样的。
2.指针变量的概念:
从上面我们可以看到,每个变量都有一个符号地址(变量名)和物理地址(在内存中的位置,又叫做指针)。变量是可以存储数据的,但是指针变量与普通变量不同,它用来存放普通变量的地址,即指针变量是用来存放普通变量的指针。要知道,指针变量也是一个变量,在内存中也是占内存的,只不过它不存放基本类型数据,而是存放其他基本类型变量的地址。既然指针变量也有自己的物理地址,那么指针变量的地址用什么 来存储呢?用比该指针类型高一级的指针变量来存放指针变量的地址,如二级指针变量存放一级指针变量的地址,三级指针变量存放二级变量的地址,依次类推。
3.总结:
牢记三句话:
指针就是地址,地址就是指针;指针变量是一个变量,它保存了基本类型变量的地址。
如果指针变量p保存了变量a的地址,那么称作p指向了a,*p 就是变量a。
如果p是一个指针变量,*p 表示了以 p 的内容为地址的变量,就是p指向的变量。
4.举例如下:
int a ; //定义int类型变量
int *p = &a; //变量 p 是一个 int* 类型的一级指针变量,&是取地址符,p保存了a 的地址
cout << *p <<endl; //输出 p 指向变量的值,即输出a的值
cout << p << endl; //输出 p 的值,即输出变量a在内存中的地址
int **q; //定义二级指针变量
q = &p; // 二级指针变量q保存了一级指针变量p的地址
cout << q <<endl; //输出指针变量p在内存中的地址
cout << *q << endl; //输出q指向变量的值,即变量p的值,即a的地址
cout << **q << endl; //可以这样理解 cout<<*(*q), 等价于 cout <<*p, 即输出a的值
int a=10;
int*p=&a;
printf("%p\n",&a);
printf("%p\n",p);
printf("%p\n",&p);
printf("%d\n",*&a);//10
//定义指针变量
/*int num = 7;
int* p = #
printf("数值%d所在的地址是 %p\n", num, p);
//注意这里*操作符为解引用操作符,它返回指针p所指的对象的值(注意不是地址)。
printf("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p, *p);
//我们可以对*p赋值(对左值赋值),从而改变p所指的地址上所保存的值,从而改变此地址所存储的变量num的值。(上面num的值变为100)
*p = 100;
printf("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p, num);
return 0;*/
//指针的运算
//取值运算符“&”
/*int num=10;
printf("num=%d\n",num);
printf("num地址=%p\n",&num);
int *p1;
p1=#
printf("%p\n",p1);
int d=10;
int *e,*f;
e=&d;
f=e;
//都存储d的地址
printf("d地址=%p\n",&d);
printf("e=%p\n",e);
printf("f=%p\n",f);
float *pF;
printf("%p\n",pF);//随机地址,最好置于NULL(野指针)*/
//通过指针变量修改指向的内存中数据
/* int a=10,*pInt;
pInt=&a;
printf("a=%d\n",a);
scanf("%d",pInt);
*//* *pInt=100;
printf("%d\n",*pInt);*//*
printf("a=%d\n",a);*/
//取值运算符*
/*int a=2024;
int *p;
p=&a;
printf("%p\n",&a);
printf("%p\n",p);
printf("%d\n",*p);*/
//通过指针变量修改指向内存地址位置的值
/*int i1=10;
int *p1=&i1;
printf("i1=%d\n",i1);//10
*p1=100;
printf("i1=%d\n",i1);//100*/
/*int *p1,*p2;
int a,b;
scanf("%d %d",&a,&b);
p1=&a;p2=&b;
int max=a;
if(max>b){
p1=&a;
p2=&b;
}
else {
p1=&b;p2=&a;
}
printf("%d地址=%p\n",a,&a);
printf("%d地址=%p\n",b,&b);
printf("p1=%p\n",p1);
printf("p2=%p\n",p2);
printf("p1指向=%d\n",*p1);
printf("p2指向=%d\n",*p2);*/
/*int a,b;
scanf("%d %d",&a,&b);
int *p1=&a;
int *p2=&b;
printf("p1指向=%d\n",*p1);
printf("p2指向=%d\n",*p2);
if(a<b){
int* p;
p=p1;
p1=p2;
p2=p;
}
printf("p1指向=%d\n",*p1);
printf("p2指向=%d\n",*p2);*/
/* int b=999;
int *p=&b;
printf("%p\n",&b);
printf("%p\n",&*p);
printf("%d\n",*&b);*/
/*int a=10;
int *p;
p=&a;
int b=100;
p=&*&b;
printf("%d",*p);*/
指针与整数值的加减运算
int arr[5]={1,2,3,4,5};
int *p=&arr[1];
printf("数组地址为:%p\n",arr);
printf("数组首元素%d地址为:%p\n",arr[0],&arr[0]);
printf("p的地址为:%p,对应的值为%d\n",p,arr[1]);
printf("p+1的地址为:%p,对应的值为%d\n",p+1,*(p+1));//3
printf("p-1的地址为:%p,对应的值为%d\n",p-1,*(p-1));//1
return 0;
int arr[LENGTH]={10,20,30,40,50};
//传统遍历
for(int i=0;i<LENGTH;i++){
printf("%d",arr[i]);
printf(" ");
}
printf("\n");
//指针方式遍历
int *p=&arr[0];
for(int i=0;i<LENGTH;i++){
printf("%d",*(p+i));
}
/* printf("%d\n",*p);//10
printf("%d\n",*(p+1));//20
printf("%d\n",*(p+2));//30
printf("%d\n",*(p+3));//40*/