指针总结_上

一、什么是指针?

指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。

简单的来说指针就是指向一个变量的存储地址,这个变量的类型可以使我们的内置类型(int,char,double,等等),也可以是我们自定义类型,对于指针的理解,我们可以将这个变量类比成一个人,指针保存的就是这个人的地址。假设我们有事情要找到这个人,接下来就会有两种可能性。①: 我们在路上无意中碰见了这个人,那么我就直接告诉他是什么事情。这种方法就是我们直接去使用这个变量的例子。 ②:我们没有碰见这个人,但是我们知道这个人地址,那么我们就可以根据这个地址去找到这个人,告诉他是什么事情。这种方法就是我们通过指针的解引用的操作,对这个变量进行操作。

二、指针的声明和使用
int main()
{
	//指针声明
	int* pa;
	char* pb; 
	int a = 10;
	char b = 'Z';
	//向指针中保存地址
	pa = &a;
	pb = &b; 
	//读取指针中的内容
	print("a = %d\n", *pa);
	print("b = %c\n", *pb);
	return 0;
}

我们先来介绍一下&

  • 对于所有学过C语言的人来说这个符号,可能有些人会说这不是按位且的操作符吗?没错,这个符号是按位且的操作符,但是在这里,他的用法不是按位且,而是取址符。我们来回想一下其实我们在很早开始学习的时候就接触这个操作符。例如我们的scanf语句的操作: scanf("%d", &a);。在这条语句的意思中,我们是为获取一个整型值来存到变量a中,所有我们要获取到a的地址,然后将这个数字存储到a所属的那片空间中。其实我们在看见这个符号的时候不用害怕,他要么就是按位且,要么就是一个取址符,对于取址符的理解,我们可以根据字面意思,取址取址就是为了获得一个地址,那么我们要将这个获取的地址保存在哪里,答案是地址要保存到指针里

指针的定义

  • 在前说到过,指针可以指任何类型,所有指针也有不同类型的指针,对于指针的定义我们可以根据上面的代码进行类比,上面的代码中我们又一个int类型的变量和char类型的变量,先看指向int类型的指针:int* pa = &a;首先我们要使用之前所提到的取地址操作符来获取a的地址空间,然后定义一个int * 类型来接收这个地址。在这里的星号就是指针的标志,只要是一个变量类型后面有一个星号,就代表这个变量所保存的是什么类型的指针。

指针的内容访问

  • 我们有了一个变量的内存地址,那我们有怎么去获得里面的地址所指的内容的,其实很简单,既然我们在定义变量的时候用了一个星号,那么我们在访问的时候就再给他一个星号来获得里面的内容,这个过程我们称之为解引用,就是解开内存里面存储的东西。

为什么会有不同类型的指针?

  • 了解计算机内存地址的都应该清楚,在计算机中的地址,如果是32位机器,那么地址就是一个8位的地址,如果是64位机器,那么就是一个16位的地址。地址的大小都是一样的(这里指地址的位数),为什么还会有不同的类型。对此我们要清楚,地址的大小一样,但是每一个所指的变量的大小是不一样,int类型四字节大小,char类型一字节大小。当我们使用指针去访问的是,我们要知道我们所能访问的地址位数的大小,不能我指向的是一个char类型的数据,但你却读取了4个字节内容,或者你是一个int的取又读取了1字节的内容,这些都是不合适的,所要我们的指针也是需要有自己的类型,来告诉编译器一次读取几个字节的内容。
三、指针的++与- -
  • 指针的++与- -其实也是很好理解,我们可以根据整数的++与- -操作,一个整数的++和- -就是将这个数字进行加一或者减一,在这里,我们就需要注意,指针++和- -也就是同理,不过这次我们操作的是地址,++就是我们将这个指针所指向的地址进行加一,但是这里的加一并不是给地址加一个一,而是给指针加一个所值类型的大小,例如:如果指针指向一个int类型的变量,++就是将地址移动4个字节的长度,- -也是同样的道理。

注意:在进行++和- -操作时要注意访问到非法的地址空间。

四、 指针的减法
  • 在这里指针的减法的使用需要有特定的条件。

假设我们有一个数组int arr[8],两个int类型的指针p1,p2
在这里插入图片描述
指针减法的使用条件

  1. 两个指针必须在同一片连续的空间中。
  2. 必须是高地址减低地址。

指针减法的结果是两个指针所差的元素个数

注意:指针间没有加法!!!

四、二级指针
  • 可能在学习的时候我们看一个星号就会感觉头疼,但是学习总是意外不断,不仅仅有一个星号的指针,还有两个星号的指针,这就是我们所说的二级指针,其实看见两个星号我们也不必担心,无非就是再给他两个星号去读取里面的内容。

如何产生二级指针

  • 我们之前说过指针可以指向任意的类型,当然这样包括指针自己本身,用一个指针,指向一个指针的地址。
int mian()
{
	int a = 10;
	int* p = &a;
	int** pp = &p;
	print("a = %p\n", *pp);
	print("a = %d\n", **pp);
	return 0;
}
  • 我们来看着一段代码,我们用了一个指针p指向了一个int类型的变量a,这个p指针是一个星号,这是我们之前所学习的一级指针,然后我们再定义一个指针pp指向了之前的p指针,这pp指针是两个星号,那么我们如何来看待这个两个星号,之前说过,指针要有自己的类型,那就是所指向的变量的类型加一个星号,这个指针指向的是一个int*类型,这就是一个星号的来源,紧接着,这个pp要证明自己是个指针,那就只能给自己再加一个星号。这就是为什么指向指针的指针有两个星号。

如何去读取二级指针的内容

  • 一级指针的访问是通过一次解引用就可以得到,因为就一个星号,二级指针的读取,就需要2次解引用操作,第一次解引用,我们获得了pp指针所指向的p所保存的内容,因为p里面保存是地址,所以我们也无法获得有效的数据,那么我们就再去解引用p所存储的地址所保存的内容,这样就得到了pp指针中的有效数据了。

在我们进行解引用的操作我们可以形象的比喻成一个加锁和解锁的过程,在我们声明的时候,一个星号代表这一个锁,但我们在使用指针的时候就需要开锁,我们需要再将这些星号还原,将这些锁逐个打开。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值