C语言--深入理解指针
一. 指针的概念
要知道指针的概念,要先了解变量在内存中是如何存储的。在存储时,内存被分为一块一块的,每一块都有一个特有的编号。而这个编号可以暂时理解为指针,就是酒店的门牌号一样。
- 变量和地址
看下面代码
void main(){
int x = 10, int y = 20;
}
代码中声明了两个变量x,y。把内存当做一个酒店,而每个房间就是一块内存。那么int x = 10;和int y = 20;的实际含义是:去酒店订了两个房间,门牌号暂时用px、py表示,让10住进px,让y住进py,其中门牌号就是px、py,也就是房间的地址。x和y在这里可理解为具体的房间,房间x的门牌号(地址)是px,房间y的门牌号(地址)是py。而10和20,通过px、py两个门牌,找到房间,住进x、y。
- 指针变量和指针的类型
指针变量就是一个变量,存储的内容是一个指针。可以理解为指针变量就是一张房卡,房卡存储了房间号的信息。在定义一个变量的时候,要确定其类型,同样,定义指针变量时也是一样的,必须确定指针类型。int变量的指针需要用int类型的指针存储,float变量的指针需要用float类型的指针存储。就像你只能用酒店A的房卡存储酒店A中房间号的信息一样。
二. 变量的指针与指针变量
变量的指针就是变量的存储地址,指针变量就是存储指针的变量。
- 指针变量的定义及使用
1.1 指针变量的定义
指针变量的定义形式:数据类型 *指针名。
int *x;表示int类型指针变量x;
float *t;表示float类型指针变量t;
char *ch;表示char类型的指针变量ch。
1.2 指针变量的使用
取地址运算符&:单目运算符&是用来取操作对象的地址。例如&i为取变量i的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。
指针运算符*(间接寻址符):与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例如 x=&i,x为i的地址,*x则为通过i的地址,获取i的内容。
int a;//声明一个整型变量a;
int *pa;//声明一个指针变量,指向变量a地址;
pa = &a//通过取地址符&获取a地址,赋值给指针变量pa。
printf("%d",*pa);//通过间接寻址符,获取指针指向的地址上的内容。
1.3 &和*的结合方法
&和*都是右结合计算的。假设变量x = 10,则*&x的含义是先获取x的地址,再获取地址上的内容,因为&和*互为逆运算,所以x = *&x。
实例:
输入x和y 两个整数,然后将其中的值大的赋值给 x,小的赋值给 y。即:假设输入 x = 8,y = 9。就将 9 赋值给 x,8 赋值给 y。
#include<stdio.h>
int main(){
int x, y;
int *px,*py;
int t;
scanf("%d",&x);
scanf("%d",&y);
px = &x;
py = &y;
if(*px <*py){
t = *px;
*px = *py;
*py = t;
}
printf("x = %d, y=%d",*px,*py);
return 0;
}
结果显示:

- 指针的初始化
指针变量与其他变量一样,在定义时可以赋值,即初始化。也可以赋值“NULL”或“0”,如果赋值为“0”,此时的“0”含义并不是数字“0”,而是Null的字符码值。
int x;
int *px = &x; //利用取地址获取x的地址,在指针变量px定义时,赋值给px
- 指针运算
3.1 赋值运算
指针变量可以相互赋值,也可以赋值某个变量的地址,或者赋值一个具体的地址。
int *px, *py, *pz, x = 10;
px = &x;//赋予某个变量的地址
py = px;//相互赋值
3.2 指针与整数的加减运算
指针变量的自增自减运算,指针加1或减1运算,表示指针向前或向后移动一个存储单位(不同类型的指针,存储单位不同)。
指针变量加上或减去一个整型数,具体加几就是向前移动几个单元,减几就是向后移动几个单元。
int x, y, z;//定义三个变量,假设他们地址是连续的,分别为400,404,408
pz = 4000;//赋值具体的地址
int *p1 = Null, *p2 = 0; //定义指针变量,分别赋值Null和0
int *px = &x;//定义一个指针,指向x
printf("x = %d",*px);//因为px指向x,所以*px = x
px + 1;//表示向前移动一个存储单元
printf("y = %d",*(px+1));//获取px指针下一个存储单元的内容
3.3 关系运算
假设有指针变量 px, py。
px > py 表示 px 指向的存储地址是否大于 py 指向的地址
px == py 表示 px 和 py 是否指向同一个存储单元
px == 0 和 px != 0 表示 px 是否为空指针
int num[2] = {1, 3};
//将数组中第一个元素地址和第二个元素的地址赋值给 px、py
int *px = x[0], *py = x[1];
int *pz = x[0];
int *pn;
if(py > px){// py > px
printf("py 指向的存储地址大于 px 所指向的存储地址");
}
if(pz == px){ //pz 和 px 都指向 x[0]
printf("px 和 pz 指向同一个地址");
}
if(pn == NULL || pn == 0){//pn 没有初始化
printf("pn 是一个空指针");
}