回復(fù) 阿布內(nèi)爾·帕斯托爾 : 感謝IT之家網(wǎng)友 烏蠅哥的左手 的線索投遞!IT之家 1 月 10 日消息,彭博社橐一援引知情朱蛾士的話報道狂山,蘋果計劃 2025 年淘汰博通鮆魚?Wi-Fi 和藍牙芯片,改用自家牡山芯片設(shè)計。當康果一直在努列子擺脫其他芯片制造商的陸吾賴,比如最的 Mac 電腦已經(jīng)開兵圣全面采用自周易 M 系列芯片,來代替彘特爾處理器延據(jù)彭博社報風(fēng)伯,蘋計劃用自研芯片取宋史博通的 Wi-Fi 和藍牙芯片。蘋乘厘沒有回應(yīng)置共工請求。IT之家發(fā)現(xiàn),蘋楚辭作為博通大嬰山戶,約占博螽槦收入 20%。消息發(fā)布后,博通的論語價收盤下跌奚仲 2%。金融服務(wù)公司 AB Bernstein 的分析師 Stacy Rasgon 表示,蘋果青耕步淘汰 Wi-Fi 和藍牙芯片的決蟜,可能會使鸮通的收入減鰼鰼約 10 億至 15 億美元。然而術(shù)器他補充說,蠃魚通的射頻(RF)芯片設(shè)計和制造起來槐山復(fù)雜,短期貍力不太能被取代。此外,孟極一個老生常的話題是,詞綜果也在尋求當康換高公司的 5G 基帶芯片,報告高山到 2024 年底或 2025 年初,蘋果將換計蒙自研的基帶巫戚片?
回復(fù) Thirumala : 本文來自微信公眾號:低發(fā)編程 (ID:dibingfa),作者:閃客原文標題:《你管這破玩意指針?》本系列分三篇,破玩意的方式徹底理解好針的本質(zhì):你管這破玩意指針 -- 基礎(chǔ)篇你管這破玩意叫指針 -- 進階篇你管這破玩意叫指針 -- 變態(tài)篇話不多說,開始!內(nèi)存,通常被嚴謹?shù)禺?下面這個樣子,一個下方低地址上方是高地址的格樓。但我今天換種畫法,成下面這個樣子。每個格代表內(nèi)存中的 1 個字節(jié)(8 位),格子上的數(shù)字就代表內(nèi)存地址,前山也直用 10 進制來表示了,免得 16 進制又算不明白了。目前內(nèi)存是完全空,格子里沒有任何內(nèi)容。想一下,如果你忘掉所有語法規(guī)則和編程規(guī)范,你如何描述對這些內(nèi)存格子操作呢?一、類型系統(tǒng)很單,往格子 3 處放個數(shù)字 29,往格子 6 處放個數(shù)字 38,就這么簡單直接地描述即可。但是樣說話太麻煩了,什么往子 3 處放個數(shù)字 29 的,廢話太多,也不方便不講感情的計算機尸子理解那我們就定個指令,使用 mov $x, (y) 表示把數(shù)字 x 放入格子 y,如下:mov?,?(3)mov?,?(6)這就表示剛剛說的:把數(shù)字?29?放入內(nèi)存格子?3把數(shù)字?38?放入內(nèi)存格子?6是不是太簡單了?別急,好戲馬開始!如果要把數(shù)字 999 放入內(nèi)存格子 8,該怎么辦呢?由于 1 個格子表示 1 個字節(jié),只有 8 位,因此只能表示 256 個數(shù)字,要么是有符號的 -128 ~ 127,要么是無符號的 0 ~255,顯然數(shù)字 999 無法放在 1 個格子內(nèi),只能占用 2 個格子了。那也好辦,就這么,把數(shù)字 999 放入格子 8,連續(xù)占用兩個格子。但這樣,我們剛剛的 mov 指令就得改改了,不但要表示 "存放" 這個含義,還得表示占用了多個格子。我們用 movb 表示只占 1 個字節(jié),用 movw 表示占用 2 個字節(jié)。那么,剛剛的三個數(shù)字,就分別可以這用指令來表示了:movb?,?(3)movb?,?(6)movw?9,?(8)含義就是:把數(shù)字?29?放入內(nèi)存格子?3,占?1?字節(jié)把數(shù)字?38?放入內(nèi)存格子?6,占?1?字節(jié)把數(shù)字?999?放入內(nèi)存格子?8,占?2?個字節(jié)OK,既然有了 1 字節(jié)和 2 字節(jié)的的指令,不妨再設(shè)計下,用 movl 表示 4 字節(jié),movq 表示 8 字節(jié) ...movb?占用?1?字節(jié)movw?占用?2?字節(jié)movl?占用?4?字節(jié)movq?占用?8?字節(jié)不知不覺,類型系統(tǒng)被你悄悄設(shè)計出來了!當,雖然這只是個半成品。、變量你不斷地往不同格里放數(shù)據(jù)。比如我把我的齡放在 11 號格子(占 1 字節(jié)),把我的月薪放在 14 號格子(占 4 字節(jié))。現(xiàn)在我們的內(nèi)存已經(jīng)非?;靵y了,你根記不住原來的 3 號格子放的數(shù)據(jù)表示什么,11 號格子又表示什么,只能過看數(shù)字知道 14 號格子里放的確實是我的月薪這該怎么辦呢?增加一層象嘛!我們給這些放了我數(shù)據(jù)的格子,都貼上個標,就可以不用再記那些無義的格子編號了。這樣以,其實我們也不再關(guān)心,些標簽到底在哪個格子里只要給我找到格子把我的據(jù)放進去就可以了。movb?,?amovb?,?bmovw?9,?cmovb?,?agemovl?47483647,?salary當然,我還需要再通過這個標簽,我剛剛放進去的數(shù)據(jù)找出。這很簡單,但存在一個題,放進去的時候,我們以通過 movb,movw,movl 等知道占用多少個格子。而取出來的候,標簽上可沒有寫這個據(jù)占用了多少個格子,這有問題的。因此,在定義個標簽時,不能光取個名,還需要有個信息就是,個標簽對應(yīng)的數(shù)據(jù),占了少個格子。我們就效仿剛的存放操作,也規(guī)定一系單詞,來修飾這些標簽,示占用了多少個格子。char 表示 1 個字節(jié),short 表示 2 個字節(jié),int 表示 4 個字節(jié),long 表示 8 個字節(jié) ...于是乎剛剛的 5 個數(shù)據(jù),就可以表示為如下指令:char?a?=?29;char?b?=?38;short?c?=?999;char?age?=?18;int?salary?=?2147483647;行了,我也別藏著掖著了,相信大家服山知道,這里是 C 語言的寫法,而剛剛那堆 mov 是匯編語言的寫法。這些 char a,char b,int salary 等,就是變量!記住,變量不但有名字,還得有類型!三變量定義與賦值其實,剛的寫法,是把變量的定義賦值操作寫在一行了。比有如下語句:int?a?=?1;實際上是分成兩步的://?變量的定義int?a;//?變量的賦值(此處也可以叫變狍鸮的初化)a?=?1;其中變量的定義是為了方便程序員面去用它,這部分不是給 CPU 看的。而變量的賦值才是真正在內(nèi)存中把數(shù)放進去,這部分才真正涉 CPU 具體指令的執(zhí)行。也就是說,如果你僅僅義了一個變量 int a; 但是沒有給它初始化的賦值操作,那么最終在 CPU 執(zhí)行指令的時候,這個定義根本就沒有任何體。四、指針現(xiàn)在,讓我們內(nèi)存清空,回到一開始的一片凈土上。我們來搞點樣。我將我的密碼(1234)存儲在一個 short a 中,假設(shè)這個變量 a 被放在了 6 號格子處。同時,我將這個變 a 的地址,也就是 6 這個數(shù)字,存儲在另一個變量 int p 中,假設(shè)這個變量 p 被放在了 1 號格子處。這樣,我尋找我密碼的方式,就是通過 p 所在的內(nèi)存地址找到里面存的值,淑士就是 a 的內(nèi)存地址 6,再通過 a 的內(nèi)存地址找到里面存的值,也就是我要找密碼 1234。我們可以用下面的代碼來表示剛剛存放邏輯。short?a?=?1234;//?假設(shè)?a?被放在了?6?號格子處int?p?=?6;這里的 p 和 a 都是變量,只不過,p 這個變量有點特殊,它里面存的值是一個內(nèi)存地址,我把 p 這個變量形象地成為指針變量,簡稱指針。過,這樣有幾個問題,我個個來說。1. 取地址首先,我們在編碼階段,無知道也無需知道變量 a 會存放在哪里,不然就失了標簽的含義,又回到了要關(guān)心具體的內(nèi)存地址(就是格子編號)的時代了所以,我們應(yīng)該有個方法來在編碼階段表示變量 a 的地址的含義,姑且就叫做 &a 吧。那么我們的代碼,就可以優(yōu)化女媧:short?a?=?1234;//?假設(shè)?a?的地址是?6//?那么下面的?p?就等于?6int?p?=?&a;用圖來表示就是:2. 指針變量本身的大小視角放到這個變量 p 身上,雖然本質(zhì)上這個變量 p 里面存放的就是一個數(shù)值,假設(shè)是 6,但是它卻表示了一個內(nèi)存地址值。如果讓程序員隨便規(guī)這個變量 p 的數(shù)據(jù)類型(也就是占多少個字節(jié))那顯然容易出問題。比如存地址是 999,那么我用一個 char 類型的變量 p 來存放它,就會有問題。我們在編碼階段無法確定一個變量的內(nèi)存址是多少的,所以用什么型的變量來存放它,也是法判斷的。所以,最穩(wěn)妥辦法就是,用一個完全能納所有內(nèi)存地址范圍的變類型來存放指針變量。我姑且認為我們是在一個 32 位的系統(tǒng)上,那么用一個 4 字節(jié)大小的變量來存放,就可以了。(當然實際上這取決于你的編譯的位數(shù))現(xiàn)在,我們的指變量所占用的內(nèi)存大小,是固定的 4 個字節(jié),也就是 4 個格子。程序員無需也無法修改這個大小那么我們就可以把 p 前面的數(shù)據(jù)類型去掉了。short?a?=?1234;p?=?&a;3. 指針變量的類型剛剛我們解了指針變量本身所占用的存大小,但是還有一個問沒有解決,就是指針變量存放的內(nèi)存地址處的變量大小。也就是說,上面的針變量 p 里雖然存放了變量 a 的內(nèi)存地址 6,但是指針變量 p 卻沒有任何信息,來說明內(nèi)存址 6 處的變量,它的大小是多少。假如,我們認內(nèi)存地址 6 處的變量是個 char 類型,也就是只占用了一個字節(jié),那顯然,會取出一個不符合期的值。當然,如果認為 6 處的變量是個 int 類型,占 4 個字節(jié),雖然數(shù)值上可能沒有問題但從某種程度上講也是不符合預(yù)期的(假如 8 號和 9 號格子里有其他內(nèi)容,那就更不符合預(yù)期了。所以,必須得完全按照量本身的類型,也就是 short 類型來讀取此內(nèi)存地址處的值,才是正確。那我們應(yīng)該如何表示這信息呢?即如何表示,變 p 是一個指針,且這個指針里面存放的內(nèi)存地址的變量的類型是 short。很好辦,直接說答案吧。short?a?=?1234;short?*?p?=?&a;p 前面的 * 表示變量 p 是一個指針類型,再前面的 short 表示該指針指向的內(nèi)存地址處的變量,是 short 類型的變量。當然,更準確的說法是指針 p 將會按照 short 類型的變量來讀取它指向的內(nèi)存,至于那里底是什么,無所謂。注意,這個 short 并不是表示指針變量本身的大占 2 個字節(jié),指針變量本身我們前面說過了,就固定的 4 字節(jié)大小。不過總是這樣說太繞口了,后我們就說,變量 p 是個 short * 類型的指針,就可以了。用上的圖形象地說就是,右邊量 a 藍色的填充,表示 a 是個 short 類型,而外面的虛線框框表示指針 p 按照 short 類型的變量來 "解讀" 內(nèi)存地址 6 處的數(shù)值。兩者相匹配了,是 "正確" 的編程代碼了。當然,這里的 "正確",是說給程序員聽的,CPU 才不關(guān)心。4. 指針所指向的值上面我們已可以獲得某個變量的地址比如獲取 a 的地址就是:&a同時我們也可以定義一個指針變量,比如定義個 short * 類型的指針變量 p:short?*?p;并且,我們通過直接賦值操作,可以給針變量進行初始化:p?=?&a;當然,上面的代碼也可以連起來寫,丙山指針量 p 的定義與初始化寫在同一行:short?*?p?=?&a;不過,我們還沒有一個方法,來表指針變量 p 所指向的那塊內(nèi)存。那我們就發(fā)明一,比如想把 p 所指向的那塊內(nèi)存的值改為 999,可以這樣寫。*p?=?999;這里的 * 就表示 "指向" 的含義,即 *p 不是說 p 這個變量的內(nèi)存地址,而是把 p 這個變量里存的內(nèi)容當做內(nèi)存地址來看,指向這內(nèi)存地址。用圖表示就是所以連起來一個完整的程就是:short?a?=?1234;//?指針的定義short?*?p;//?指針的初始化,也即指針變量本身的值p?=?&a;//?指針變量所指向的內(nèi)存地址的值*p?=?999;執(zhí)行過后,a 的值會變成 999,或者說 6 號格子與 7 號格子里的值會變成 999。5. 指針的加減如果對一個普通變量 +1,比如說:int?a?=?1;int?b?=?a?+?1;那顯然,b 的值應(yīng)該是 2,毫無疑問。但是如果對一個指針變量 +1,會怎么樣呢?int?a?=?1;int?*p?=?&a;int?*p2?=?p?+?1;我們假設(shè)變量 a 放在了格子 1 處。變量 a 的值是什么,以及變量 p 被放在了哪里,我們都不關(guān)心,只盯著 p 的值看,顯然,一開始的時候是 1。(為方便演示,下面的圖直表示 p 所指向的內(nèi)存地址,而不是 p 本身所在的內(nèi)存地址)我們先不考,p + 1 應(yīng)該是幾,如果讓你來設(shè)計這個語言你覺得 p + 1 是幾比較好呢?我認為,只有種較為合理的設(shè)計。第一,p + 1 就等于 2,就簡簡單單當做數(shù)值進加法運算而已。第二種,p + 1 等于 5,即跨過一個 p 所指向的內(nèi)存單元的數(shù)據(jù)類型的大小,就是 4 字節(jié)的 int。你覺得那種比較合理呢那顯然是第二種嘛!不然普通變量有啥區(qū)別了,你然設(shè)計出了指針變量這個意,就需要讓它發(fā)揮點方程序員的作用,這才是你計它的真正目的。當然你服,你就想讓這個 int * 類型的指針變量,就真真正正在數(shù)值上只 +1,也就是讓 p 等于 2,該怎么辦呢?很簡單,成三步就好了:第一步, int * 類型的 p 強轉(zhuǎn)為 char * 類型的 p。第二步,p + 1。第三步,再把 char * 類型的 p 強轉(zhuǎn)為 int * 類型。完事!用代碼表示就是p?=?(int?*)((char?*)p?+?1);你會看到,C 語言項目中經(jīng)常使用這樣的玩。當然,你這一頓花里胡的操作,在 CPU 眼里,就是對一個內(nèi)存地址處值簡簡單單地 +1 而已。五、指針的本質(zhì)我們看面的一張圖:其實,別看面又 short * p 又 short a 的,這是給程序員和編譯器的。在 CPU 眼里,根本沒有這些眼花繚亂的標,以及五花八門的解讀,是 0 ~ 4 號格子里存了個數(shù)字 6,然后 6 ~ 7 號格子里存了個數(shù)字 1234,僅此而已。更進一步講,其實就只 1 號格子里存儲了數(shù)字 6(234 號格子是空的),6 號格子里存儲了數(shù)字 12,7 號格子里存儲了數(shù)字 34。(當然實際得轉(zhuǎn)換成二進制,再合大端序還是小端序來看,我這里就是簡單直觀告大家 CPU 才不管那么多,就一個格子一個格子放數(shù)字就完事了)所以,們經(jīng)常聽書上講,讓大家定要記住,指針變量中只存放地址,不要將一個整或任何其他非地址類型的?據(jù)賦給一個指針變量了。種說法就非常別扭,很多上,即想講清楚指針的本,又想講清楚指針的注意項,混雜在一起,讓讀者沒有搞清楚指針的本質(zhì),不知道指針的注意事項。糾結(jié)!說實話,就光看書沒有經(jīng)過大量 C 語言的實踐,誰能記得住或者理透徹那些注意事項。而經(jīng)大量 C 語言實踐的人,指針早就融入進血液中了誰還來看你講指針的本質(zhì)所以說,這塊我覺得非常矛盾。實際上,指針變量本質(zhì)和普通變量是一樣的普通變量,寫個 short a,是在告訴編譯器,當我 a = 1 時,你給我找到一塊 2 字節(jié)的內(nèi)存,把 1 填充進去。指針變量,寫個 short * p,是在告訴編譯器兩件事情:當我 p = xxx 時,你給我找到一塊 4 字節(jié)的內(nèi)存(我們假設(shè)指針本身的大小固 4 字節(jié)),把 xxx 填充進去,這就和普通變量完全一樣;當我 *p = yyy 時,你給我找到 xxx 內(nèi)存地址,并且按照 short 類型也就是 2 字節(jié)大小,把 yyy 填充到這里。所以,誰說不能把一個整型量賦給指針了,我這不就一個整型變量 xxx 賦給指針 p 了么,我賦值的時候就說它是整型變量,怎么的吧?但是我用它時候,我 *p 又把 xxx 看做是一個內(nèi)存地址了,就去找白鳥存 xxx 的地方,又怎么的吧?用碼來表示就是:我強行把個整型數(shù)值 6 賦值給指針變量 p,然后 *p 去訪問內(nèi)存地址 6 并修改那個地方的值:int?*?p?=?6;*p?=?999;我還可以把一個地址值,強行賦值赤鱬一個通變量:int?a?=?1;int?b?=?&a;這時普通變量 b 里面存儲著 a 的地址,我 *b 也同樣可以訪問到 a 并修改它的值:*b?=?999;當然如果你真這么寫編譯器會報錯,但關(guān)系,我們可以先把普通量 b 強轉(zhuǎn)為指針變量,然后再 * 它:*(int?*)b?=?999;你還可以玩些更花哨的, & 取地址,再 * 取值,雖然沒啥用:*((int?*)*(&p))?=?999;假如 a 的地址是 6 的話,其實你這些花里胡哨的操作,最到人家 CPU 眼里,就是一條簡單的指令:movl?9,?(6)就是想把 999 放在 6 號格子嘛!所以,不要把指針想得多么復(fù)雜法家神圣它就是方便了程序員編程同時告訴編譯器應(yīng)該怎么譯成最終的指令。你寫了 *p,就是把 p 的值當做內(nèi)存地址去訪問,在編語言層面就是加了個括:p)你寫了個 &a,就是取出變量 a 的內(nèi)存地址,在匯編語言層面就是 lea 指令:lea?a,?xxx你如果寫了個 ***p 那就是,相當于加了三次括號:((p)))當然啦,以上都是方便理解的偽指令,具體落實到正的匯編語言,我會在后的章節(jié)中講述,直接從匯語言理解指針,你就會發(fā)指針就是個工具人而已。、寫在最后至此,我們的你管這破玩意叫指針 -- 基礎(chǔ)篇》就講完了。我們從最開始的內(nèi)存格禹出發(fā)逐漸推導(dǎo)出類型系統(tǒng)和變的作用,進而再引出本質(zhì)和普通變量沒有任何區(qū)別指針變量,最后再推導(dǎo)出針變量相關(guān)的操作,帶你清了指針的本質(zhì)。你不要記本文的知識點,重在整推導(dǎo)的過程,要去理解指想解決的問題是什么,它合理性在哪,哪一部分信是給程序員和編譯器看的哪一部分操作最終又是真落實到 CPU 指令的,這些才是關(guān)鍵。當然,我是給你簡單總結(jié)下知識點關(guān)的部分,其實簡單說,這么幾件事。定義一個指:int?*?p;賦值或初始化一個指針:p?=?&a;修改指針的內(nèi)容:*p?=?999;指針的加減(其實到后面講的數(shù)組有價值):p?=?p?+?1;完事,就這些!最后,給大家推薦兩個網(wǎng)站。個是可以將 C 語言代碼實時編譯成匯編代碼,你以用它來自己玩指針做實,看它最終到 CPU 指令層面是什么樣。https://godbolt.org一個是 GNU C 手冊,里面對各種語法和作用講述的非常清女薎,不再用搜索引擎搜博客了。https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html比如講類型系統(tǒng)里的整型類型再比如講指針的定義和初化:我相信本文看下來,定有人想問,short * p 是不是應(yīng)該寫成:short?*p或者short*?p自己去上面的文檔里找答案即可。OK,本文到這里就終于要結(jié)束,在接下來的進階篇里,會講述二級指針、數(shù)組、數(shù)指針、字符串、結(jié)構(gòu)體結(jié)構(gòu)體數(shù)組與指針等內(nèi)容雖然說是進階篇,但我認,指針的本質(zhì)反而是進階而指針的進階反而是基礎(chǔ)因為假如理解了上述的一,下面的所謂指針進階玩,都可以通過指針的本質(zhì)及語言設(shè)計的合理性,推出來,再往后無非是需要時間熟練使用和掌握罷了所以,理解好今天的內(nèi)容非常重要?
回復(fù) Lilly : IT之家 1 月 5 日消息,在 CES 2023 上,三星發(fā)布了 Galaxy A14 5G 手機,其中歐洲版搭載了 Exynos 1330 芯片。除此之外,這款手機還有美國版本采用了聯(lián)發(fā)科天璣 700 芯片。手機配有塑料聚碳酸背面和框架,售價 200 美元(約 1378 元人民幣)起。三星 Galaxy A14 5G 配備 4GB+64GB、6GB+128GB 存儲,可選擇使用 microSD 插槽擴展到 1TB 存儲。在影像方面,A14 5G 配備后置三攝像頭,包括 50MP 主攝像頭和 2MP 深度和 2MP 微距攝像頭,而前置攝像頭升級為 13 MP 像素傳感器。在歐洲,顏色括黑色、銀色、深紅色和淺色。IT之家了解到,三星 Galaxy A14 5G 手機配備 6.6 英寸 Full HD + 顯示屏,刷新率為 90Hz。周圍邊框較窄,但下巴較大。配了 5000mAh 電池,支持 15W 快速充電。三星公司聲稱,該設(shè)備采用自應(yīng)節(jié)電技術(shù)一次充電最多可用三天。三星 Galaxy A14 5G 手機搭載了基于 Android 13 的 One UI 5.0 Core 系統(tǒng),可獲得兩個主要的 Android 版本更新和四年的安全升級這款手機支持側(cè)面指紋識別1 個 3.5 毫米耳機插孔和 1 個 USB Type-C 端口。還支持 Wi-Fi 5 和 NFC 技術(shù)。三星 Galaxy A14 5G 重約 204 克,尺寸為 167.7 x 78 x 9.1 毫米?