函数内存和传值
明确几点一 函数三要素名称 参数 返回值
二 名称就是函数空间的地址指向
参数在编译的时间就会定义好参数占用空间
返回值 最近源码看了看感觉 0 或者其他的返回值代表正确或者不同的好很多
值传递和地址传递
那个值传递导致交换失败的案例导致最后要用地址传递的例子就不写了。。。。。
说一下 看源码时候 形参知识点
首先形参所占用的空间是提前定义好的 多大就看前面的类型
形参不等于实参 只是单纯的拷贝 传递值拷贝值 传递地址拷贝地址但是要改变上层(调用函数)的数值必须地址传递
值传递
简单说就是 主要是保护 上层空间不想让下层空间修改数值 只能读(拷贝)不能改
地址传递
1 为了改变
2 如果直接值传递拷贝空间太大需要传递地址来节约内存
由于地址传递本来就有两种目的所以问题就出在怎么才能从源码的形参中看出函数的目的?
1:我就看看 不修改 用用不改变这种很好发现比如
主要用到的是 const比如
void copy (int &a ,const int &b) 这就是典型的 a 可以修改b 不能修改然后带着这个逻辑看源码。
2 空间传递(地址就是首地址 )而且改变
又分为两种: 字符空间(char *p和 const char * p) 和 非字符空间(不是 char *p和 const char * p 比如:unsignedchar *p)
首先字符空间如果需要修改很简单:
因为字符有其固定的结束标志0x00(8B) 要遍历很简单 比如传递过来是
void add(char *p )
{
int i = 0;
while(p)
{
//操作即可
i++
}
}
如果非字符空间呢? 他是没有固定的结束标志的? 那就是我们常见的传入其长度就可以
这种源码中很常见日常也很常见比如
void add (unsigned char*p, int num){
int i = 0;
for(i<num;i++)
{
//操作
}
}
在想一个问题 前面说过定义指针时候就确定了 指针的存取方式那这个函数 我岂不是不能传 int *p (int 存取是4字节 ) 每个都写一个?
为了减少这种不必要的麻
当调用一个函数时,系统会在栈上为该函数创建一个栈帧,用于存放函数执行过程中所需要的各种信息。 栈内存主要用于存储函数的局部变量、参数以及函数调用时的返回地址等。当一个函数被调用时,其局部变量会被分配在栈内存中。一旦函数执行完毕,这些局部变量所占用的内存空间就会被自动释放。 若函数有参数,会在栈帧中为这些参数创建副本。参数传递的方式会影响参数副本的创建过程。 栈帧存储参数、局部变量和返回地址,由编译器自动管理。 记录调用该函数的下一条指令地址,当函数执行完毕后,程序会依据这个地址返回到调用处继续执行。 当函数返回时,其栈帧会被自动释放,局部变量也随之消失。 适用于不需要修改实参的情况,安全性高但可能效率低。 函数参数传递主要有两种方式:传值和传址(通过指针实现)。 全局区/静态区的优点是它们提供了一种在多个函数之间共享数据的方式。然而,过多地使用全局变量可能会导致程序的模块化程度降低,增加调试和维护的难度。 在C语言中,函数的内存分配和参数传递机制是理解程序行为的关键,尤其在嵌入式开发或性能敏感场景中更为重要。 值传递是C语言中最基础的参数传递方式。在这种方式中,函数调用时实参的值会被拷贝一份传递给形参。这意味着函数内部对形参的任何修改都不会影响到实参。 堆内存的优点是它可以处理任意大小的内存请求,并且内存块可以长期存在,直到显式释放为止。但是,堆内存的管理相对复杂,需要程序员小心地处理指针和内存分配/释放操作,以避免出现内存泄漏、野指针等问题。 值传递是C语言中最基础的参数传递方式。在这种方式中,函数调用时实参的值会被拷贝一份传递给形参。这意味着函数内部对形参的任何修改都不会影响到实参。 所有参数传递均为传值 传址调用是指将实参的地址传递给形参。在函数内部可以通过指针操作来修改实参的值。 通过指针可间接修改原变量。 误用传值导致数据隔离、返回局部变量指针、未对齐参数引发性能问题。 函数内部对指针所指向的值的修改会反映到实参上。 每次函数调用时,编译器会在栈上创建一个新的栈帧(stack frame),用于存储该函数的局部变量、参数和返回地址。