原来指针这么简单?

前言

经过了一段时间的学习,终于学习到了C预压中第一块硬骨头指针,以下是我对于指针的一些剖析,全文2300左右,请耐心读完,保证你有收获。



1、指针是什么?

指针是什么呢?

指针理解的2个要点:

 1. 指针是内存中的一个最小的单元的编号,也就是指针

 2.我们平时口语中的指针,通常指的是指针变量,是一个用来存放内存地址的变量

总结:指针在计算机中就是地址,口语中的指针通常指的是指针变量。

下面我们再用硬件角度解读一下指针。

对于32位机器,假设有32跟地址线,那么假设每根地址线再寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0)

那么32跟地址线产生的地址就会是:

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

00000000 00000000 00000000 00000011

............

111111111 111111111 111111111 111111110

111111111 111111111 111111111 111111111

这里就有2的32次方个地址

每个地址表示一个字节,那我们就可以给2^32Byte == 4GB 的空间进行编址。

如果为64位机器就可以给2^64byte 空间。

同时我们可以这样理解内存

指针变量

我们通过&(取地址操作符)取出变量的内存的起始地址,把地址可以存放在一个变量中,这个变量就是指针变量。

#include<stdio.h>
int main()
{
	int a = 10;//在内存中开辟一块空间
	int* p = &a;//这里我们用&(取地址操作符)取出变量a地址,放在指针变量p里面

	return 0;
}

 总结:

  • 指针变量用来存放地址的变量。地址是唯一标识一个内存单元的
  • 指针的大小在32位平台是4字节的,在64位平台是8字节的。

2.指针和指针类型

  在接下来的模块中我们讲探讨一下:指针的类型

经过了这么长时间的学习我们都知道变量有不同的类型,包括整形,浮点型等等,那么指针到底有没有类型呢?

准确的来说:有的。

int* pi = NULL;

char * pc = NULL;

short* ps = NULL:

long* pl = NULL;

float* pf = NULL;

double* pd = NULL;

这里我们不难发现指针的定义方式是: type + * 

                                                             类型名 + 指针

那么这些指针类型的意义是什么呢?

接下来两个小知识点会详细的讲述指针类型的作用。

2.1指针 +- 整数

 结论:从这个具体的例子来看可以看出指针的类型会影响步长。

2.2指针的解引用

总结:通过这里我们不难发现指针变量的类型在解引用的时候决定了对指针解引用的时候有多大的权限(能操作几个字节)。 

 3.野指针

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

3.1野指针的成因

  1. 指针未初始化
  2. 指针越界访问
  3. 指针指向的空间释放

3.2如何规避野指针

1. 指针初始化

2. 小心指针越界

3. 指针指向空间释放即使置NULL

4. 避免返回局部变量的地址

5. 指针使用之前检查有效性

4. 指针运算

  • 指针+- 整数
  • 指针-指针
  • 指针的关系运算

4.1 指针+-整数

 指针加减整数在上面我们讲过,指针加一,回向后面走相应指针类型的大小

4.2 指针-指针

先说结论,利用指针减指针我们可以得到两个指针之间对应的元素。

代码演示:

#include<stdio.h>

int my_strlen(char* pc)
{
	char* start = pc;
	while (*pc != '\0')
	{
		pc++;
	}
	return pc - start;
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d ", len);
	return 0;
}

4.3 指针的关系运算

for(vp = &values[N_VALUES]; vp > &values[0];)
{
    *--vp = 0;
}
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
    *vp = 0;
}

标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与 指向第一个元素之前的那个内存位置的指针进行比较。

5.指针和数组

我们先看一个例子:

其中我们不难发现,数组名和数组的首元素地址相同。 

结论:数组名是数组首元素地址

int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是数组首元素的地址

6.二级指针

一级指针变量:存放变量地址的变量

二级指针变量 :存放一级指针地址的变量

 

7. 指针数组

指针数组这个词有点隐晦的含义。 想必大家都听过指针和数组,但是连起来什么呢? 这到底是个指针还是个数组?

答案:是一个数组,指针作为定语修饰数组,顾名思义一个存放指针的数组。

int* arr3[5];

 这个就是指针数组的格式。

 

 


总结

以上就是我对于指针学习一些浅薄的理解,如果大家有什么问题可以留言,小生看到一定积极回答。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值