指针初识(1)

7b1426743435453d90140b620c6465ce.png

一、指针是什么

在计算机中,指针式编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,降低至形象化的称为“指针”。意思就是他能找到以他为地址的内存单元。

内存:内存是电脑上特别重要的存储器,计算机上的所有程序都是在内存中运行的。所以为了有效使用内存,就把内存划分成一个个小小的内存单元,每个内存单元的大小是1字节。

为了能够有效访问的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为内存单元的地址。

电脑有32位地址线和64根地址线之分,一旦通电就有了正电(1)与负电之分(0)(电信号转化为数字信号)而这些数字信号就组成了一系列的0、1序列一共有2^32次方种可能。(32根地址线为例),这些序列就组成了内存编码,每个内存编码占一个字节。

总结:指针是个变量,存放内存单元的地址。(指针是用来存放地址的变量)

#include<stdio.h>
int main()
{
  int a=10;
  int* p=&a;//指针变量
  return 0;
}

这里我们能知道:

1、在32位的机器上,地址是32个0或1组成的二进制序列,那地址就要用4个字节的空间来存储,所以一个指针变量的大小应该是4个字节;

2、同样的在64位的机器上,地址是64个0或1组成的二进制序列,那地址就要用8个字节的空间来存储,所以一个指针变量的大小应该是8个字节。 

 

#include<stdio.h>
int main()
{
	printf("%d\n", sizeof(int*));
	printf("%d\n", sizeof(char*));
	printf("%d\n", sizeof(float*));
	printf("%d\n", sizeof(long*));
	printf("%d\n", sizeof(short*));
	return 0;
}

69e7199dc56e49de9731ab21c0f85378.png 

总结:

1、指针是用来存放地址的,地址是唯一标示一块地址空间的;

2、指针的大小在32位平台是4字节,在64位平台是8字节。

二、指针和指针类型 

指针也有其自己的指针类型

65c1a1916f0c4f51b096b2923de3b488.png

我们可以看到,既然指针类型的大小都为8,那为什么要区分呢?用一种通用的指针类型不行吗?

当然是不可以的,因为指针类型具有一定的实际意义,下面我们就来看一下指针类型的实际意义:

748ab6abe0974db39bb1705fc9f4c240.png 

不管是char*类型还是int*的指针都能够很好的存放好a的地址,那区别在哪里呢?

6e69d51212a94fec86cbf5fb1d2969d4.png 

 在这里我们打开调试窗口,输入&a就可以找到a的地址,是倒着读的11 22 33 44,然后我们借用操作后发现a的地址变为:00 00 00 00

4ae721a7e86c4f6e962dac588f5a2cf6.png

但是如果我们把指针类型改为char*的话 ,在进行解引用操作时,内存里的4个字节我们仅仅只操作了1个字节,这便是指针类型有区别的原因

3d37de69a2294e9182b2ea93b22ee7f6.png

指针类型的意义:指针类型决定了指针进行解引用操作时能够访问空间的大小的权限。比如:int*能够操作4个字节,short*能够操作2个字节等等。

除此之外指针类型还有一个意义:

指针+-整数

#include<stdio.h>
int main()
{
	int a = 0x11223344;
	int* p = &a;
	char* q = &a;
	printf("%p\n", p);
	printf("%p\n", p+1);

	printf("%p\n", q);
	printf("%p\n", q+1);
	return 0;
}

8213184ed98340788c2519197f36eafd.png 

在这里我们就可以很明显看到区别:前两个相差了4个字节而后面两个相差了1个字节

指针类型决定了指针走一步有多长(指针步长)比如:int* p;p+1-->4;char* p;p+1-->1

应用:我们可以把一个数组中的元素全部改成同一个值

#include<stdio.h>
int main()
{
  int arr[10]={0};
  int* p=arr;//数组名是首元素地址
  int i=0;
  for(i=0;i<10;i++)
  {
    *(p+i)=1;
  }
  return 0;
}

三、野指针 

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

野指针的成因:

1、指针未初始化

#include<stdio.h>
int main()
{
  int* p;//局部变量指针未初始化,默认为随机值
  *p=20;
  return 0;
}

 2、指针越界访问

#include<stdio.h>
int main()
{
  int arr[10]={0};
  int*p=arr;
  int i=0;
  for(i=0;i<=11;i++)
  {
    //当指针指向的范围超出数组arr的范围时,p就是野指针
    *(p++)=i;
  }
  return 0;
}

3、指针指向的空间释放举个栗子:

#include<stdio.h>
int* test()
{
	int a = 10;
	return &a;
}
//函数一结束开辟出来的a的空间就已经还给系统了,不属于我们当前编译器
int main()
{
	int* p=test();
	*p = 20;
	return 0;
}
//也就是说虽然地址已经保存了,但指针指向的位置不可知,电脑可能已经把他分配给别的数组了,不能随便修改了

如何避免野指针

1、指针初始化

2、小心指针越界

3、指针指向空间释放及时置NULL

4、指针使用之前检查有效性 

结语 :

本次分享就先到这里,相信大家通过这篇文章一定会有所收获。感谢大家的关注和观看!

 

 

 

 

 

 

 

 

 

 

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值