c 值传递和引用传递,谁能说一下C语言参数传值和传引用是什么概念谢谢

1,谁能说一下C语言参数传值和传引用是什么概念谢谢你好,首先纠正一下你的一个错误,C语言里没有引用的概念 。引用就是一个别名 , 定义一个变量a,再定义一个引用c,即 int &c = a;就是给a变了个别名,实际上是一个实体 。传值就是将变量的值复制一遍,在函数调用栈上使用,还有一个传指针,即传变量地址,就是将变量的地址传到函数栈上去,这样 , 函数在栈上执行对该变量的操作都会直接操作到原变量的值 。传引用和传指针都能直接改变原变量的值,而传值不能修改原变量,只能修改它们的复制品(即在栈上建立的变量并被赋予了传进来的变量的值);C语言只能“参数传值”,没有“引用传递” 。C++有引用传递 。传值就是传递值,引用传递就是传地址,可以形实参数可以同步变化 。你好!传值只是把这个变量的值赋给形参,改变形参的值,实参不变 。传引用时改变形参,实参也会改变 。希望对你有所帮助,望采纳 。
2 , C语言中的值传参和引用传参分别是指什么在C语言中其实没有引用传参,都是值传参 。即传递的都是实参的副本 。如下示例 , //交换两个参数的值,值传参void swap(int x, int y) int temp = x; x = y; y = temp;}int a = 2, b =1;swap(a,b); //a,b的值不会改变,因为改变的是实参a,b的副本 。另一个示例://所谓的“引用传参” , 交换两个数值void swap(int *x, int *y) int temp = *x; *x = *y; *y = tem;}int a =2, b = 1;swap(&a, &b);//a,b的值改变其实这里引用传参,传递的也是参数的副本,只是这个副本是变量a,b的地址,所以你在函数swap中你并不能通过参数改变变量a,b的地址 , 因为它只是一个副本 , 是值传递 。但你得到变量的地址,你就可以访问和改变变量的内容,所以在第二个swap函数中,你可以通过*x和*y来改变实参的值 , 从而可以达到交换变量a,b值的效果 。但这并不是引用传递 。只是有这样的说法 。推荐你去秒秒学上看看相关的内容,我也是从那上面学来的 。【c 值传递和引用传递,谁能说一下C语言参数传值和传引用是什么概念谢谢】
3,C值传递和引用传递的理解说到参数传递,必须得弄清值类型和引用类型:(为了容易表达,我暂且命名存放在堆中的内容为堆中对象,存放在栈上的内容为栈中对象 。)值类型存放在栈中,直接访问 。如果有:int a=0;int b=a;就产生了两个栈中对象 。引用类型需要在堆中显式分配 , 且不能直接访问,需要在栈中分配一个栈中对象(C++叫指针,C#叫引用)指向其堆中对象 。如果:StringBuilder strb = new StringBuilder();StringBuilder strb2 = strb;则在堆中只有一个堆中对象,只是栈中有两个栈中对象指向堆中对象 。可以看出:每个变量都是一个栈中对象 。不管是值类型还是引用类型,只是值类型的栈中对象就是其内容,而引用类型的栈中对象只是一个指向堆中对象的地址 。判断是值类型还是引用类型:int a1 = 10;StringBuilder strb1 = new StringBuilder("ABC");int a2 = a1;StringBuilder strb2 = strb1;bool bl1 = object.ReferenceEquals(a1,a2); //false为值类型(因为值类型要装箱)bool bl2 = object.ReferenceEquals(strb1,strb2); //true为引用类型参数传递分值传递和引用传递两种 。通常,在没有显式指出ref和out时都是值传递 。值传递:传的是对象的值拷贝 。(即函数内参数对象是调用时传递对象的栈中对象的拷贝 。)引用传递:传的是栈中对象的地址 。(即函数内参数对象与调用时传递对象完全是同一栈中对象 。)现在用例子来说明传值跟传地址的不同:private void button2_Click(object sender, System.EventArgs e)StringBuilder strb1 = new StringBuilder();StringBuilder strb2 = new StringBuilder();Test1(strb1);Test2(ref strb2);string str1 = strb1.ToString(); //str1值:"A"string str2 = strb2.ToString(); //str2值:"BC"}void Test1(StringBuilder strb)//strb和strb1是两个栈中对象,但指向相同的地址,这个操作是改变堆中对象strb.Append("A");//这里将strb指向一个新的堆中对象,所以后面的操作与strb1指向的栈中对象无关strb = new StringBuilder("B");strb.Append("C");}void Test2(ref StringBuilder strb)//这里的strb和strb2是同一个栈中对象,所以改变strb的值使其指向另一个对象也等于改变strb2strb = new StringBuilder("B");strb.Append("C");}
4,C中的值传递和引用传递是什么C#值类型数据直接在他自身分配到的内存中存储数据,而C#引用类型只是包含指向存储数据位置的指针 。基础数据类型(string类型除外):包括整型、浮点型、十进制型、布尔型 。整型包括:sbyte、byte、char、short、ushort、int、uint、long、ulong 这九种类型;浮点型就包括 float 和 double 两种类型;十进制型就decimal ;布尔型就是 bool 型了 。结构类型:就是 struct 型 。枚举类型:就是 enum 型 。引用类型有五种:class、interface、delegate、object、string引用类型作为参数时:1、在修改变量本身时,结果类似于值传递,即不会改变传递前的变量的值2、在修改变量的属性或字段时 , 才是引用传递 , 会影响到传递前的变量的值3、参数使用了ref后,才是真正的引用传递,不管修改变量本身还是修改变量的属性或字段,都会影响到传递前的变量的值值传递:传的是对象的值拷贝 。(即函数内参数对象是调用时传递的对象的栈中对象的拷贝 。)引用传递:传的是栈中对象的地址 。(即函数内参数对象与调用时传递的对象完全是同一栈中对象 。)在Java中:1. 基本类型和基本类型变量被当作参数传递给方法时 , 是值传递 。在方法实体中 , 无法给原变量重新赋值,也无法改变它的值 。2. 对象和引用型变量被当作参数传递给方法时,是引用传递 。在方法实体中,无法给原变量重新赋值,但是可以改变它所指向对象的属性 。和c#中的一样 , 只不过Java中没有ref, out等关键字说到参数传递,必须得弄清值类型和引用类型:(为了容易表达,我暂且命名存放在堆中的内容为堆中对象,存放在栈上的内容为栈中对象 。)值类型存放在栈中 , 直接访问 。如果有:int a=0;int b=a;就产生了两个栈中对象 。引用类型需要在堆中显式分配,且不能直接访问,需要在栈中分配一个栈中对象(c++叫指针 , c#叫引用)指向其堆中对象 。如果:stringbuilder strb = new stringbuilder();stringbuilder strb2 = strb;则在堆中只有一个堆中对象,只是栈中有两个栈中对象指向堆中对象 。可以看出:每个变量都是一个栈中对象 。不管是值类型还是引用类型,只是值类型的栈中对象就是其内容,而引用类型的栈中对象只是一个指向堆中对象的地址 。判断是值类型还是引用类型:int a1 = 10;stringbuilder strb1 = new stringbuilder("abc");int a2 = a1;stringbuilder strb2 = strb1;bool bl1 = object.referenceequals(a1,a2); //false为值类型(因为值类型要装箱)bool bl2 = object.referenceequals(strb1,strb2); //true为引用类型参数传递分值传递和引用传递两种 。通常,在没有显式指出ref和out时都是值传递 。值传递:传的是对象的值拷贝 。(即函数内参数对象是调用时传递对象的栈中对象的拷贝 。)引用传递:传的是栈中对象的地址 。(即函数内参数对象与调用时传递对象完全是同一栈中对象 。)现在用例子来说明传值跟传地址的不同:private void button2_click(object sender, system.eventargs e)stringbuilder strb1 = new stringbuilder();stringbuilder strb2 = new stringbuilder();test1(strb1);test2(ref strb2);string str1 = strb1.tostring(); //str1值:"a"string str2 = strb2.tostring(); //str2值:"bc"}void test1(stringbuilder strb)//strb和strb1是两个栈中对象 , 但指向相同的地址,这个操作是改变堆中对象strb.append("a");//这里将strb指向一个新的堆中对象 , 所以后面的操作与strb1指向的栈中对象无关strb = new stringbuilder("b");strb.append("c");}void test2(ref stringbuilder strb)//这里的strb和strb2是同一个栈中对象,所以改变strb的值使其指向另一个对象也等于改变strb2strb = new stringbuilder("b");strb.append("c");}5,在c语言编程中传值方式和传引用方式之间有什么区别传值方式:当一个函数是传值方式的时候,你调用这个函数的时候传入的实参的值会被拷贝到形参,但是形参与实参之间并没有什么联系,比如变量b=5,a=b;这个时候将b赋值给a,他们的值相等,但是当这以后无论a的值怎么改变都不会影响到b,b=5,a=b;a=1;这时候b依然是5,这就是传值方式#include<stdio.h>void add(int a,int b)a=a+b;//改变了形参a的值return a;}void main()int a=1,b=2;printf("%d\n",add(a,b));//3printf("%d\n",a);//1printf("%d\n",b);//2}传引用方式:当你调用一个函数时 , 传入的是实参的地址的时候,这时候修改形参,实参也会受到影响,不过这种传地址某种意义是传值,首先将实参的地址拷贝到形参 , 他们两个以后就没有关系了 , 你也可以改变形参保存的地址 , 实参的地址不会改变,但是你操作的是形参对应地址的内容,与实参对应地址的内容一致,操作是同一个对象,所以形参对这个地址的操作,在实参那里也会看到效果#include<stdio.h>void add(int *a,int *b)*a=*a+*b;//改变了形参a的值return *a;}void main()int a=1,b=2;printf("%d\n",add(&a,&b));//3printf("%d\n",a);//3printf("%d\n",b);//2}在C语言中,并没有引用的概念,这个是C++的概念 。在C++的函数参数中,有两种形式,其中TYPE&var的形式 , 称为传引用方式;TYPEvar的形式,称为传值 。二者的区别为,当传引用时,实际传到函数中的形参,是实际参数的一个引用,而不是仅传递值到函数中 。具体的表现有以下几条:1传引用时,形参和实参是同一个变量,即使用相同的内存空间,二者有相同的地址 。而传值时二者地址不同;2传引用时,由于没有新建变量,所以对于类对象参数,不会产生构造和析构 。而如果是传值调用,调用时会进行构造,退出函数时会进行析构;3由于传引用使用的是原本实参的地址,所以对引用参数值的修改,会在退出函数后体现在主调函数中 , 而传值调用对参数的修改不会影响到主调函数 。你应该知道什么是引用吧,比如inta=1;int&b=a;这样就是引用,这样也表示a就是b,b就是a 。函数调用传参时 , 如函数B(intc),当调用函数B(a),这样就表示c=a=1;这样只是表示c的值为1,a只是给它赋值了,它只是等于1,与a没有关系了 。但是如果调用B(int&c);,这样就表示int&c=a=1;这样不仅仅表示c等于1了,因为是传引用,这样C就是a,a就是c , 你在函数B里面对c进行任何操作,同时对a也进行了相应的操作 。传值方式:当一个函数是传值方式的时候,你调用这个函数的时候传入的实参的值会被拷贝到形参 , 但是形参与实参之间并没有什么联系,比如变量b=5,a=b;这个时候将b赋值给a , 他们的值相等,但是当这以后无论a的值怎么改变都不会影响到b,b=5,a=b;a=1;这时候b依然是5 , 这就是传值方式#includevoid add(int a,int b) { a=a+b;//改变了形参a的值 return a; } void main() { int a=1,b=2; printf("%d\n",add(a,b));//3 printf("%d\n",a);//1 printf("%d\n",b);//2 } 传引用方式: 当你调用一个函数时,传入的是实参的地址的时候,这时候修改形参,实参也会受到影响,不过这种传地址某种意义是传值,首先将实参的地址拷贝到形参,他们两个以后就没有关系了 , 你也可以改变形参保存的地址,实参的地址不会改变,但是你操作的是形参对应地址的内容 , 与实参对应地址的内容一致,操作是同一个对象,所以形参对这个地址的操作,在实参那里也会看到效果 #include void add(int *a,int *b) { *a=*a+*b;//改变了形参a的值 return *a; } void main() { int a=1,b=2; printf("%d\n",add(&a,&b));//3 printf("%d\n",a);//3 printf("%d\n",b);//2 }

    推荐阅读