這是參加面試時(shí)面試官問(wèn)的一道開(kāi)放式的題目渔嚷。
問(wèn)題:為什么C/C++語(yǔ)言使用指針蒲列?
這個(gè)問(wèn)題一問(wèn)出來(lái),直接被面試官給秒殺了唧取,面試官大神,你怎么不按套路出牌呢?
說(shuō)好的malloc和new的區(qū)別呢?說(shuō)好的const和#define有什么缺點(diǎn)呢?說(shuō)好的進(jìn)程和線程有什么區(qū)別和聯(lián)系呢?說(shuō)好的進(jìn)程間通信有哪些方式呢毅弧?說(shuō)好的%¥%#……@……*&()#咆霜!@#*……“……#%#%#呢?說(shuō)好的這些面試題,統(tǒng)統(tǒng)都沒(méi)有。一上來(lái)就來(lái)這么一個(gè)問(wèn)題。加上本身語(yǔ)言表達(dá)能力不夠好司致,當(dāng)時(shí)的心情就是這樣的:不淡定中帶點(diǎn)傷感霉晕!
現(xiàn)在想想,這個(gè)問(wèn)題就是一個(gè)大坑扒俯。
首先墩邀,這個(gè)題目理解起來(lái)就有點(diǎn)貓膩。言外之意好像是想讓你說(shuō)C/C++中有指針,而C#或者Java等語(yǔ)言中沒(méi)有指針。將這些編程語(yǔ)言做一下對(duì)比。
假裝沉思了3秒鐘鸠匀,然后我就想當(dāng)然的,順著這么個(gè)思路,就開(kāi)始順口開(kāi)河了。C#是高級(jí)語(yǔ)言,沒(méi)有指針啥啥的就開(kāi)始了。反反復(fù)復(fù)那么幾句話穷当,怎么扯也扯不出個(gè)清晰的邏輯出來(lái)汪疮。說(shuō)出來(lái)的答案連自己都覺(jué)得是bullshit蜓洪。
現(xiàn)在回頭想想,當(dāng)時(shí)的理解和答案是大錯(cuò)特錯(cuò)了。這本身就就是一個(gè)錯(cuò)誤的問(wèn)題∑危或者說(shuō)萨惑,面試官就是故意將你往溝里帶姐仅,等著你中套。
答案是:每一種編程語(yǔ)言都使用指針磕道。不止C/C++使用指針疯特。
為什么這樣說(shuō)邻吞?
因?yàn)楹髞?lái)在網(wǎng)上搜索答案時(shí)旺遮,在Quora上找到了一些大神們的解答鱼响。
“Everything uses pointers. C++ just exposes them rather than hiding them,”
It’s easier to give someone an address to your home than to give a copy of your home to everyone.
每一種編程語(yǔ)言都使用指針桶癣。C++只是將指針暴露給了用戶(程序員)间雀,而Java和C#等語(yǔ)言擇是將指針給隱藏起來(lái)了连锯。
但糟糕的是摇展,有些語(yǔ)言試著將指針隱藏起來(lái)捻勉,卻露出了尾巴埠偿,有時(shí)候讓人非常費(fèi)解。
下面是30年老程序員Marcus Geduld舉的栗子。引用如下:
Take, for instance, Javascript:
function foo( bar ) {
bar++;
}
var x = 5;
foo( x );
console.log( x );
Now, what is the value of x at then end of this code? 5 or 6?
Even though, in the function, the value of x gets assigned to bar and then incremented from 5 to 6, the log statement at the end will print 5. Why? because x’s value will be copied in to the function. In other words, bar won’t be pointing at the value of x, even though I wrote foo( x ). It will be pointing at a copy of that value.
Now, let’s say I wrote this:
function foo2( anArray ) {
anArray[ 0 ]++;
}
var myArray = [ 10, 20, 30 ];
foo2( myArray );
console.log( myArray );
In this case, the log will read [ 11, 20, 30 ]. So in the first case, the value was untouched. In this case, it’s been changed. Why, because foo2 didn’t get passed a copy of a value. Rather, it got passed a pointer—to the same array that myArray pointed to. So, in the first case, x and bar pointed to different values, whereas in the second case, myArray and anArray pointe to the same value, a pointer to [10, 20, 30 ].
Put more simply, this is a variable set to a value …
var a = 10;
Whereas this is a variable set to a pointer:
var a = [ 10 ];
But since nothing makes this explicit, you just have to learn some weird rules. And since many beginners don’t, they get hopelessly muddled. And they wind up accidentally changing values they didn’t intend to change and accidentallynot-changing values they did intend to change. Ugh!
Just in case this is unclear, compare this …
function foo( bar ) { bar++; console.log( bar ) };
var x = 5;
foo( x );
console.log( x );
output:
6
5
… with this :
function foo2( bar ) { bar[ 0 ]++; console.log( bar[ 0 ] ); }
var x = [ 5 ];
foo2( x );
console.log( x[ 0 ] );
output:
6
6