值传递与地址传递的区分

原来,其实函数在调用时是隐含地把实参a,b的值分别赋值给了x,y,之后在你写的Exchg1函数体内再也没有对a,b进行任何的操作了。交换的只是x,y变量。并不是a,b。当然a,b的值没有改变啦!函数只是把a,b的值通过赋值传递给了x,y,函数里头操作的只是x,y的值并不是a,b的值。这就是所谓的参数的值传递了。
}
输出的结果:
x=____, y=____
a=____, b=___:代码如下。
Exchg2(int *px, int *py)
{
int tmp=*px;
*px=*py;
*py=tmp;
print(“*px=%d,*py=%d\n”,*px,*py);
}
main()
我们先看Exchg3函数的定义处Exchg3(int &x,int &y)。参数x,y是int的变量,调用时我们可以像值传递(如:Exchg1(a,b); )一样调用函数(如:Exchg3(a,b); )。但是x,y前都有一个取地址符号&。有了这个,调用Exchg3时函数会将a,b分别代替了x,y了,我们称x,y分别引用了a,b变量。这样函数里头操作的其实就是实参a,b本身了,也就是说函数里是可以直接修改到a,b的值了。
哈哈,终于明白了,正是因为它隐含了那两个的赋值操作,才让我们产生了前述的迷惑(以为a,b已经代替了x,y,对x,y的操作就是对a,b的操作了,这是一个错误的观点啊!)。
三.函数参数传递方式之二:地址传递
继续——地址传递的问题!
看题二的代码:
Exchg2(int *px, int *py)
{
int tmp=*px;
四.函数参数传递方式之三:引用传递
看题三的代码:
Exchg3(int &x, int &y) //注意定义处的形式参数的格式与值传递不同
{
int tmp=x;
x=y;
y=tmp;
print(“x=%d,y=%d\n”,x,y);
}
main()
{
int a=4;
int b=6;
Exchg3(a,b); //注意:这里调用方式与值传递一样
int tmp;
tmp=x;
x=y;
y=tmp;
请注意在调用执行Exchg1函数的操作中我人为地加上了头两句:
int x=a;
int y=b;
这是调用函数时的两个隐含动作。它确实存在,现在我只不过把它显式地写了出来而已。问题一下就清晰起来啦。(看到这里,现在你认为函数里面交换操作的是a,b变量或者只是x,y变量呢?)
}
问:你认为这个函数是在做什么呀?
答:好像是对参数x,y的值对调吧?
请往下看,我想利用这个函数来完成对a,b两个变量值的对调,程序如下:
void main()
{
int a=4,b=6;
Exchg1 (a,b) //a,b变量为Exchg1函数的实际参数。
/ printf(“a=%d,b=%d\n”,a,b)
x=y;
y=tmp;
print(“x=%d,y=%d\n”,x,y);
}
main()
{
int a=4;
int b=6;
Exchg2(a,b);
Print(“a=%d,b=%d\n”, a, b);
}
输出的结果:
x=____, y=____
a=____, b=____
问下划线的部分输出的应是什么,请完成。
引用传递Exchg3(a,b)函数里是用a,b分别代替了x,y。函数里操作的是a,b
。
{
int a=4;
int b=6;
Exchg2(&a,&b);
Print(“a=%d,b=%d\n”, a, b);
}
输出的结果为:
*px=____, *py=____
a=____, b=____
问下划线的部分应是什么,请完成。
3.考题三:
Exchg2(int &x, int &y)
{
int tmp=x;
再看调用处:Exchg2(&a, &b);
它将a的地址(&a)代入到px,b的地址(&b)代入到py。同上面的值传递一样,函数调用时作了两个隐含的操作:将&a,&b的值赋值给了px,py。
px=&a;
py=&b;
呵呵!我们发现,其实它与值传递并没有什么不同,只不过这里是将a,b的地址值传递给了px,py,而不是传递的a,b的内容,而(请好好地在比较比较啦)
整个Exchg2函数调用是如下执行的:
px=&a; //
py=&b; //请注意这两行,它是调用Exchg2的隐含动作。
int tmp=*px;
*px=*py;
*py=tmp;
print(“*px=%d,*py=%d\n”,*px,*py);
这样,有了头两行的隐含赋值操作。我们现在已经可以看出,指针px,py的值已经分别是a,b变量的地址值了。接下来,对*px,*py的操作当然也就是对a,b变量本身的操作了。所以函数里头的交换就是对a,b值的交换了,这就是所谓的地址传递(传递a,b的地址给了px,py),你现在明白了吗?
最后对值传递与引用传递作一个比较:
1.在函数定义格式上有不同:
值传递在定义处是:Exchg1(int x, int y);
引用传递在这义处是:Exchg1(int &x, int &y);
2.调用时有相同的格式:
值传递:Exchg1(a,b);
引用传递:Exchg3(a,b);
3.功能上是不同的:
值传递的函数里操作的不是a,b变量本身,只是将a,b值赋给了x,y函数里操作的只是x,y变量而不是a,b,显示a,b的值不会被Exchg1函数所修改。
3.理解值传递的形式
看调用Exch1函数的代码:
main()
{
int a=4,b=6;
Exchg1(a,b) //这里调用了Exchg1函数
printf(“a=%d,b=%d”,a,b)
}
Exchg1(a,b)时所完成的操作代码如下所示。
int x=a;//←
int y=b;//←注意这里,头两行是调用函数时的隐含操作
下面请让我逐个地谈谈这三种传递形式。
二.函数参数传递方式之一:值传递
1.值传递的一个错误认识
先看题一中Exchg1函数的定义:
void Exchg1(int x, int y) //定义中的x,y变量被称为Exchg1函数的形式参数
{
int tmp;
tmp=x;
x=y;
y=tmp;
printf(“x=%d,y=%d\n”,x,y)
2.一个预备的常识
为了说明这个问题,我先给出一个代码:
int a=4;
int x;
x=a;
x=x+3;
看好了没,现在我问你:最终a值是多少,x值是多少?
(怎么搞的,给我这个小儿科的问题。还不简单,不就是a==4 x==7嘛!)
在这个代码中,你要明白一个东西:虽然a值赋给了x,但是a变量并不是x变量哦。我们对x任何的修改,都不会改变a变量。呵呵!虽然简单,并且一看就理所当然,不过可是一个很重要的认识喔。
1.考题一:程序代码如下:
void Exchg1(int x, int y)
{
int tmp;
tmp=x;
x=y;
y=tmp;
printf(“x=%d,y=%d\n”,x,y)
}
void main()
{
int a=4,b=6;
Exchg1 (a,b) ;
printf(“a=%d,b=%d\n”,a,b)
Print(“a=%d,b=%d\n”, a, b);
}
输出结果:
x=6, y=4
a=6, b=4 //这个输出结果与值传递不同。
看到没有,与值传递相比,代码格式上只有一处是不同的,即在定义处:
Exchg3(int &x, int &y)。
但是我们发现a与b的值发生了对调。这说明了Exchg3(a,b)里头修改的是a,b变量,而不只是修改x,y了。
}
我问:Exchg1 ()里头的printf(“x=%d,y=%d\n”,x,y)语句会输出什么啊?
我再问:Exchg1 ()后的printf(“a=%d,b=%d\n”,a,b)语句输出的是什么?
程序输出的结果是:
x=6 , y=4
a=4 , b=6 //为什么不是a=6,b=4呢?
奇怪,明明我把a,b分别代入了x,y中,并在函数里完成了两个变量值的交换,为什么a,b变量值还是没有交换(仍然是a==4,b==6,而不是a==6,b==4)?如果你也会有这个疑问,那是因为你跟本就不知实参a,b与形参x,y的关系了。
你不在机子上试,能作出来吗?你对你写出的答案有多大的把握?
正确的答案,想知道吗?(呵呵,让我慢慢地告诉你吧!)
好,废话少说,继续我们的探索之旅了。
我们都知道:C语言中函数参数的传递有:值传递,地址传递,引用传递这三种形式。题一为值传递,题二为地址传递,题三为引用传递。不过,正是这几种参数传递的形式,曾把我给搞得晕头转向。我相信也有很多人与我有同感吧?
*px=*py;
*py=tmp;
print(“*px=%d,*py=%d\n”,*px,*py);
}
main()
{
int a=4;
int b=6;
Exchg2(&a,&b);
Print(“a=%d,b=%d\n”, a, b);
合集下载

C语言中函数参数传递

C语言中函数参数传递

C语⾔中函数参数传递C语⾔中函数参数传递的三种⽅式(1)值传递,就是把你的变量的值传递给函数的形式参数,实际就是⽤变量的值来新⽣成⼀个形式参数,因⽽在函数⾥对形参的改变不会影响到函数外的变量的值。

(2)地址传递,就是把变量的地址赋给函数⾥形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,能改变函数外的变量的值。

(3)引⽤传递,实际是通过指针来实现的,能达到使⽤的效果如传址,可是使⽤⽅式如传值。

说⼏点建议:如果传值的话,会⽣成新的对象,花费时间和空间,⽽在退出函数的时候,⼜会销毁该对象,花费时间和空间。

因⽽如果int,char等固有类型,⽽是你⾃⼰定义的类或结构等,都建议传指针或引⽤,因为他们不会创建新的对象。

例1:下⾯这段代码的输出结果为:#include<stdio.h>void change(int*a, int&b, int c){c=*a;b=30;*a=20;}int main ( ){int a=10, b=20, c=30;change(&a,b,c);printf(“%d,%d,%d,”,a,b,c);return 0;}结果:20 30 30解析:1,指针传参 -> 将变量的地址直接传⼊函数,函数中可以对其值进⾏修改。

2,引⽤传参 -> 将变量的引⽤传⼊函数,效果和指针相同,同样函数中可以对其值进⾏修改。

3,值传参 -> 在传参过程中,⾸先将c的值复制给函数c变量,然后在函数中修改的即是函数的c变量,然后函数返回时,系统⾃动释放变量c。

⽽对main函数的c没有影响。

例2:#include<stdio.h>void myswap(int x, int y){int t;t=x;x=y;y=t;}int main(){int a, b;printf("请输⼊待交换的两个整数:");scanf("%d %d", &a, &b);myswap(a,b); //作为对⽐,直接交换两个整数,显然不⾏printf("调⽤交换函数后的结果是:%d 和 %d\n", a, b);return 0;}#include<stdio.h>void myswap(int *p1, int *p2){int t;t=*p1;*p1=*p2;*p2=t;}int main(){int a, b;printf("请输⼊待交换的两个整数:");scanf("%d %d", &a, &b);myswap(&a,&b); //交换两个整数的地址printf("调⽤交换函数后的结果是:%d 和 %d\n", a, b);return 0;}#include<stdio.h>void myswap(int &x, int &y){int t;t=x;x=y;y=t;}int main(){int a, b;printf("请输⼊待交换的两个整数:");scanf("%d %d", &a, &b);myswap(a,b); //直接以变量a和b作为实参交换printf("调⽤交换函数后的结果是:%d 和 %d\n", a, b);return 0;}第⼀个的运⾏结果:输⼊2 3,输出2 3第⼆个的运⾏结果:输⼊2 3,输出3 2第三个的运⾏结果:输⼊2 3,输出3 2解析:在第⼀个程序中,传值不成功的原因是指在形参上改变了数值,没有在实参上改变数值。

[总结]值传递、地址传递、引用传递的区别

[总结]值传递、地址传递、引用传递的区别

[总结]值传递、地址传递、引⽤传递的区别值传递、地址传递、引⽤传递的区别:============================值传递好⽐是你把⽂件复制⼀份,通过⽹络传给他,然后他可以在他本机上对⽂件做任何的修改,修改会保存下来,但是你机器上的⽂件不会发⽣任何的变化。

即形参与实参是两个不同的变量,各⾃占⽤不同的存储单元。

地址传递好⽐是你把⽂件在⽹络上的地址告诉他⼈,他⼈通过⽹络访问你机器上的⽂件,他可以对⽂件进⾏修改并保存,此时,⽂件的内容就会发⽣变化。

即形参与实参是相同的变量,占⽤同⼀段内存空间。

引⽤传递是变量的别名,对别名操作就是对变量本⾝操作。

==========================================================地址传递是通过把地址传递给函数,然后函数根据地址要对存储单元操作。

打个⽐⽅说:你告诉某⼈⼀个房间号,让他根据房间号去拿去东西。

交换⼆个数的理解:值传递没有办法交换两个数。

⽤地址传递可以实现。

打个⽐⽅说: 在两个房间门⼝有两个服务⼈员,房间⾥有⼀本书和字典。

现在要求交换这两件东西。

服务员就是地址,如果找到服务员,然后让她把东西拿出来和别⼀个房间交换。

这样达到了交换的⽬的。

地址传递能够实现交换的⽬的。

另⼀种⽅法:在两个服务⼈员中还有⼀个⼈是管理⼈员,如果管理⼈员让这两个服务员换⼀下位置,这样以后按服务员找各⾃房间的东西,也起到了交换的⽬的。

这是通过指针的指针来实现的。

以上⼆种情况是效率最⾼提第⼆种了。

第⼀种是交换房间的东西,⼈没有换。

第⼆种是交换⼈,东西没有换。

从以可以感性的知道,⽤指针操作会更快。

 例⼦:void GetMemory(char *p, int num){p = (char *)malloc(sizeof(char) * num);}void Test(void){char *str = NULL;GetMemory(str, 100); // str 仍然为 NULLstrcpy(str, "hello"); // 运⾏错误}这种情况下: p=str; 是值传递。

四《C语言程序设计》实验四选择结构程序设计实验目的1、掌握分支

四《C语言程序设计》实验四选择结构程序设计实验目的1、掌握分支

四《C语言程序设计》实验四选择结构程序设计一、实验目的1、掌握分支语句的格式和功能。

2、掌握选择结构的程序设计。

3、掌握分支结构的嵌套。

二、实验内容与要求1、编程,计算下列分段函数值:x2+3x-4,x<0且x≠-4f(x)= x2-6x+5,0=x<10且x≠1及x≠5x2-4x-1,其他要求如下:(1)用if语句实现分支。

自变量x与函数值均采用双精度类型。

(2)自变量x值从键盘输入,且输入前要有提示信息。

(3)数据的输出格式采用以下形式:x=输入值,f(x)=计算值(4)分别以-3.0,-1.0,0.5,1.5,2.5,3.5,4.5,5.5为自变量,运行该程序。

记录结果。

(5)源程序以sy4_1.c存盘。

2、编程,将一个百分制成绩转换成等级制成绩。

具体要求如下:(1)百分制与等级制的对应关系如下:(3)用键盘输入百分制成绩,输入前要有提示信息。

(4)要能判断输入数据的合理性,对于不合理的数据应输出错误信息。

(5)输出结果中应包含百分制成绩和成绩等级。

(6)分别输入成绩-10,99,60,85,70,101,45,运行该程序。

记录结果。

(7)源程序以sy4_2.c存盘。

三、思考题1、实现选择结构程序设计的方法有哪几种?各有什么特点?适用条件是什么?2、如何设置选择结构中的判断条件?它在程序设计中的意义何在?实验五循环结构程序设计(1)一、实验目的1、掌握循环的概念。

2、掌握三种常用的循环语句的格式和功能。

3、初步掌握循环结构的编程方法。

二、实验内容与要求1、编程,分别利用三种循环语句,求1+2+3+…50之和。

要求如下:(1)输出计算结果;数据的输出格式采用以下形式:1+2+3+…50=计算值(2)源程序分别以sy5_1.c、sy5_2.c、sy5_3.c存盘。

2、编程,穷举算法解百马百担问题(有100匹马驮100担货,大马驮3担,中马驮2担,两匹小马驮1担,问有大、中、小马各多少?)要求如下:(1)输出计算结果;在数据输出之前应有提示信息。

VB程序设计实验教案方媛

VB程序设计实验教案方媛

河西学院
教案
2015~2016学年第二学期
课程名称Visual Basic程序设计
授课教师
职称
教师所在单位信息技术与传媒学院
河西学院教务处制
注:表中()选项请打“√”。

授课时间顺序编号: 1
填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

填表说明:每项页面大小可自行添减。

调用函数时的三种参数传递方式(传值传引用传地址)

调用函数时的三种参数传递方式(传值传引用传地址)

调用函数时的三种参数传递方式(传值传引用传地址)在编程语言中,参数是在函数调用过程中传递给函数的值或变量。

参数传递方式可以分为传值、传引用和传地址三种。

1. 传值(Call by Value):参数按照值的方式进行传递,函数接收的是实际参数的一个副本。

在函数内部对参数的修改不会影响到原始的参数。

这是最常见的参数传递方式,在许多编程语言中都是默认的方式。

特点:-参数的值在函数内部是只读的,函数不会对原始的参数进行修改。

-通过副本传递参数,避免了对原始参数进行意外修改的风险。

优点:-参数的值是独立于函数之外的,可以保证函数的安全性和一致性。

-函数内部对参数的修改不会影响到原始的参数,避免了意外的副作用。

缺点:-对于较大的数据类型,由于需要复制参数的值,会消耗更多的内存和时间。

2. 传引用(Call by Reference):参数按引用的方式进行传递,函数接收的是实际参数的引用或指针。

在函数内部对参数的修改会影响到原始的参数。

在引用传递参数的语言中,使用引用的方式可以让函数修改原始参数的值。

特点:-参数在函数内部是可写的,可以对参数进行修改。

-函数通过引用访问参数,可以直接修改原始参数的值。

优点:-函数可以直接修改原始参数的值,方便了对参数的修改操作。

-不需要复制参数的值,减少了内存和时间的消耗。

缺点:-参数的值可以被函数随时修改,可能导致意外的副作用,使程序变得难以理解和调试。

-对于没有被传引用的参数,无法从函数内部访问到其值。

3. 传地址(Call by Address):参数按照地址的方式进行传递,函数接收的是实际参数的地址。

在函数内部对参数进行修改会影响到原始的参数。

传地址方式类似于传引用,不同之处在于传地址是通过参数的指针来修改参数的值。

特点:-参数在函数内部是可写的,可以对参数进行修改。

-函数使用指针访问参数,可以直接修改原始参数的值。

优点:-函数可以直接修改原始参数的值,方便了对参数的修改操作。

值传递与地址传递的区别

值传递与地址传递的区别

1.考题一:程序代码如下:void Exchg1(int x, int y){inttmp;tmp=x;x=y;y=tmp;printf(“x=%d,y=%d\n”,x,y)}void main(){int a=4,b=6;Exchg1 (a,b) ;printf(“a=%d,b=%d\n”,a,b)}输出的结果:x=__, y=__a=__, b=__问下划线的部分应是什么,请完成。

2.考题二:代码如下。

Exchg2(int *px, int *py){inttmp=*px;*px=*py;*py=tmp;print(“*px=%d,*py=%d\n”,*px,*py);}main(){int a=4;intb=6;Exchg2(&a,&b);Print(“a=%d,b=%d\n”, a, b);}输出的结果为:*px=__, *py=__a=__, b=__问下划线的部分应是什么,请完成。

3.考题三:Exchg2(int &x, int &y){int tmp=x;x=y;y=tmp;print(“x=%d,y=%d\n”,x,y);}main(){int a=4;int b=6;Exchg2(a,b);Print(“a=%d,b=%d\n”, a, b);}输出的结果:x=__, y=__a=__, b=__问下划线的部分输出的应是什么,请完成。

你不在机子上试,能作出来吗?你对你写出的答案有多大的把握?正确的答案,想知道吗?(呵呵,让我慢慢地告诉你吧!)好,废话少说,继续我们的探索之旅了。

我们都知道:C语言中函数参数的传递有:值传递,地址传递,引用传递这三种形式。

题一为值传递,题二为地址传递,题三为引用传递。

不过,正是这几种参数传递的形式,曾把我给搞得晕头转向。

我相信也有很多人与我有同感吧?下面请让我逐个地谈谈这三种传递形式。

二.函数参数传递方式之一:值传递1.值传递的一个错误认识先看题一中Exchg1函数的定义:void Exchg1(int x, int y)//定义中的x,y变量被称为Exchg1函数的形式参数{int tmp;tmp=x;x=y;y=tmp;printf(“x=%d,y=%d\n”,x,y)}问:你认为这个函数是在做什么呀?答:好像是对参数x,y的值对调吧?请往下看,我想利用这个函数来完成对a,b 两个变量值的对调,程序如下:void main(){int a=4,b=6;Exchg1 (a,b)//a,b变量为Exchg1函数的实际参数。

二级C语言分类模拟题543

二级C语言分类模拟题543(总分:64.00,做题时间:90分钟)一、选择题(总题数:40,分数:64.00)1.有以下程序:#include<stdio.h>#include<stdlib.h>void fun(double*p1,double*p2,double*s){s=(double*)calloc(1,sizeof( double));*s=*p1+*(p2+1);}main(){ double a[2]={1.1,2.2},b[2]={10.0,20.0},*s=a;fun(a,b,s);printf("%5.2f/n",*s);}程序运行后的输出结果是______。

(分数:1.00)A.21.10B.11.10C.12.10D.1.10 √解析:[解析] 本题考查把数组名作为函数参数,执行fun函数后,s的值并没有发生变化,仍然是指向a,所以输出结果为1.10,选项D正确。

2.以下关于C语言函数参数传递方式的叙述正确的是______。

(分数:1.00)A.数据只能从实参单向传递给形参√B.数据可以在实参和形参之间双向传递C.数据只能从形参单向传递给实参D.C语言的函数,参数既可以从实参单向传递给形参,也可以在实参和形参之间双向传递,可视情况选择使用解析:[解析] 数据只能由实参单向传递给形参称为“值传递”,而不能由形参传给实参,A选项正确;数组名、指针等作参数,实参传递给形参的是地址值,这样形参和实参就指向同一段内存单元,在函数体内对形参数据的改变也将影响到实参。

实参和形参之间不可双向传递,B、D选项错误。

数据不能从形参传递给实参,故C选项错误。

3.以下选项中关于C语言常量的叙述错误的是______。

(分数:1.00)A.所谓常量,是指在程序运行过程中,其值不能被改变的量B.常量分为整型常量、实型常量、字符常量和字符串常量C.常量可分为数值型常量和非数值常量D.经常被使用的变量可以定义成常量√解析:[解析] 此题考查的是常量和变量的定义,常量不是经常使用的变量,而是一个确定的数值,所以答案选择D。

按值传递和按地址传递

按值传递和按地址传递变量分为基本类型(值型)和引⽤类型变量. 基本数据类型包括数字,字符串,布尔,null,undefined这些, 引⽤数据类型包括object(Object,Array, RegExp, Date, Math...), 函数.如果将基本类型的值赋值给变量, 变量会将这个值的本⾝保存起来:var a = 123; // 将数值123赋给变量avar b = a; // 将变量a的值(数值123)赋给变量b此时如果将变量b⾃增操作, 变量a的值不会受到影响;b++;console.log(b); // 124console.log(a); // 123如果将对象赋值给变量, 实际上是把对象的引⽤赋值给了变量; 变量保存的只是对象在内存中的地址.var a = {x:1, y:3};var b = a; // 将对象的地址赋值给b上⾯的代码, 变量a和b都指向相同的地址, 也就是引⽤了同⼀个对象; 如果对b所引⽤的对象进⾏改变, 这⼀改变也会体现在变量a之中;b.x++;console.log(b.x); // 2console.log(a.x); // 2接下来看这段代码:var a = {x:1,y:2};var b = a; // b和a指向同⼀个对象a = {x:2,y:1}; // a重新赋值,指向另⼀个对象console.log(b.x);这段代码通过赋值运算符将a重新赋值, 于是a不再引⽤⼀开始的对象, a与b之间的联系被切断, 因此不会再互相影响.函数的参数(按值传递)ECMAScript中所有函数的参数都是按值传递的;function swap(a,b) {var tmp = a;a = b;b = temp;}var one = 1;var zero = 0;swap(one, zero);console.log(one, zero); // one与zero的值没有发⽣改变把函数外部的值赋值给函数内部的参数, 相当于把值从⼀个变量复制给另⼀个变量⼀样. 函数的参数a和b可以理解成函数的私有变量,它们被赋于了全部变量one和zero的值, 然⽽这两个函数内部变量赋值的改变影响不到全部变量one和zero.如果使⽤对象, 情况⼜会有所不同:function setName(obj) { = "Nicolas";}var person = new Object();setName(person);console.log();以上代码创建了⼀个对象, 将对象保存到变量person中. 变量person被传递到函数setName后被复制给了obj, 这⼀步可以理解成, 对象的引⽤地址被复制给了obj. obj和person引⽤了同⼀个对象. 于是, 当在函数内部为obj添加name属性后, 函数外部的person也会有所反映.有的⼈会认为如果把引⽤类型数据作为参数, 参数就是按引⽤传递的. 其实⽆论传递了什么, 全都是按值传递. 改写下上⾯的代码:function setName(obj) { = "Nicolas";obj = new Object(); = "Greg";}var person = new Object();setName(person);console.log(); // "Nicolas"这个例⼦中在函数内部创建了⼀个新的object对象并将name属性设置为"Greg", 如果person是按引⽤传递的, person就会被修改了name属性为"Greg"的新对象; ⽽事实上并没有. 说明即使在函数内部修改了参数的值, 也影响不到原始引⽤. 实际上函数内部重写的obj是引⽤了⼀个只在函数局部作⽤域中存在的对象, 函数执⾏完毕后这个对象就会被销毁.本⽂参考了javascript⾼级程序设计第3版和javascript编程全解(然⽽写得⽐原书乱多了...)。

C语言参数传递(值传递、地址传递)+二级指针

C语⾔参数传递(值传递、地址传递)+⼆级指针参数传递C语⾔参数传递⼀般分为:值传递和地址传递(本质上只有值传递)(注意:C语⾔中没有引⽤传递,C++才有引⽤传递,因为很多C语⾔环境是⽤C++编译器编译,使得C看起来⽀持引⽤传递,导致很多⽹上很多blog都把引⽤传递归为C语⾔参数传递的⼀类,当使⽤Microsoft Visual C++ 2010 Express或VC6之类的编译器时使⽤引⽤传递就⽆法编译通过)值传递:形参是实参的拷贝,改变形参的值并不会影响外部实参的值。

从被调⽤函数的⾓度来说,值传递是单向的(实参->形参)1 #include <stdio.h>23void swap(int x, int y);45 main()6 {7int a = 10, b = 20;89 swap(a, b);10 printf("a=%d\nb=%d\n", a, b);1112return0;13 }14void swap(int x, int y)15 {16int t;1718 t = x;19 x = y;20 y = t;21 }上述代码运⾏后a、b的值并未改变地址传递:形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本⾝进⾏的操作1 #include <stdio.h>23void swap(int *x, int *y);45 main()6 {7int a = 10, b = 20;89 swap(&a, &b);10 printf("a=%d\nb=%d\n", a, b);1112return0;13 }14void swap(int *x, int *y)15 {16int t;1718 t = *x;19 *x = *y;20 *y = t;21 }上述代码执⾏后a和b值交换,a=20、b=10易错点补充:1 #include <stdio.h>23void swap(int *x, int *y);45 main()6 {7int a = 10, b = 20;8int *pp = &a;9int *kk = &b;10 swap(pp, kk);11 printf("a=%d\nb=%d\n", *pp, *kk);1213return0;14 }15void swap(int *x, int *y)16 {17int *t;1819 t = x;20 x = y;21 y = t;22 }请读者想⼀下,上述代码执⾏后a和b的值是否交换,为什么?上述代码看起来像交换了指针pp和kk的指向,实际上并没有代码的运⾏结果a=10、b=20,运⾏结果是a和b的值并没有改变,因为这时使⽤的实参pp,kk是值传递,传递的是指针的值,以指针pp来说,指针的值是变量a的地址,指针的值传⼊后⽤形参int *x和int *y接收,这⾥x和pp虽然都指向变量a的地址,但指针x和pp⾃⾝的地址并不相同(意思是x拷贝了⼀份pp的值),意味着你能改变变量a的值,但是不能改变pp的值(这⾥与值传递相似)为了更加直观,清晰的看出值的交换,这⾥添加⼀些代码来显⽰内存和变量的值1 #include <stdio.h>23void swap(int *x, int *y);45 main()6 {7int a = 10, b = 20;8int *pp = &a;9int *kk = &b;1011 printf("a的地址%p----b的地址%p\n\n", &a, &b);12 printf("pp的值%p----kk的值%p\n", pp, kk);13 printf("pp的地址%p----kk的地址%p\n\n", &pp, &kk);14 swap(pp, kk);15 printf("a = %d\nb = %d", *pp, *kk);1617return0;18 }19void swap(int *x, int *y)20 {21int *t;2223 printf("x的值%p----y的值%p\n", x, y);24 printf("x的地址%p----y的地址%p\n", &x, &y);26 t = x;27 x = y;28 y = t;29 }从pp和x的地址可以看出,x和pp是两块不同的内存区域,x在swap函数内执⾏完后并不会对pp值产⽣任何影响,相当于复制了⼀份pp的值,如下图(灵魂画⼿已上线)传⼊指针的值虽然不能对指针的值进⾏修改,但是可以通过地址直接对a的值进⾏修改也可以实现交换,代码如下1 #include <stdio.h>23void swap(int *x, int *y);45 main()6 {7int a = 10, b = 20;8int *pp = &a;9int *kk = &b;1011 swap(pp, kk);12 printf("a = %d\nb = %d", *pp, *kk);1314return0;15 }16void swap(int *x, int *y)17 {18int t;1920 t = *x;21 *x = *y;22 *y = t;23 }传⼊指针的值和和传⼊变量的地址在数值上是⼀样的,但是⼀个是传值传递⼀个地址传递,如下图(灵魂画⼿已经上线)⼆级指针上⾯提到的参数传递⽅式有,传⼊变量的值,传⼊变量的地址,传⼊指针的值三种参数传递⽅式下⾯介绍第四种,传⼊指针的地址,上⾯第⼆种(传⼊变量的地址)和第三种(传⼊指针的值)传递⽅式使⽤的⽤来接收参数的形参都是int *类型的指针这⾥因为传⼊的是指针的地址,所以要使⽤⼆级指针int **x,因为传⼊的指针的地址,实现值的交换的⽅式就有两种⼀种是直接对变量的值进⾏修改,另⼀种就是对指针的值进⾏修改第⼀种:直接对变量值进⾏修改1 #include <stdio.h>23void swap(int **x, int **y);45 main()6 {7int a = 10, b = 20;8int *pp = &a;9int *kk = &b;11 swap(&pp, &kk);12 printf("a = %d\nb = %d", *pp, *kk);1314return0;15 }16void swap(int **x, int **y)17 {18int t;1920 t = **x;21 **x = **y;22 **y = t;23 }第⼆种:对指针的值进⾏修改1 #include <stdio.h>23void swap(int **x, int **y);45 main()6 {7int a = 10, b = 20;8int *pp = &a;9int *kk = &b;1011 swap(&pp, &kk);12 printf("a = %d\nb = %d", *pp, *kk);1314return0;15 }16void swap(int **x, int **y)17 {18int *t;1920 t = *x;21 *x = *y;22 *y = t;23 }注意swap函数⾥⽤int *来交换指针的值,⽽不能⽤int **来进⾏交换,读者可⾃⾏修改代码验证想⼀下为什么?下⾯是⼆级指针⽰意图(灵魂画⼿已上线)若有疑问,欢迎留⾔。

c语言复习

C 语言复习C 语言概述1. C 语言的关键字有哪些?作了关键字就不能做标识符(如变量名、数组名,函数名、结构体类型名)2.C 语言的运算符有哪些,掌握常用运算符的优先级、运算对象的个数及结合性。

参见附录3. C 语言是完全模块化和结构化的程序设计语言。

函数是 C 语言程序的基本单位,一个程序由一个或多个函数组成,其中必须有一个main ()函数(也只能有一个)程序从main ,()开始执行,执行完main()函数结束。

3. 4. 函数的首部:4. 5. 函数体:用花括号括起来,一般包括两部分:声明部分和执行部分。

5. 6. C 语言的每个语句和数据声明后面必须有一个分号。

7. C 语言本省没有输入输出语句,由库函数实现。

6.8. 了解运行C 语言程序的过程,理解“源程序”“目标程序”“可执行程序”“编译” 、、、、“连接”和“执行”的概念最简单的 C 程序设计掌握 C 语言的7.9 种控制语句(P70 页),包括各控制语句的使用方法和语法规范,掌握 1. switch 语句的用法,理解break 和continue 的区别并能准确运用。

2. 注意复合语句的概念和用法,注意在使用if,while,for 等控制语句时,一组语句是否加括号构成复合语句对语句执行顺序的影响。

3. 输入输出由库函数实现,故使用前要#include <stdio.h> 4. 掌握单字符输入输出函数putchar()和getchar()函数的调用方法。

5. 掌握格式化输入输出函数printf()和scanf()的调用方法。

掌握常用的格式说明符的功能和规则。

6. printf()中双括号括起来的内容除了%d 等格式说明符外,其他字符原样输出,同样,格式化输入函数scanf()中双引号括起来的内容除了%d 等格式说明符外,其他字符照原样输入。

特别注意在输入数据时格式要和scanf 中设定的格式说明符匹配。

算法1. 2. 3. 4. 5. 什么是算法?什么是数据结构?掌握求阶乘、判断闰年和判断素数的算法 C 语言程序的 3 种基本结构:顺序、选择和算法的表示:了解流程图法和N-S 图法了解结构化程序设计思想。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档