Lead into

指针其实跟一些运算符的表达式类似(例如i++,i--),它通过符号隐藏了内部的计算过程,只要学习者逐步的分解开,就很容易理解了。学习指针的时候,尽量想象底层硬件的工作方式,也能有助理解。

为什么会觉得指针难?
因为指针在现在的高级语言上基本不使用了,不使用的东西就会觉得很遥远、很神秘且难。但是只要你经常使用C语言编程,你就不会觉得难。

Target

  • 理解指针的相关概念
  • 清楚理解值传递引用传递的区别
  • 什么场景下需要用到指针?
    • 引用传递
  • 早期的计算机硬件,为什么需要指针这种语法?
  • 理解指针变量、指针函数、指针参数

Concept

指针类型的声明

char *a;
char b = "B";
a = &b;

// print a
B

间接访问操作符

通过一个指针访问它所指向的地址的过程称为间接访问(indirection),或解引用指针(dereferencing the pointer)。

用于执行间接访问的操作符就是单目操作符* ,
单目操作符* 也有叫 间接运算符* 。

间接引用过程图:

图1


图2

指针类型的长度

口 = 1bit ;

指针类型的长度 = 4字节,
【口口口口 口口口口】
【口口口口 口口口口】
【口口口口 口口口口】
【口口口口 口口口口】

了解即可 。

Why do I need to transfer the length?

因为在C语言中,数组作为参数的时候,就是一个指针。
因此,在函数内,是不能通过sizeof( )之类的函数得到这个指针所指字符串的长度的,得到的只是指针变量的长度。必须也得将长度传输过去。

二维指针

以此类推,还有三维、四维指针;

就是指向指针的指针。

问题:二维指针在哪里能用到?
TODO

const修饰的指针

直接看: https://blog.51cto.com/waleon/5670923 (看 1. const属性 章节)
总结就是, 使用const修饰指针变量,这个指针地址不能改变了,但是,指针指向的内存地址,这个地址存储的数据是可以改变的。

C - Pointer arithmetic

先思考,指针运算都用在哪里?

  • 指针++,这种用在链式数组,可以向后读取数据。

example :
有一段字符串 ” ajskldjfklajdfl ” ,自定义一个函数统计出其中j字符在该字符串中所出现的次数。(使用指针的方式实现)

int Count(chat* p)
{
  int count = 0;
  for(int i=0; *(p+i)!='\0'; i++){
    if (*(p+i) == 'j'){
      count++;
    }
	}
	return count;
}

void main()
{
	char str[] = "ajskldjfklajdfl"
	printf("有几个j : %d", Count(str));
}

Whay need Point?

早期的电子设备是不需要指针的,当时的设备的内存极小,哪怕是到了现在,一枚ESP32-C3单片机的内存也才内置不过400 KB SRAM。当时的程序员们可以使用汇编直接控制寄存器,可是后来内存越来越大,直接控制寄存器就变得越来越麻烦,于是封装了“指针”这个抽象的概念用以进行间接寻址

指针让程序员得以从硬件中解放出来,却没有剥夺程序员们灵活自由控制内存的权力。自由控制内存权利这个东西,看给谁用,给优秀的人,就是锋利的工具,能锦上添花,给愚蠢的人,就会干出蠢事且危险失控的事。比如:

  • 用指针在堆内申请内存却忘了释放,造成内存泄漏;
  • 访问野指针造成预料之外的行为;访问空指针导致程序报错;等等

指针能提低内存消耗,高效率传输的案例:
假设你从内存中一次性读取了一个1GB的文件,哪么存放这些数据的变量也会消耗1GB的内存。姑且不论申请堆区内存和读取文件的部分,假如你需要写一个函数处理这些文件,如果不用指针的话,调用函数时会在内存中再拷贝一份数据成为函数内的临时变量,而这份拷贝同样会消耗1GB内存。如此庞大的内存消耗,作为存放在栈区的临时变量无疑会塞满栈区,并且因为塞不下而导致程序出错;哪怕没有出错,这么庞大的资源消耗也表明这是一个毫无优化的程序,用户体验极差。

虽然实际工程中会通过分块读写文件以降低资源消耗,但不可否认,没了指针哪怕分块读写都会消耗双倍内存。使用指针作为函数参数,可以让函数直接操作指针地址存放的数据,这种参数传递方式会在第三节进行介绍,名为指针传递

Function Pointer in C

函数指针也可以称为回调函数、指针函数...,那么是什么函数指针?

reference:
什么是函数指针
https://333rd.net/posts/read/什么是函数指针/

Reference

【C语言指针】三分钟理解C指针【动画展示】
https://www.bilibili.com/video/BV1YB4y1D7cS/?spm_id_from=333.337.search-card.all.click&vd_source=8b3d9b9c8dc3d45e894bef954677559d

【指针的秘密】这可能是最好懂的C语言指针讲解
https://www.bilibili.com/video/BV1V44y1Y7JS/?spm_id_from=333.337.search-card.all.click&vd_source=8b3d9b9c8dc3d45e894bef954677559d

指针的前世今生
https://333rd.net/posts/read/指针的前世今生/#12-内存的本质

C 指针 | 从底层原理到花式技巧(图文详解)
https://blog.51cto.com/waleon/5670923

posted on 2023-03-02 09:30  Mysticbinary  阅读(88)  评论(0编辑  收藏  举报