C语言--深入理解指针

发布时间 2023-12-04 21:32:56作者: Bonne_chance

C语言--深入理解指针

一. 指针的概念

要知道指针的概念,要先了解变量在内存中是如何存储的。在存储时,内存被分为一块一块的,每一块都有一个特有的编号。而这个编号可以暂时理解为指针,就是酒店的门牌号一样。

  1. 变量和地址
    看下面代码
void main(){
  int x = 10, int y = 20;
}

代码中声明了两个变量x,y。把内存当做一个酒店,而每个房间就是一块内存。那么int x = 10;int y = 20;的实际含义是:去酒店订了两个房间,门牌号暂时用pxpy表示,让10住进px,让y住进py,其中门牌号就是px、py,也就是房间的地址。xy在这里可理解为具体的房间,房间x的门牌号(地址)是px,房间y的门牌号(地址)是py。而10和20,通过pxpy两个门牌,找到房间,住进xy

  1. 指针变量和指针的类型
    指针变量就是一个变量,存储的内容是一个指针。可以理解为指针变量就是一张房卡,房卡存储了房间号的信息。在定义一个变量的时候,要确定其类型,同样,定义指针变量时也是一样的,必须确定指针类型。int变量的指针需要用int类型的指针存储,float变量的指针需要用float类型的指针存储。就像你只能用酒店A的房卡存储酒店A中房间号的信息一样。

二. 变量的指针与指针变量

变量的指针就是变量的存储地址,指针变量就是存储指针的变量。

  1. 指针变量的定义及使用
    1.1 指针变量的定义

指针变量的定义形式:数据类型 *指针名
int *x;表示int类型指针变量x
float *t;表示float类型指针变量t
char *ch;表示char类型的指针变量ch

1.2 指针变量的使用
取地址运算符&:单目运算符&是用来取操作对象的地址。例如&i为取变量i的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。
指针运算符*(间接寻址符):与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例如 x=&ixi的地址,*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 赋值给 x8 赋值给 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;
}

结果显示:

  1. 指针的初始化

指针变量与其他变量一样,在定义时可以赋值,即初始化。也可以赋值“NULL”或“0”,如果赋值为“0”,此时的“0”含义并不是数字“0”,而是Null的字符码值。

int x;
int *px = &x; //利用取地址获取x的地址,在指针变量px定义时,赋值给px
  1. 指针运算
    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 表示 pxpy 是否指向同一个存储单元
px == 0px != 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 是一个空指针");
}