用一把王者的时间带你了解指针

对于学习C语言来说,指针是始终绕不过的话题,因为指针的功能实在是太强大了,学会了指针你才能说你的C语言学的不错,正是指针功能的强大,才导致了指针的学习难度比较大,很多人对指针都是望而生畏,下面就让我来为大家介绍一些有关指针的知识,让大家对指针有一个了解。

1.什么是指针

指针就是地址!你可以想象这样一个场景,你上大学的时候要住校,那么在分配宿舍的时候给你分配到了807。对于计算机来说,创建变量就相当于分配宿舍,而宿舍门牌号就是对应宿舍所在的地方,也就是变量的地址,而这个地址的学名就叫做指针!

2.指针的产生原因:

前面我们说了指针是地址,那么指针究竟是怎么产生的呢? 说到指针的产生原因就不得不和稍微设计一些计算机组成原理的知识。我以32位机器为例,32位机器就有32根地址线。而地址线通了电以后就会有0和1两种不同的状态,0(低电平)和1(高电平)。

通电后,地址线就会产生如下的二进制序号:

00000000000000000000000000000000----->0

00000000000000000000000000000001---->1

........

1111111111111111111111111111111111111----->2^31-1

这些二进制序号的不同就构成了不同的门牌号,而这个门牌号就是计算机的内存单元的标识,也就是所谓的地址,而指针就是地址,所以这就是指针的由来。

3.指针的定义、大小及指针类型的意义:

我们了解了指针的产生的原因,那么我们应该怎么定义一个指针呢?这里就要介绍一个运算符:&

这个运算符在C语言的含义就是取出变量的地址,那么定义一个指针就可以如下的方式:

/*指针的定义:(类型名) * 变量名=&变量
以整型变量为例*/
int i=10;
int* pi=&i;

 *号声明变量是一个指针,int则是指针变量指向的元素类型,*号靠近变量名或者是靠近int都是可以的,个人 的习惯是*号靠近类型名。&i表示取出变量i的地址,将地址放到指针中合情合理!

那么可能就会有人好奇,指针既然是一个地址,那么它会不会有大小呢?它的大小又是多少呢?

答案是指针有大小,在C语言中可以通过sizeof()运算符计算指针的大小,程序如下:

#include<stdio.h>
int main()
{
    int i=10;
    int* pi=&i;
    printf("%d",sizeof(pi));
   return 0;
}

运行结果如下:

 可能你还会好奇,不同类型的指针会不会有不同的大小,我们可以写一个char类型的指针来打印一下它的大小:

#include<stdio.h>
int main()
{   
    char c='w';
    char* pc=&c;
    printf("%un",sizeof(pc));
    return 0;
}

运行结果如下:

 可以发现char类型的指针的大小也是4,为什会这样呢?这是我们就要和指针产生的原因联系起来了,因为指针是门牌号,而门牌号是32(64)根地址线通电产生的01序列组成的,因此指针的大小就是32个比特位或者是64个比特位,而sizeof()计算的是字节大小,1字节=8bit,所以指针的大小在32位平台就是4,在64位平台就是8。

指针的大小固定了,那么指针的类型又有什么特殊的意义呢?

来看下面这一段代码:

#include<stdio.h>
int main()
{  int i=0x11223344;
   int* pi=&i;
   *pi=0;
  return 0;
}

在内存窗口中打开,变量i的信息如下:

 运行到*pi=0之后,内存里i的情况如下:

 明显,四个字节的内容全被改成了0,那么我们这一次使用char类型的指针又会发生什么呢?

#include<stdio.h>
int main()
{
	int i = 0x11223344;
	char* pi =(char*)& i;
	*pi = 0;
	return 0;
}

运行*pi=0后,内存窗口里的结果如下:

 这里发现:只有第一个部分被改成了00,其他部分都没有变!为什么会出现这种现象呢?

这就是指针类型的意义!虽然指针的大小都是固定的数字,但类型的不同决定了它解引用能够访问几个字节的内容!

对于16进制数:11 22 33 44

在内存中的存储是用二进制存储,而二进制表示太长了,因此我们通常用16进制的方式表达:4位2进制就是一个16进制。

在内存中存储的是 44 33 22 11

对于pi,因为第一个pi是指向int类型的,所以说*pi一次可以访问4个字节,因此我们看到四个字节都被改成了0,而对于第二个pi是指向char类型的,*pi只能访问一个字节的内容,所以最后我们看到只有一个字节的内容被改成了00.

不止如此,指针的类型同样还决定了自增或自减一次跳过多少个对应类型的字节,这就是指针类型的意义!

4.使用指针的一些注意事项:

前面我们讲了指针的定义,指针的由来以及指针的大小和指针类型的意义,那么在使用指针的时候应该要注意以下几点:

1.指针一定要初始化!

指针一定要初始化,对于C语言来说,变量的初始化一直都是一个很重要的工作,对于指针变量同样也是如此,当你不知道指针该指向谁的时候记得让它指向NULL!

2.指针的乘除运算没有意义!

不要对两个指针进行乘除运算,因为这没有任何实际意义。对于两个指针加减和比较运算,如果指向的不是同一块连续空间也没有实际意义!

如:

int i=10;

int* pi=&i;

int j=5;

int* pj=&j;

pj-pi;//错误!两个不指向同一连续空间的地址相加没有任何意义!!11

3.注意指针的合法性:

这种情况多存在于数组越界以及动态内存分配的情况,数组越界自然不必多说,而动态分配再回收了内存空间以后,原来的空间我们就没有访问权限了,这是候我们就应该把指向原来空间的指针置空,防止它非法访问,这个在随后的动态内存分配的内容会深入探究。

总结:指针的内容还有很多,今天我讲的还只是冰山一角,希望我的讲解对大家学习指针有帮助。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>