从c++,到java,再到javascript也谈函数的参数传递

函数在现在的编程语言教材里,占的分量不大,尤其是java语言的编程书籍,但我认为函数是程序开发的重要基石,真正弄懂了函数,才算真正的会编程,函数还没有真正弄明白,就先不要去搞什么io,gui,线程那些玩意,有些同学总说C++难学,其实是看见各种千奇百怪的函数原型,不知该如何调用,把函数真正搞明白了,再看联机手册,肯定不会再像天书难懂了。

先从c++说起,(c++和c语言语法上是有区别的,但也不大,但我是不太爱区分的,后缀名一般用cpp,仍用printf,少用cout,cin),也可以说先从C语言中的函数说起。如果说java代码是由类构成的,那么C语言就是由函数构成的。

         在我给学生讲解C语言的函数时,让学生记住3句话:

         1.函数的参数就是函数内部的变量(我上课时把变量叫做空间,目前正在编一本用空间讲述C,JAVA的教材,这篇文章的内容就是教材的一部分)。

         2.在调用的时候要给参数(这里可以换成变量或空间)赋值,记住是给函数内部的变量赋“值”,没有什么所谓“传址”,“传引用”,(c++中有引用,始终理解不好,所以不提倡使用,有指针足够用了,看了很多代码,引用很少有人用)

         3.在传递数组的时候,只是把数组的首地址传进去,不能把数组的每个值都传进去。传多维数组的时候除了第一维,其它维的长度一定要写在参数里。

      有函数如下:

      void exampleFunc(int a,int  b,int *c ,char d[],char e[][4])

        {

               int m=0;

               int n=0;

               m=a;

               b=n;                        //不会修改下面调用中传入的k

               *c=m;                   //会修改下面调用中的k的值,

               d[0]=(char)a;

               e[1][0]=n;

 

          }

    如果调用的话有如下代码:

    void testExampleFunc1()

     {

              int k=4;

              char e[][6]={"abc","edf"};

              char  h[]=“abcdef”;

              exampleFunc1(2,k,&k,h,e);

              int *p;

              p=&k;

              exampleFunc1(2,k,p,h,e);//如果你有一个指针p,当然可以把p的值直接传进去

              p=h;

              exampleFunc1(2,k,p,p,e);//指针p可以当数组传进去            

     } 

解释一下:

        1.参数里面的a,b,c,d,e和函数里的m,n一样都是函数内部的变量,在一个作用域里面,可以互相赋值,数组的写法和在函数里的写法不一样,这个第三条讲。这条虽然简单,但能消除你对参数的陌生和恐惧。

        2.在调用的时候,按照函数的类型依次传值进去,可以直接传入常量2到参数a,可以把k里的值复制到参数b里,c是指针型变量,需要一个地址,&k正好表示k的地址,如果你有一个指针p,当然可以把p的值直接传进去。剩下两个是数组,第三条讲。看似很简单,但是要注意“复制”这两个字,把一个变量传入到参数中,是把值复制进去,参数中的值无论怎么修改都不会改变传入的变量,要想通过函数修改变量怎么办,很简单把变量的地址传进去,变量的地址用什么存,指针,指针的内容能不能改呢,也能,把指针的地址传进去,用什么存,二阶指针,不管怎么说,都是复制值,只不过是不同的值,相同阶数的不同类型变量可以互相转换赋值,不同阶数的变量严格禁止转换赋值,所以传递参数时一定保证阶数匹配。

        3.d和e是两个数组型参数,传递时传首地址就行,h不用下标单独使用,就表示首元素的地址,和&h[0]的意思完全一样,参数里的数组和函数里定义的数组是完全不一样的,一定要主意,当然指针p也可以当数组传进去,想传递数组的时候,用个指针变量做参数也是完全可以的。参数里char d[]和char *d其实是一样的。注意二维数组的写法。

       会了这些内容,尤其是数组的传递,已经能看懂大多数函数原型了,但是还会遇见一些很古怪写法的参数,不要害怕,那一定是函数指针,传递个函数名进去就可以了,当然这个函数的原型要匹配,看着挺复杂,传起来却简单。函数指针也是一种空间,用来存函数的地址。

    最后,一般还会出道题,看是不是真的掌握了:

   有5个函数

   void func1(char c);

   void func2(char *c);

   void func3(char c[]);

   void func4(char *c[]);

   void func5(char **c);

   现有两个数组

          char m[5];

          char *n[5];

   写出用m,n做传入变量调用5个函数的写法,有几种写几种。先不公布答案,大家试着写一下。

 

说完了c,就可以说说java了,对于java而言,函数要简单一些,只用记住前两句话就行了。

 

class Example

{     

        private int a=0;

        public int b=0;

        void func(int m,int n[],Example l)

        {

              a=m;

              n[0]=a;

              l.b=a+1;

              l=new Integer(45);         

                

        }

}

调用

class TestExample

{     

         void testFunc(int m,int n[])

        {

                 Example example=new example();

                 Example m=new example();

                 int a[]=new int[5];

                 int  k=3;

                 example.func(k,a,m);

         }

}

 在java里,数组是一种对象,直接把数组对象传进去就可以了,关键还是要把数组弄明白了,这里不多讲,主要讲一点,参数Example l,l是对象句柄,其实就是指针,JAVA里所有复合类型变量都是指针,所有基本类型变量都是非指针,调用的时候k的值怎么都不会改变,数组a的第0个元素会改变,l在未重新赋值之前,存的是和m相同的值,m和 l指向同一对象,l.b=a+1修改了m的成员变量b的值,  l=new Integer(45);  之后,l存入了新对象的地址,和m不会再有任何瓜葛,说来说去,不明白指针想把java学明白是很不容易的,把指针弄明白了,搞任何语言都很容易,下面说javascript还会说指针,另外还要注意的是函数里可以使用成员变量, 这个问题也不是函数的问题,主要是静态成员变量,成员变量和静态函数和成员函数之间的调用关系,也不再这里讨论了。


最后说说javascript,这是一门解释性语言,也是一门面向对象的语言,php,perl.ruby,python等都是解释性语言,解释性语言基本上都是弱类型语言,和c,java 等有较大的差别,主要特点是变量不用定义类型,不同类型之间随便赋值,写起来很随意,不好的地方就是类型匹配的错误无法检查,只会在运行时发生,其实实现原理并不复杂,在c语言里,指针虽然有类型,但所占有的空间大小还是一样的,所有指针都是可以互相赋值的,在弱类型语言里,所有存储数据,对象的空间的地址都有指针保存,都必须通过指针进行访问,所有的变量其实都是指针。
看代码
function jsFunc(a,b,c)
{
  
    a.name="I was changed!";
    b="Test is changed";
    c[3]=5;
   
}
var myObj = new Object();
myObj.name = "Fred";
myObj.age = 42;
n="Test";
k=new Array();
k[5]=23;
jsFunc(myObj,n,k);
alert(myObj.name);
alert(n);
alert(k);
有三个参数a,b,c,调用的时候,分别传入了3个地址,myObj 的值传给了参数a,a和myObj指向同一个对象,a修改了属性name,myObj的属性name被修改,n的值传给了参数b,b的值被重新赋值,b指向了新的对象,n的值不会有任何变动,这里数组也是一个对象,k存储了这个对象的地址,k的值传给了参数c,c就可以访问数组中元素,并进行修改,javascript里面,String,Number,Date等对象和java里的String类很像,只能通过新建对象来修改值,没有成员函数可以修改值。

在3种语言里,函数参数的传递都是一样的,都是值传递,值可以是数据,也可以是地址,参数是函数内部的变量,修改参数的值不会引起函数外变量的改变,但是通过参数的值可以修改参数指向的空间,也就是函数外的空间。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页