337p人体粉嫩胞高清图片,97人妻精品一区二区三区在线 ,日本少妇自慰免费完整版,99精品国产福久久久久久,久久精品国产亚洲av热一区,国产aaaaaa一级毛片,国产99久久九九精品无码,久久精品国产亚洲AV成人公司
網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

C語(yǔ)言之父把"地雷"埋了50年,47%程序員踩過(guò)這個(gè)坑

0
分享至


1972年,Dennis Ritchie在貝爾實(shí)驗(yàn)室敲下第一行C代碼時(shí),可能沒料到那個(gè)叫"指針"的設(shè)計(jì)會(huì)成為后世開發(fā)者的集體噩夢(mèng)。Stack Overflow 2024年調(diào)研顯示,47%的C/C++開發(fā)者認(rèn)為指針相關(guān)bug是最難調(diào)試的問(wèn)題——這個(gè)數(shù)字比內(nèi)存泄漏高出12個(gè)百分點(diǎn)。

Bjarne Stroustrup(C++之父)有句被引用過(guò)百萬(wàn)次的吐槽:「C讓你很容易打傷自己的腳,C++讓這事變難,但真出問(wèn)題時(shí),整條腿都沒了。」這話雖針對(duì)C++,卻精準(zhǔn)戳中了指針的本質(zhì)——它是一把沒有保險(xiǎn)栓的鏈鋸,能砍樹,也能砍腿。

本文從內(nèi)存地址的物理本質(zhì)講起,一路拆到函數(shù)指針和void*的黑魔法。讀完你會(huì)理解:為什么Linux內(nèi)核60%的漏洞和指針有關(guān),以及為什么嵌入式工程師寧可手寫匯編也要繞過(guò)某些指針操作。

一、指針的本質(zhì):內(nèi)存里的"門牌號(hào)系統(tǒng)"

先扔掉所有教科書定義。想象一棟沒有電梯的老式居民樓,每層4戶,門牌號(hào)從101開始連續(xù)編號(hào)。指針就是這棟樓里的"地址本"——它不存放住戶本人,只記錄"302室住著張三"。

代碼層面的真相更簡(jiǎn)單:

int value = 42; // 在內(nèi)存某處存了數(shù)字42 int *ptr = &value; // ptr這個(gè)變量存的是value的門牌號(hào)

這里有兩個(gè)關(guān)鍵符號(hào):&是"取地址",*是"解引用"(順著門牌號(hào)找人)。新手最容易混淆的是聲明時(shí)的*和使用時(shí)的*——聲明時(shí)它是"類型修飾符",告訴編譯器這是個(gè)指針變量;使用時(shí)它是"解引用運(yùn)算符",執(zhí)行真正的尋址操作。

再看一段解剖式代碼:

int x = 10; int *p = &x; // p里存的是x的內(nèi)存地址 printf("Address of x: %p\n", (void*)p); // 打印門牌號(hào):0x7ffd... printf("Value of x: %d\n", *p); // 打印值:10 *p = 20; // 不經(jīng)過(guò)x,直接修改內(nèi)存里的值 printf("New value: %d\n", x); // x變成20

最后那行*p = 20就是指針的"隔空打穴"——x自己沒動(dòng),但內(nèi)存里的值被改了。這種間接訪問(wèn)機(jī)制是C語(yǔ)言所有高級(jí)特性的基石,也是所有段錯(cuò)誤的源頭。

二、void*:內(nèi)存世界的"萬(wàn)能插座"

void*是C標(biāo)準(zhǔn)里最特殊的指針類型,被稱為"無(wú)類型指針"或"通用指針"。它的設(shè)計(jì)初衷是解決類型系統(tǒng)的剛性問(wèn)題——就像電源插座不該規(guī)定你必須插吹風(fēng)機(jī)還是充電器。

看這段類型穿梭代碼:

int int_val = 100; float float_val = 3.14; char char_val = 'A'; void *generic_ptr; // 聲明一個(gè)萬(wàn)能容器 generic_ptr = &int_val; printf("Integer: %d\n", *(int*)generic_ptr); // 必須強(qiáng)制轉(zhuǎn)回int* generic_ptr = &float_val; printf("Float: %.2f\n", *(float*)generic_ptr); // 再轉(zhuǎn)回float*

關(guān)鍵限制:void*不能直接解引用。編譯器不知道你要取幾個(gè)字節(jié)、怎么解析二進(jìn)制模式,必須顯式告訴它"按int解釋"或"按float解釋"。這種設(shè)計(jì)在malloc/free、回調(diào)函數(shù)、泛型數(shù)據(jù)結(jié)構(gòu)(如Linux內(nèi)核的鏈表)中無(wú)處不在。

但void*也是類型安全的墳?zāi)埂?996年Ariane 5火箭爆炸事故,根源就是把64位浮點(diǎn)數(shù)塞進(jìn)16位整型空間——而void*的隨意轉(zhuǎn)型讓這類錯(cuò)誤在編譯期零警告。

三、數(shù)組與指針:一場(chǎng)持續(xù)50年的身份迷思

這是C語(yǔ)言最經(jīng)典的"合法謊言":數(shù)組名在大多數(shù)表達(dá)式中會(huì)退化為指向首元素的指針。K&R(C語(yǔ)言之父合著的經(jīng)典教材)第5.3節(jié)花了整整3頁(yè)解釋這個(gè)例外清單,但90%的開發(fā)者只記得前半句。

真相代碼:

int arr[5] = {10, 20, 30, 40, 50}; int *p = arr; // 等價(jià)于 &arr[0],不是整個(gè)數(shù)組的地址 // 這四種寫法訪問(wèn)的是同一個(gè)元素: printf("%d\n", arr[0]); // 數(shù)組語(yǔ)法 printf("%d\n", *arr); // 指針語(yǔ)法(數(shù)組退化為指針) printf("%d\n", *p); // 指針解引用 printf("%d\n", p[0]); // 指針用數(shù)組語(yǔ)法——完全合法

最后那個(gè)p[0]讓無(wú)數(shù)人困惑:指針怎么能用方括號(hào)?答案是C的語(yǔ)法糖設(shè)計(jì)——p[i] 被定義為 *(p + i),這個(gè)等式對(duì)指針和數(shù)組名同時(shí)成立。換句話說(shuō)(整篇唯一一次),方括號(hào)只是指針運(yùn)算的化妝品。

但數(shù)組和指針絕非同一事物。sizeof(arr)返回整個(gè)數(shù)組的字節(jié)數(shù)(20字節(jié)),sizeof(p)返回指針本身的大小(8字節(jié),64位系統(tǒng))。這個(gè)差異在函數(shù)參數(shù)傳遞時(shí)尤為致命:

void foo(int arr[5]); // 編譯器默默改為 int *arr void foo(int *arr); // 實(shí)際生成的代碼

數(shù)組長(zhǎng)度信息在傳遞時(shí)徹底丟失,這就是為什么C標(biāo)準(zhǔn)庫(kù)函數(shù)總要額外傳個(gè)size_t參數(shù)。

四、指針?biāo)阈g(shù):編譯器替你藏的"乘法器"

指針?biāo)阈g(shù)是C語(yǔ)言最高效的數(shù)組遍歷方式,也是最難直覺理解的機(jī)制。核心規(guī)則:指針+1不是加1個(gè)字節(jié),而是加1個(gè)元素的大小。

遍歷代碼示例:

int numbers[5] = {1, 2, 3, 4, 5}; int *ptr = numbers; for (int i = 0; i < 5; i++) { printf("Element %d: %d at address %p\n", i, *(ptr + i), (void*)(ptr + i)); }

假設(shè)int占4字節(jié),ptr初始值為0x1000。那么:

? ptr + 0 = 0x1000(指向numbers[0]) ? ptr + 1 = 0x1004(指向numbers[1]) ? ptr + 2 = 0x1008(指向numbers[2])

編譯器在背后做了隱式乘法:實(shí)際地址 = 基地址 + i × sizeof(int)。這種設(shè)計(jì)讓指針?biāo)阈g(shù)與數(shù)據(jù)類型解耦——同樣的++ptr遍歷代碼,對(duì)char數(shù)組每次跳1字節(jié),對(duì)double數(shù)組每次跳8字節(jié)。

但這也埋下了對(duì)齊要求的隱患。某些ARM處理器訪問(wèn)未對(duì)齊的int*會(huì)直接拋出硬件異常,而x86只是性能懲罰。嵌入式開發(fā)者的血淚經(jīng)驗(yàn):指針?biāo)阈g(shù)前先用__alignof__檢查對(duì)齊。

五、二維數(shù)組:指針的指針,還是數(shù)組的數(shù)組?

原文在此處截?cái)啵炎銐蛘故綜指針的深淵。int matrix[3][4]的內(nèi)存布局是連續(xù)的12個(gè)int,但matrix[1]的類型是int[4](數(shù)組),又會(huì)退化為int*。這種"數(shù)組的數(shù)組"與"指針的指針"(int **)在語(yǔ)法上可互換、在語(yǔ)義上截然不同的特性,讓動(dòng)態(tài)二維數(shù)組成為面試高頻題。

Linux內(nèi)核開發(fā)者Robert Love在《Linux Kernel Development》里寫過(guò)一個(gè)細(xì)節(jié):內(nèi)核代碼中90%的多維數(shù)組訪問(wèn)都改用一維指針+手動(dòng)偏移計(jì)算,只為避免編譯器對(duì)多維數(shù)組的邊界檢查開銷。

當(dāng)你下次在GDB里盯著0x7ffd5e8c3a2c這樣的地址發(fā)呆時(shí),不妨想想Ritchie當(dāng)年的設(shè)計(jì)權(quán)衡:把內(nèi)存的直接操控權(quán)交給程序員,意味著信任程序員能管好自己。這種信任在1972年是革命性的,在2024年則成了安全審計(jì)的噩夢(mèng)。指針不會(huì)消失,但Rust的所有權(quán)系統(tǒng)正在證明:同樣的硬件操控力,可以用更嚴(yán)格的規(guī)則封裝。

你最近一次segmentation fault是在調(diào)試什么功能?

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
個(gè)人公眾號(hào)“千問(wèn)”停更近10年,近期接連遭阿里投訴均被駁回,號(hào)主:規(guī)避風(fēng)險(xiǎn)不發(fā)AI文章,如果我不發(fā)聲,賬號(hào)就不保了

個(gè)人公眾號(hào)“千問(wèn)”停更近10年,近期接連遭阿里投訴均被駁回,號(hào)主:規(guī)避風(fēng)險(xiǎn)不發(fā)AI文章,如果我不發(fā)聲,賬號(hào)就不保了

中國(guó)能源網(wǎng)
2026-03-25 13:53:05
伊朗復(fù)仇,美國(guó)最害怕的事情發(fā)生!戰(zhàn)爭(zhēng)令人想起這位累死的大人物

伊朗復(fù)仇,美國(guó)最害怕的事情發(fā)生!戰(zhàn)爭(zhēng)令人想起這位累死的大人物

華人星光
2026-03-20 11:48:15
伊朗外長(zhǎng):以色列將美國(guó)推向沖突

伊朗外長(zhǎng):以色列將美國(guó)推向沖突

新華社
2026-03-26 06:30:05
比美國(guó)還囂張的國(guó)家出現(xiàn),禁止所有中國(guó)外交官入境,不讓統(tǒng)一

比美國(guó)還囂張的國(guó)家出現(xiàn),禁止所有中國(guó)外交官入境,不讓統(tǒng)一

尋墨閣
2026-03-25 07:21:38
約基奇狂砍23+17+17,掘金沖上西部第三,湖人倍感壓力

約基奇狂砍23+17+17,掘金沖上西部第三,湖人倍感壓力

陳鋅特色美食
2026-03-25 14:26:13
香港超級(jí)兇宅230萬(wàn)港元推拍,未達(dá)底價(jià)收回;曾發(fā)生五尸命案,風(fēng)水師謀財(cái)害命

香港超級(jí)兇宅230萬(wàn)港元推拍,未達(dá)底價(jià)收回;曾發(fā)生五尸命案,風(fēng)水師謀財(cái)害命

星島記事
2026-03-25 16:56:04
特朗普支持率公布

特朗普支持率公布

第一財(cái)經(jīng)資訊
2026-03-25 08:31:57
扒開張雪峰的家底才明白:他最厲害的不是報(bào)志愿,而是選對(duì)妻子

扒開張雪峰的家底才明白:他最厲害的不是報(bào)志愿,而是選對(duì)妻子

風(fēng)起見你
2026-03-25 10:40:24
黃仁勛呼吁所有人使用AI提升自己:大學(xué)生畢業(yè)時(shí)都要成AI專家

黃仁勛呼吁所有人使用AI提升自己:大學(xué)生畢業(yè)時(shí)都要成AI專家

快科技
2026-03-24 22:46:04
棄40萬(wàn)鎊周薪去賺大錢 下一站沙特超 2年合同 年薪1億歐

棄40萬(wàn)鎊周薪去賺大錢 下一站沙特超 2年合同 年薪1億歐

智道足球
2026-03-25 15:36:30
“最慘超女”黃雅莉:沒工作沒積蓄,34歲生子后住5平米的小屋

“最慘超女”黃雅莉:沒工作沒積蓄,34歲生子后住5平米的小屋

幽棠的趣式
2026-03-23 21:16:36
曝張雪峰已立遺囑,遺產(chǎn)由女兒張姩菡單獨(dú)繼承,遺囑立于去年3月

曝張雪峰已立遺囑,遺產(chǎn)由女兒張姩菡單獨(dú)繼承,遺囑立于去年3月

扒蝦侃娛
2026-03-25 23:09:21
以色列全境被打穿,防空淪為擺設(shè),海灣國(guó)家不甘示弱,或下場(chǎng)打仗

以色列全境被打穿,防空淪為擺設(shè),海灣國(guó)家不甘示弱,或下場(chǎng)打仗

鐵錘簡(jiǎn)科
2026-03-26 00:35:12
俄羅斯港口遭突襲,普京連夜下令反擊,兩國(guó)私下聯(lián)手被曝光

俄羅斯港口遭突襲,普京連夜下令反擊,兩國(guó)私下聯(lián)手被曝光

軍科零零
2026-03-26 07:13:38
鄭裕彤家族危機(jī)爆發(fā),或賣祖業(yè)自救,為何沒有香港豪門出手相助?

鄭裕彤家族危機(jī)爆發(fā),或賣祖業(yè)自救,為何沒有香港豪門出手相助?

林小明商業(yè)評(píng)說(shuō)
2026-03-25 14:18:52
胡兵沒想到,張雪峰意外猝死僅1天,竟讓51歲瞿穎口碑再次暴漲

胡兵沒想到,張雪峰意外猝死僅1天,竟讓51歲瞿穎口碑再次暴漲

愛下廚的阿釃
2026-03-26 06:20:07
開業(yè)5天已快回本一半!花27萬(wàn)元拿下太昊陵廟會(huì)C位攤的豬蹄老板:每天營(yíng)業(yè)14個(gè)小時(shí),僅睡四五個(gè)小時(shí),喉嚨都喊啞了

開業(yè)5天已快回本一半!花27萬(wàn)元拿下太昊陵廟會(huì)C位攤的豬蹄老板:每天營(yíng)業(yè)14個(gè)小時(shí),僅睡四五個(gè)小時(shí),喉嚨都喊啞了

極目新聞
2026-03-24 22:57:22
教育徹底變天!2026屆初中生注意,這是最后一屆只拼分?jǐn)?shù)的一屆

教育徹底變天!2026屆初中生注意,這是最后一屆只拼分?jǐn)?shù)的一屆

老特有話說(shuō)
2026-03-25 15:22:58
張雪峰,倒在上市前夜

張雪峰,倒在上市前夜

帥真商業(yè)
2026-03-25 11:31:43
價(jià)格飆漲6000%!原研藥集體撤離中國(guó)的影響,開始出現(xiàn)了...

價(jià)格飆漲6000%!原研藥集體撤離中國(guó)的影響,開始出現(xiàn)了...

墜入二次元的海洋
2026-03-24 00:58:18
2026-03-26 09:40:49
灰度測(cè)試中
灰度測(cè)試中
生活正在重構(gòu),目前還在灰度測(cè)試階段,暫不全量發(fā)布。
64文章數(shù) 1關(guān)注度
往期回顧 全部

科技要聞

硅谷因AI大裁員?一線工程師戳破真相

頭條要聞

舉天價(jià)零件發(fā)出靈魂拷問(wèn)的美官員 自己被大學(xué)生質(zhì)問(wèn)了

頭條要聞

舉天價(jià)零件發(fā)出靈魂拷問(wèn)的美官員 自己被大學(xué)生質(zhì)問(wèn)了

體育要聞

35歲替補(bǔ)門將,憑什么入選英格蘭隊(duì)?

娛樂(lè)要聞

張雪峰遺產(chǎn)分割復(fù)雜!是否立遺囑成關(guān)鍵

財(cái)經(jīng)要聞

黃仁勛:芯片公司的時(shí)代已經(jīng)結(jié)束了

汽車要聞

智己LS8放大招 30萬(wàn)內(nèi)8系旗艦+全線控底盤秀實(shí)力

態(tài)度原創(chuàng)

房產(chǎn)
時(shí)尚
親子
藝術(shù)
本地

房產(chǎn)要聞

41億!259畝!建學(xué)校…三亞這個(gè)大城更,最新方案曝光!

《非窮盡列舉》,好看又絕望

親子要聞

期盼每個(gè)孩子天天都能睡好覺

藝術(shù)要聞

王洪文的狂草背后隱藏的秘密,趙孟頫書法的真實(shí)價(jià)值揭秘!

本地新聞

來(lái)永泰同安 赴一場(chǎng)春天的約會(huì)

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版