C语言指针-什么是指针,如何引用指针

C语言指针-什么是指针,如何引用指针

1.什么是指针

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元,编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号,在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。

​ 通过地址就能找到所需的变量单元,可以说,地址指向该变量单元,将地址形象化的称为“指针”,意思是通过它(指针)能找到以他为地址的内存单元。

比如:一个房间的门口挂了一个房间号2008,这个2008它房间的地址,或者说2008指向“该房间”。

注意:

对不同类型的数据,在内存中分配的存储单元大小(字节数)和存储方式是不同的,例如:整数以补码形式存放,实数以指数形式存放,如果指定地址1010,希望从该单元中调出数据,虽然可以找到指定的存储单元,但是无法确定是从一个字节中取信息还是两个字节取信息。为了有效存取一个数据,除了知道位置信息外,还需要该数据的类型信息,地址包括内存编号和它所指向的数据的类型信息或者说它是带“类型的地址”。例如:int a;&a表示变量a的地址,确切的说它是整型变量a的地址。

例如:

int a,float b;
分配到2000开始的存储单元中,&a和&b的信息不完全相同
虽然存储单元编号相同,但是他们的数据类型是不一样的

2.存储单元的地址和内容

假设定义了整型变量i,j,k,20002003分配给i;20042007分配给j;2008~2011分配给k;

一般是通过变量名来引用变量的值printf(“%d\n”,i);

在编译的时候,系统分配4个字节给i,并建立了变量名和地址的对应表,因此在执行上面语句时,从该4个字节中按照整型数据的存储方式读出整型变量i的值,然后按十进制整数格式输出。

注意:对变量的访问都是通过地址进行的

2.1直接访问和间接访问

打一个比方:

为了打开一个A抽屉,有两种办法,方法1是将A钥匙带在身上,需要时直接找出该钥匙打开抽屉,取出所需的东西,这就是“直接访问”,方法2是,为了安全起见,将A钥匙放到另一个抽屉B中锁起来,如果需要打开A抽屉,就需要先找出B钥匙,打开B抽屉,取出A钥匙,在打开A抽屉,取出A抽屉中的东西,这就是“间接访问”。

直接按变量名进行的访问,称为“直接访问

依然是上面的例子,如果输入

printf("%d",&i);
//在执行时,把键盘输入的值送到地址为2000开始的整型存储单元中国
k = i + j;
//从2000~2003字节取出i的值,再从2004~2007取出j的值,相加后送到k所占用的2008~2011字节单元中

如果是将变量i的地址存放到另一个变量中,然后通过变量来找到变量i的值,从而访问i变量的方式称为“间接访问”。

用一个来存放整型变量的地址

i_pointer = &i;
//把i的地址(2000)存放到i_pointer中
//i_pointer的值就是2000(即是变量i所占用单元的起始地址)
//间接访问i的值:
先找到存在“变量i的地址”的变量i_pointer,从中取出i的地址,然后在2000字节开始的存储单元中取出i的值

在这里插入图片描述

为了表示将数值为3送到变量中,有两种方式

(1)直接访问:将3直接送到变量i所标识的单元中,如i=3。这是根据变量名直接向变量i赋值,由于变量名与变量的地址有一一对应的关系,就按此地址直接对变量i的存储单元进行访问。

(2)间接访问:将3送到变量i_pointer所指向的单元(即变量i的存储单元),例如“*i_pointer = 3”,其中 *i_pointer表示i_pointer指向的对象。

在这里插入图片描述

指向就是通过地址来体现的,假设i_pointer中的值是变量i的地址(2000),这样就在i_pointer和变量i之间建立一种联系,即通过i_pointer能知道i的地址,从而找到变量i的内存单元。

​ 由于通过地址就能找到所需的变量单元,因此说,地址指向该变量单元(如同一个房间号指向某一房间一样),将地址形象的称为“指针”。意思是通过指针就能找到以它为地址的内存单元(如同根据地址2000就能找到哦啊变量i的存储单元一样)。

​ 如果有一个变量专门用来存放另外一个变量的地址(即指针),则称它为“指针变量”,i_pointer就是一个指针变量。指针变量就是一个地址变量,用来存放地址,指针变量的值是地址(即指针)。

即:指针是一个地址,而指针变量是存放地址的变量

3.指针变量

指针变量的定义:

存放地址的变量是指针变量,它是用来指向另一个对象(如变量,数组,函数等)。

例如:通过指针变量访问整型变量

#include<stdio.h>
int main()
{
	int a=100,b=10;//定义整型变量a和b,并且初始化
    int *p1,*p2;//定义指向整型数据的指针变量p1和p2
    p1 = &a;//把变量a的地址赋给指针变量p1
    p2 = &b;//把变量b的地址赋给指针变量p2
    printf("a=%d,b=%d\n",a,b);//输出ab的值
    printf("*p1=%d,*p2=%d\n",*p1,*p2);//输出变量ab的值
    return 0}

"*"表示指向

"*p1"表示指针变量p1所指向的变量,也就是变量a,

*p2同理。

 int *p1,*p2;//表示定义了两个指针变量
   printf("*p1=%d,*p2=%d\n",*p1,*p2);//表示指针*p1和*p2所指向的变量

注意:

在定义指针变量的时候,一定要指定指针变量的类型。

在这里插入图片描述

3.1定义指针变量

形式:

类型名 *指针变量名;
例如:
    int *p1,*p2;
//int是指针的基本类型,表示指针变量可以指向的变量的类型。
//*p1和*p2可以指向整型的变量i和j,不能指向浮点类型的a和b

注意:

(1)*表示该变量为指针型变量

(2)定义指针变量时候必须指定类型,因为不同数据类型在内存中所占的字节数和存放方式是不一样的。

(3)一个变量的指针包含两个方面:一是以存储单元编号表示纯地址,一是它指向的存储单元的数据类型(int,char等)

(4)指向整形数据的指针类型表示为"int *",读作指向int的指针或者简称int指针,其他类型的同理。

(5)指针变量中只能存放地址指针,不要将一个整数赋给一个指针变量,因为从形式上看整数只能赋给整形变量,而不能赋给指针变量,地址只能用地址符号"&"得到并赋给一个指针变量例如:”p=&a“;

3.2引用指针变量

熟练掌握运算符

(1)&,取地址运算符,&a是变量a的地址

(2)*,指针运算符(间接访问运算符)

(3)*p表示指针变量p指向的对象

(1)给指针变量赋值

p=&a;
//把a的地址赋值给p,指针变量p的值是变量a的地址,p指向a

(2)引用指针变量指向的变量

p=&a;
printf("%d",*p);//以整数形式输出指针变量p所指向的变量的值,即变量a的值
*p=1;//把1赋给p当前所指向的变量,相当于把1赋给a,即a=1

(3)引用指针变量的值

p = &a;
printf("%o",p);//以八进制数形式输出指针变量p的值,即输出a的地址

3.3编程:输入两个a和b两个整数,按先大后小的顺序输出a和b

方法一:用指针的方法处理这个问题,不交换整型变量的值,而是交换两个指针变量的值

#include<stdio.h>
int main()
{
	int *p1,*p2,*p;//定义的三个int*类型的指针变量 
	int a,b;
	printf("please input two number:");
	scanf("%d%d",&a,&b);
	p1 = &a;//p1指向a的地址 
	p2 = &b;//p2指向b的地址 
	if(a<b)
	{
		p=p1;
		p1=p2;
		p2=p;
        //可以不用定义中间变量
        //p1=&b;p2=&a
	}
	printf("a=%d,b=%d\n",a,b);
	printf("max=%d,min=%d\n",*p1,*p2);
	return 0;
 } 

方法二:利用指针作为函数参数

#include<stdio.h>
void swap(int *p1,int *p2){
	int temp;
	temp = *p1;
	*p1 = *p2;
	*p2 =temp;
} 
int main(void)
{
	int a,b;
	printf("please input two number:");
	scanf("%d%d",&a,&b);
	int *p1,*p2;
	p1 = &a;//把a的地址赋给p1
	p2 = &b;//把b的地址赋给p2
	if(a<b)
	{
		swap(p1,p2);
	}
	printf("a=%d,b=%d\n",a,b);
	return 0;
}

注意:

void swap(int *p1,int *p2){
	int *temp;//没有初始化,是野指针
	*temp = *p1;
	p1 = *p2;//‘int *’ from ‘int类型不匹配
	p2 =*temp;
} 
void swap(int *p1,int *p2){
	int *temp=NULL;//error
    //改为:
    //int *temp=(int *)malloc(sizeof(int));
	*temp = *p1;
	*p1 = *p2;
	*p2 =*temp;
} 

指针定义为NULL的时候,表示为空指针,指向的是一个零地址,零地址是没有存储空间的,指针指向零地址是不可用的,读写都不能,也不能访问。

malloc是在堆区连续的开辟空间,空间可以赋初值为0,但是它就不叫0地址,空间连续后是可以用的,0地址是没有连续空间的,所以是不能用的。

void swap(int x,int y)
{
    int temp;
    temp = x;
    x=y;
    y=temp;
}

函数调用时,a的值传给x,b的值传给y,x和y的值是交换了,但是a和b的值是没有交换的,因为在函数结束的时候,x和y释放了,形参的值并没有改变实参

在这里插入图片描述

如何调用函数得到要改变的值:

①通过形参改变实参,使用指针变量

②设计的函数的形参为指针类型的

void swap(int *p1,int *p2){
	int *temp=(int *)malloc(sizeof(int));
	temp = p1; 
	p1 = p2;
	p2 =temp;
} 

,b的值传给y,x和y的值是交换了,但是a和b的值是没有交换的,因为在函数结束的时候,x和y释放了,形参的值并没有改变实参

[外链图片转存中…(img-hNXi52xQ-1660563958276)]

如何调用函数得到要改变的值:

①通过形参改变实参,使用指针变量

②设计的函数的形参为指针类型的

void swap(int *p1,int *p2){
	int *temp=(int *)malloc(sizeof(int));
	temp = p1; 
	p1 = p2;
	p2 =temp;
} 

实参变量和形参变量之间的数据传递是单向的“值传递”,用指针变量作为函数参数也应该遵从这一规则。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最没脑子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值