C语言进阶教程(函数参数的秘密)

举报
yd_274589494 发表于 2023/07/29 12:19:53 2023/07/29
【摘要】 @TOC 前言本篇文章带大家学习一下函数的参数,函数的参数有很多同学认为就是很简单的东西,但是里面却包含了非常多的知识。 一、函数参数会占用内存吗当你调用函数时,需要将函数参数的值传递给函数的形式参数。这个过程中,内存会被分配来存储传递的参数值。具体地说,对于基本数据类型的参数(如整数、浮点数等),其值会直接传递给函数,并在函数内部使用。而对于复杂数据类型的参数(如结构体、数组等),通常使用...

@TOC


前言

本篇文章带大家学习一下函数的参数,函数的参数有很多同学认为就是很简单的东西,但是里面却包含了非常多的知识。

一、函数参数会占用内存吗

当你调用函数时,需要将函数参数的值传递给函数的形式参数。这个过程中,内存会被分配来存储传递的参数值。具体地说,对于基本数据类型的参数(如整数、浮点数等),其值会直接传递给函数,并在函数内部使用。而对于复杂数据类型的参数(如结构体、数组等),通常使用指针或引用传递,将参数的地址传递给函数,在函数内部通过指针或引用访问参数的值。

内存的分配和使用是由编译器和操作系统管理的。在函数调用过程中,栈(stack)是通常用来存储函数参数的内存区域。当函数调用结束后,栈上的参数内存会被释放,可以用于其他函数调用或程序的运行。

需要注意的是,函数参数的内存占用是临时的,仅在函数调用期间有效。一旦函数调用结束,函数参数的内存将被释放,不再占用内存。

总结起来,函数参数在调用函数时会占用内存,但是这个内存占用是临时的,并在函数调用结束后被释放。

函数调用栈:

在这里插入图片描述

二、函数参数的求值顺序

下面给出一个程序:

#include <stdio.h>

int main(int argc, char** argv)
{
    int k = 1;
    printf("k = %d k = %d\n", k++, k++);

    return 0;
}

大家肯定都会认为结果就是1和2,其实结果并不是1和2。
结果和我们认为的是相反的,是2和1,那么这是为什么呢?

在C语言中,函数参数的求值顺序是未定义的。这意味着编译器可以根据需要按任意顺序对函数参数进行求值。

在你提供的示例代码中,printf函数的参数表达式中包含了两次k++操作。由于未定义的求值顺序,编译器可以按任意顺序对这两个k++进行求值。

在这种情况下,编译器选择先求值第一个k++,并将其值(1)传递给printf函数的参数。然后,编译器再求值第二个k++,将其值(2)传递给printf函数的参数。因此,结果显示为1和2。

需要注意的是,因为编译器的选择是未定义的,所以在实际编程中,应避免在函数参数中使用具有副作用的表达式,特别是多次使用同一个变量并改变其值。这样的代码会导致行为不确定,不同的编译器可能得到不同的结果。

总结起来,结果为1和2是由于函数参数求值顺序是未定义的。在实际编程中,应避免依赖于未定义的行为,并编写清晰、可预测的代码。

三、什么是函数调用栈

函数调用栈(Function Call Stack),也称为调用栈、执行栈或运行栈,是计算机程序在执行函数调用及返回时所使用的一种数据结构。它主要用于跟踪函数的调用关系、保存函数的局部变量和控制函数的执行流程。

函数调用栈是基于栈(Stack)数据结构实现的。栈是一种特殊的数据结构,遵循"后进先出"(Last-In-First-Out, LIFO)的原则。在函数调用栈中,每个函数调用都会创建一个新的栈帧(Stack Frame),即一个独立的区域。

当一个函数被调用时,它的参数、局部变量和返回地址等信息被存储在函数调用栈的栈帧中。栈帧的结构通常包括以下几个重要的部分:

1.返回地址(Return Address):指向调用函数的指令地址,用于在函数执行完后返回到正确的位置继续执行。

2.局部变量(Local Variables):存储函数内部定义的局部变量的空间。

3.参数(Arguments):存储传递给函数的参数值。

4.上一个函数的栈帧指针(Previous Frame Pointer):指向上一个函数的栈帧,用于函数返回时恢复上一级函数的上下文。

当函数调用结束时,它的栈帧会被弹出(出栈),同时控制权会返回到上一级函数的栈帧中继续执行。这个过程称为函数返回。

函数调用栈的管理和维护是由处理器、操作系统和编译器共同协作完成的。每个线程都有自己的函数调用栈,栈的大小是有限的,当递归函数层次太深或者占用的栈空间超过了限制,就可能引发栈溢出错误。

函数调用栈在程序执行期间发挥着重要的作用,它使得函数调用和返回能够正确执行,并提供了存储局部变量和管理函数执行流程的机制。

总结

本篇文章就讲解到这里,大家不仅仅是看文章更多的是需要去动手练习,这才是提高的方法。

大家可以关注微信公众号,资料源码等都在公众号中。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。