C语言学习记录-12.26

学习内容:

1.规定指针只能指向数组后一个地址,而不能指向数组前一个地址

C语言学习记录-12.26_第1张图片
个人猜测,可能是错误的
在内存中,栈区从高地址向低地址扩展,数组从低地址像高地址扩展。上图可以看出,很可能你的arry[0](数组的第一个元素)就是栈区的顶部了,你数组前一个地址,再往低地址去,根本就不存在有这样一个内存地址,那你程序还跑啥。但是数组后一个地址是存在的,虽然可能会跨界访问让程序奔溃或死循环,但它最起码是存在的。

2.数组的本质

例子:arry[2] <--------> *(arry+2)

我之前感觉arry[2]就是为了方便,为了更好看,现在看来确实是这样的目的。那为何不一开始就把这个东西说明出来,反而让人更好理解?

简单来说,arry就是一个自带的指针变量(这样就可以少一句指针变量定义语句,好像不仅是可以好看,还能省事),当然,arry可以是x,可以是y,可以是任何名字,名字无关紧要,定义为指针变量就行。

3.n级指针

指针变量存储一个变量的地址
本身也是变量,也要为其分配内存地址
那就再创建一个指针变量存储这个指针变量的地址。

指针变量的数据类型为:”指向地址内的数据类型 + *
int *p =&a;
int * * pp=&p;
int * * * ppp=&pp;
int * * **pppp=&ppp;

有什么用呢?二级指针多,那一级指针的地址有什么用呢?

4.结构体传参要传结构体地址(及用指针)

参数传参也叫参数压栈,栈就是弹夹,数据就是子弹,先进而后出,后进而先出。
传值传参:本身要为形参分配内存地址,结构体一般很大,为其分配的地址很多,浪费,系统开销大。(见序号5的文章)

5.函数栈帧的创建与销毁

https://blog.csdn.net/qq_61635026/article/details/124384367
1)ebp和esp两个寄存器决定一个栈区的上下限,现在有共享单车,函数是共享ebp和esp来定位自己的区域大小和位置,一个函数用完给另一个函数用。
2)调用别的函数时,首先要保存目前这个函数的ebp下限(咱是共享的,没有多的寄存器,为了之后能返回),再把目前函数的esp上限当作调用函数的ebp下限。(装子弹,垒砖块)
3)形参区域居然在调用函数的区域之外,在主函数与调用函数区域中间,隔开二者。(本质还是地址的绝对直接访问,调用函数要访问在其之外的形参,只要将ebp地址加特定数值(类似”指针变量++“,加到形参的地址)就可以访问形参区域)
4)eax寄存器是独立于栈区之外的,用于各个函数传递数值。

总:
传值:为形参分配独立空间,eax寄存器来传值和返回值。
传址:直接用地址,该加几加几,减几减几,只要记住各自ebp下限(以此为参考地址加减),直接访问就行。

函数调用完,其地址内的内容没有被销毁,只是不要了,也没有啥影响,下次用这些地址,重新赋值修改就行了。

6.调试

  1. 调堆栈:看调用函数逻辑。
  2. 反汇编:看寄存器逻辑
  3. 内存窗口:看内存内容

学习产出:

  • CSDN 无技术博客1 篇

你可能感兴趣的:(c语言,学习,开发语言)