形参和实参的区别

形参和实参的区别

形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。

实参出现在主调函数中,进入被调函数后,实参变量也不能使用。

形参和实参的功能是作数据传送。发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。

1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。因此,形参只有在函数内部有效。 函数调用结束返回主调函数后则不能再使用该形参变量。

2.实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。

3.实参和形参在数量上,类型上,顺序上应严格一致, 否则会发生“类型不匹配”的错误。

4.函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化

5.当形参和实参不是指针类型时,在该函数运行时,形参和实参是不同的变量,他们在内存中位于不同的位置,形参将实参的内容复制一份,在该函数运行结束的时候形参被释放,而实参内容不会改变。
而如果函数的参数是***指针类型变量***,在调用该函数的过程中,传给函数的是实参的地址,在函数体内部使用的也是实参的地址,即使用的就是实参本身。所以在函数体内部可以改变实参的值。

#include <stdio.h>
#include <stdlib.h>
typedef struct nod{
    int data;
    struct nod *l,*r;
}List;

List *creat(List *root){
    root=(List *)malloc(sizeof(List));
    root->data=1;
    root->l=NULL;
    root->r=NULL;

    root->l=(List *)malloc(sizeof(List));
    root->l->data=2;
    root->l->l=NULL;
    root->l->r=NULL;

    root->r=(List *)malloc(sizeof(List));
    root->r->data=3;
    root->r->l=NULL;
    root->r->r=NULL;

    root->l->l=(List *)malloc(sizeof(List));
    root->l->l->data=4;
    root->l->l->r=NULL;

    root->l->l->l=(List *)malloc(sizeof(List));
    root->l->l->l->data=5;
    root->l->l->l->r=NULL;

    return root;
}

//
void LL1(List **p){
    List *q=(*p)->l;//这将是新树的根节点
    (*p)->l=q->r;
    q->r=(*p);
    (*p)=q;//重新指向当前子树根节点
}

List *LL2(List *p){ //改为void则编译不报错,但不能运行
    List *q=p->l;//这将是新树的根节点
    p->l=q->r;
    q->r=p;
    p=q;//重新指向当前子树根节点
    return p;
}

//a的值变化只在函数内部进行
void test1(int a){
    a++;
    printf("test1函数里面的 a 的值是:%d\n",a);
}

//里面的参数是形参
//用*a的目的就是改变实参的值
//这是一种引用调用机制,将实参的地址传递给形参,
//从表面上看是以实参变量取代形参,因此任何发生在形参上的改变实际上都发生在实参变量上。
void test2(int *a){
    (*a)++;
    printf("test2函数里面的 a 的值是:%d\n",(*a));
}
int main(){
    List *root=NULL;
    root=creat(root);

    printf("root           %d\n",root->l->data);
    printf("root->l->l     %d\n",root->l->l->data);
    printf("root->l->l->l  %d\n",root->l->l->l->data);

    //LL(&root->l);
    root->l=LL2(root->l);
    printf("\n\n");
    printf("root->l        %d\n",root->l->data);
    printf("root->l->l     %d\n",root->l->l->data);
    printf("root->l->r     %d\n",root->l->r->data);
    printf("\n\n");

    int a=0;//实参
    test1(a);
    printf("       函数外边 a 的值是:%d\n\n\n",a);


    test2(&a);
    printf("       函数外边 a 的值是:%d\n\n\n",a);
    return 0;
}

运行结果:

其他解答:::::
如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值。

这一节我们先来讲解C语言函数的参数,下一节再讲解C语言函数的返回值。

C语言函数的参数会出现在两个地方,分别是函数定义处和函数调用处,这两个地方的参数是有区别的。
形参(形式参数)
在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参。
实参(实际参数)
函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参。

形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。
形参和实参的区别和联系

  1. 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

  2. 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

  3. 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型。

  4. 函数调用中发生的数据传递是单向的,只能把实参的值传递给形参,而不能把形参的值反向地传递给实参;换句话说,一旦完成数据的传递,实参和形参就再也没有瓜葛了,所以,在函数调用过程中,形参的值发生改变并不会影响实参。

请看下面的例子:

#include <stdio.h>
//计算从m加到n的值
int sum(int m, int n) {
    int i;
    for (i = m+1; i <= n; ++i) {
        m += i;
    }
    return m;
}
int main() {
    int a, b, total;
    printf("Input two numbers: ");
    scanf("%d %d", &a, &b);
    total = sum(a, b);
    printf("a=%d, b=%d\n", a, b);
    printf("total=%d\n", total);
    return 0;
}

运行结果:
Input two numbers: 1 100↙
a=1, b=100
total=5050

在这段代码中,函数定义处的 m、n 是形参,函数调用处的 a、b 是实参。通过 scanf() 可以读取用户输入的数据,并赋值给 a、b,在调用 sum() 函数时,这份数据会传递给形参 m、n。

从运行情况看,输入 a 值为 1,即实参 a 的值为 1,把这个值传递给函数 sum() 后,形参 m 的初始值也为 1,在函数执行过程中,形参 m 的值变为 5050。函数运行结束后,输出实参 a 的值仍为 1,可见实参的值不会随形参的变化而变化。

以上调用 sum() 时是将变量作为函数实参,除此以外,你也可以将常量、表达式、函数返回值作为实参,如下所示:
total = sum(10, 98); //将常量作为实参
total = sum(a+10, b-3); //将表达式作为实参
total = sum( pow(2,2), abs(-100) ); //将函数返回值作为实参

  1. 形参和实参虽然可以同名,但它们之间是相互独立的,互不影响,因为实参在函数外部有效,而形参在函数内部有效。

更改上面的代码,让实参和形参同名:
纯文本复制

#include <stdio.h>
//计算从m加到n的值
int sum(int m, int n) {
    int i;
    for (i = m + 1; i <= n; ++i) {
        m += i;
    }
    return m;
}
int main() {
    int m, n, total;
    printf("Input two numbers: ");
    scanf("%d %d", &m, &n);
    total = sum(m, n);
    printf("m=%d, n=%d\n", m, n);
    printf("total=%d\n", total);
    return 0;
}

运行结果:
Input two numbers: 1 100
m=1, n=100
total=5050

调用 sum() 函数后,函数内部的形参 m 的值已经发生了变化,而函数外部的实参 m 的值依然保持不变,可见它们是相互独立的两个变量,除了传递参数的一瞬间,其它时候是没有瓜葛的。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
函数的形参实参是函数调用过程中的两个概念。 形参是在函数定义时定义的参数,它是函数内部使用的占位符。形参可以在函数定义时指定,用于接收传递给函数的实际参数值。形参是函数定义的一部分,它的作用域仅限于函数内部,函数外部无法访问。 实参是在函数调用时实际传递给函数的参数值。实参可以是常量、变量、表达式或函数等。实参的值可以在函数调用时指定,在函数内部可以通过形参使用实参的数值。实参可以是任意类型的数据。 形参实参之间的关系是通过函数调用来建立的。当调用函数时,实参的值被传递给形参,形成一一对应关系。形参将使用实参的数值执行函数内部的操作。 形参实参之间的区别主要有以下几点: 1. 定义位置不同:形参是在函数定义时指定的参数,实参是在函数调用时传递的参数。 2. 作用范围不同:形参的作用范围仅限于函数内部,而实参的作用范围可以是函数内部和外部。 3. 类型限制不同:形参可以指定特定类型或不限制类型,而实参必须与形参的类型匹配。 4. 值传递方式不同:对于值类型的形参,默认情况下是按值传递的,即在函数调用时创建形参的副本;而对于引用类型的形参,默认情况下是按引用传递的,即实参形参指向同一个内存地址。 总之,形参是函数定义时声明的占位符,实参是函数调用时传递的具体数值。通过函数调用,实参的值被传递给形参,从而实现函数的功能。形参实参是函数输入和输出的桥梁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心醉瑶瑾前

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值