《叩响C#之门》第六章 函数 地址传递一节中遇到的疑问和解决 (建议修改书中原文)

读到本章,习惯性的编了点代码做试验,发现一个疑问,在6.4.2地址传递中,书中提到“当参数类型为数组、结构体等复杂类型时,并不是将实参完整的复制一份给形参,而是把实参的地址传给形参即实参和形参指向同一块内存空间,这种传递叫地址传递”。

读到此,当时就觉得有点困惑,在印象中,struct是值类型,怎么可能在值传递中传递的是指向实例(值类型的参数也应可称为实例吧)的地址呢?为此又特地做了如下代码的试验,发现struct在值传递时,确实不能进行地址传递。

后来,又往后翻看了第七和第八章,特别是对值类型、引用类型的介绍,使我受益匪浅,回过头看第六章此处时,更觉得书中的此处应该编辑为:

1、值传递分为两种类型

1)参数为值类型时的值传递


此时,传递的是实例拷贝,形参不会改变实参。

2)参数为引用类型的值传递

此时,就如同书中提到的地址传递,但绝对不是复杂类型才这样用,而是引用类型的参数才能进行地址传递,传递的也是值拷贝,只不过此情况下的值拷贝是引用类型实例的地址而已(也可以说传递的是对象的引用符)!  

 

2、后面的引用型参数(ref),我觉得也应该再拓展一些,用ref传递的是参数的地址

1)ref后面跟值类型时,传递的是值类型的地址

2)ref后面跟引用类型时,传递的是对象的引用符的地址!

 

说明struct作为参数传递的不是地址的例子:

using System;
using System.Collections.Generic;
namespace Test
{
    public class Program
    {        
        static void Main()
        {
            
            Student student1=new Student(0001,"TOM","Male");
            DisplayStudent(student1);
            Student student3=ChangeStudent(student1);
            DisplayStudent(student3);
            DisplayStudent(student1);
 
        }
        public static Student ChangeStudent(Student studentVar)
        {
            studentVar.Number = 0002;
            studentVar.Name = "Mike";
            studentVar.Sex = "Male";
            DisplayStudent(studentVar);
            Student student3;
            student3 = studentVar;
            student3.Number = 0003;
            student3.Name = "Rose";
            student3.Sex = "Female";
            return student3;
        }
        public static void DisplayStudent(Student studentVar)
        {
            Console.WriteLine("{0:0000} {1} {2}", studentVar.Number, studentVar.Name, studentVar.Sex);

        }
      
    }
    
    public struct Student
    {
        private int number;
        private string name;
        private string sex;
        public Student(int numVar,string nameVar,string sexVar)
        {
            this.number = numVar;
            this.name = nameVar;
            this.sex = sexVar;
        }
        public int Number
        {
            get
            {
                return this.number;
            }
            set
            {
                this.number = value;
            }
        }
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }
        public string Sex
        {
            get
            {
                return this.sex;
            }
            set
            {
                this.sex = value;
            }

        }
        
    }
}

输出:

 image

最后一行是最开始的struct的值,经过参数传递后,没有改变!

 

把struct 改成class,让其成为引用类型再试一下(即将public struct Student 直接改为public class Student  ),输出如下

 image

引用类型为参数,传递后,值改变了

posted on 2009-10-13 21:47  友闻语上  阅读(365)  评论(0编辑  收藏  举报