一、什么是形参和实参
形参实参其实就是形式参数和实际参数。具体在代码中体现如下:如果我们有一个平方的自定义函数square,我们有:
#include<stdio.h>
int square(int x) { return x * x;}
int main() { int a = 0; scanf("%d", &a); printf("%d", square(a)); return 0;}
>>>416其中在调用函数square的时候把值传输给变量x的变量a就是实际变量,而变量x在调用函数之前并不会占用内存,因此在调用之前这个变量的存在形式都是“形式上”的,因此称作形式参数。
二、形参实参的相对关系
同时需要注意的是,参数的实际和形式并不是绝对的概念,事实上,同一个变量在不同调用层级中,可以同时作为上一层调用的形式参数和下一层调用的实际参数。实参和形参是通过函数调用的关系来确定的,一句话概括就是:
谁在函数的定义中接受值,对于这个函数就是形式参数。
谁在函数的调用中提供值,对于这个函数就是实际参数。
比如下面的这段代码:
#include<stdio.h>
int mul(int y) { return y * y;}
int square(int x) { return mul(x);}
int main() { int a = 0; scanf("%d", &a); printf("%d", square(a)); return 0;}
>>>416在main中调用sqaure时,a作为实际变量传输值给形式变量x,此时x对于square函数来说是形参。
在square中调用mul时,x作为实际变量传输值给形式变量y,此时x对于mul函数来说是实参。
三、实参传输的方式
1.传输值直接拷贝
对于绝大部分变量而言,调用函数传输的是值,传输到形式参数之后,形式参数会在栈内开辟新的存储空间,把值拷贝过去。他们分别占用独立的内存空间。
因此,对形式参数的修改仅限于形参自己的内存,改变形式参数的值并不会影响实际参数的值。
2.数组传递地址
数组是一个特例,在作为形式参数的时候会退化为指针,因为数组天生就是“通过地址访问”的数据结构。(之后设计指针的章节会介绍(这人又给自己挖坑了))
因此在数组作为形参并且需要遍历的时候,我们是需要把数组长度也作为形参进行定义的,因为在函数内部的数组实际上退化成了指针,是没法通过strlen或者sizeof求出长度的!
之后我们学到指针的时候也会发现,甚至有时候,需要把数组作为形式参数的时候,会直接把指针作为实际变量传输过去。(挖坑!)
下一篇讲作用域,参数的生命周期以及对应的内存存储区域。
部分疑问由gpt提供回答,如果有误恳请批评指出!!
部分信息可能已经过时











