什么叫引用?只因个变量的值和其它的不一?
首先理解:都是变量
int i;
ArrayList b;
i和b都是变量.
但i是基本变?也叫原始变量.
其它的就叫引用变?因ؓ它的值是一个内存地址?引用对象?但记?它们都是有一个值的!i是一个数?而b是一个内存地址?单的说是一个十六进
制的?.除了基本变量之外的变量都是引用变?Vector a;q里的a也是一个变?它也是有值的,它的值是一个十六进制的?
变量的赋?
int i=10;
int j=i;
//q里把i的?0l了j,所以j的g?0
ArrayList b=new ArrayList();
ArrayList c=b;
//首先,b是一个引用变?它的"?:是一个内存地址?!! new
ArrayList()要分配一D内存保存它?怎么h到这D内?那就是通过b里的g.b的值就是new
ArrayList()所占内存的首地址.然后c也是一个引用变?它的?地址?和b是一L.也就是new
ArrayList()所占内存的首地址.所以当通过b或者cq行操作?它们都是操作同一个对象的.
在方法调用的时?Ҏ的参数实际也是一个变?如果是基本类型变量的时?假设有方法method(int aa);
int j=10;
method(j);
q里?int aa实际也是定义了一个变?调用的时候把j的?10也给了aa.所以aa也是10,改变了aa的值ƈ不会改变j的?
如果是引用变量的时?假设有方法methodA(ArrayList aa);
ArrayList b = new ArrayList();
methodA(b);
//Ҏ定义了变量aa,调用的时候把b的?地址?!!!!)l了aa,所以aa与b有一L?地址?!!!),在方法里通过aaL作的时?b所引用的对象也p改变?因ؓ它们引用同一个对?
U?a = new 银行帐户();//开一个银行帐?q回一个卡L?写在你的Ua里边.
用一张纸(引用变量),把你的银行卡号写在上?然后调用我的时?我用另外一张纸(引用变量---Ҏ的Ş?,把你的号码抄q来.然后我通过q个卡号,d银行扑ֈ你的帐号,l你存点?
然后你用你的U?引用变量)上的卡号 <没变,q是那个卡号>再去查询银行帐号的时候就会发C多了一些钱?....
说说我对g递和引用传递的看法Q?br />
首先我认为,大家对Java传递参数的行ؓ是清楚的Q这个争论只是一个语义上的争论?br />
也就是我们是否需要区分g递和应用传递呢Q或者说q样的区分有没有意义Q是否合理?
博主认ؓ存在引用传递的关键点在于,传递的对象地址|本质上它是一个引用,无论它是否被copyq?br />
认ؓ只有g递的关键点在于,传递的对象地址|它是一个值的copyQ这个g表的意义无所谓?br />
引用是c++里的概念Q由于java跟c++是有一定关pȝQ这里把引用q移q来Q如果合理未不可?br />
c++中关于引用的解释一般喜Ƣ说是看?#8220;别名”Q我查了几本书,大部分提到引用ƈ不会分配内存I间Q也有一本书提到Q某些编译器会分配存储空间来存储被引用对象的地址?br />
那么q是回到语义上来Qc++里的q个引用Q语义上?#8220;别名”的意思,我的理解是,一l指向同一个对象的别名应该只存储一份内存地址。当然具体实现可能会
把引用当做一个不可变的指针来处理Q每个别名都存储自己的对象地址Q。但是请注意Q我们应该关注于它的语义Q即Q它没有M值的copyQ即使是一个地
址Q只是另外一个名字而已?br />
但是java里面没有q样的概念,所有的地址传递其行ؓ是值的传递方式,语义上统一成g递更为清晎ͼ我们只需要考虑q个值具体是什么,无非两种Q要么是基本cd|要么是个地址?br />
所以我认ؓq个“引用”的概忉|到java中ƈ不合适。只有g递的说法更合理?/p>
Ƨ几里d法又称辗{盔R法,用于计算两个整数a,b的最大公U数。其计算原理依赖于下面的定理Q?
定理Qgcd(a,b) = gcd(b,a mod b)
证明Qa可以表示成a = kb + rQ则r = a mod b
假设d是a,b的一个公U数Q则?
d|a, d|bQ而r = a - kbQ因此d|r
因此d?b,a mod b)的公U数
假设d ?b,a mod b)的公U数Q则
d | b , d |r Q但是a = kb +r
因此d也是(a,b)的公U数
因此(a,b)?b,a mod b)的公U数是一LQ其最大公U数也必然相{,得证
Ƨ几里d法是Ҏq个原理来做的,其算法用C++语言描述为:
void swap(int & a, int & b){
int c = a;
a = b;
b = c;
}
int gcd(int a,int b){
if(0 == a ){
return b;
}
if( 0 == b){
return a;
}
if(a > b){
swap(a,b);
}
int c;
for(c = a % b ; c > 0 ; c = a % b){
a = b;
b = c;
}
return b;
}
2、Stein法
Ƨ几里d法是计两个数最大公U数的传l算法,它无Z理论q是从效率上都是很好的。但是有一个致命的~陷Q这个缺陷只有在大素数时才会昄出来?
考虑现在的硬件^収ͼ一般整数最多也是64位,对于q样的整敎ͼ计算两个C间的模是很简单的。对于字长ؓ32位的q_Q计两个不过32位的整数?
模,只需要一个指令周期,而计?4位以下的整数模,也不q几个周期而已。但是对于更大的素数Q这L计算q程׃得不qh设计Qؓ了计两个超q?
64位的整数的模Q用户也怸得不采用cM于多位数除法手算q程中的试商法,q个q程不但复杂Q而且消耗了很多CPU旉。对于现代密码算法,要求计算
128位以上的素数的情冉|比皆是,设计q样的程序迫切希望能够抛弃除法和取模?
Stein法由J. Stein 1961q提出,q个Ҏ也是计算两个数的最大公U数。和Ƨ几里d法 法不同的是QStein法只有整数的移位和加减法,q对于程序设计者是一个福韟?
Z说明Stein法的正性,首先必须注意C下结论:
gcd(a,a) = aQ也是一个数和它自n的公U数是其自n
gcd(ka,kb) = k gcd(a,b)Q也是最大公U数q算和倍乘q算可以交换Q特D的Q当k=2Ӟ说明两个偶数的最大公U数必然能被2整除
C++/java 实现
// c++/java stein 法
//arrange so that a>b
int gcd(int a,int b){
if(a<b){
int temp = a;
a = b;
b=temp;
}
if(0==b)//the base case
return a;
if(a%2==0 && b%2 ==0)//a and b are even
return 2*gcd(a/2,b/2);
if ( a%2 == 0)// only a is even
return gcd(a/2,b);
if ( b%2==0 )// only b is even
return gcd(a,b/2);
return gcd((a+b)/2,(a-b)/2);// a and b are odd
}