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

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

前言

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

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

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

内存的分配和使用是由编译器和操作系统管理的。在函数调用过程中,栈(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):指向上一个函数的栈帧,用于函数返回时恢复上一级函数的上下文。

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

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

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

总结

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


相关文章
|
17天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
28 0
|
3天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
1天前
|
C语言
【C语言】字符分类函数与字符转换函数
【C语言】字符分类函数与字符转换函数
7 1
|
1天前
|
程序员 编译器 C语言
C语言之函数与参数
C语言之函数与参数
5 0
|
2天前
|
存储 算法 C语言
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
|
3天前
|
C语言
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
|
4天前
|
存储 C语言
C语言函数的返回值
C语言函数的返回值
7 0
|
4天前
|
C语言 Windows
C语言中的fopen与fclose函数详解
C语言中的fopen与fclose函数详解
11 1
|
4天前
|
C语言
深入理解C语言中的printf函数及数据输出
深入理解C语言中的printf函数及数据输出
13 0
|
17天前
|
程序员 C语言 开发者
C语言库函数 — 字符串函数(含模拟实现字符串函数)
C语言库函数 — 字符串函数(含模拟实现字符串函数)
36 0