C語言使用char是否可以節約記憶體?

時間 2021-05-10 17:30:42

1樓:undefined

這兩處都不會。

第一處,迴圈計數器大概率會被優化到暫存器裡,所以這個地方你用什麼都沒有區別。

第二處,如果是cdecl,那麼棧是64位對齊的,所以沒用,如果不是,那麼引數是暫存器傳遞的,所以沒用。

這兩處是相當精確的「一點卵用都沒有」的情況。

2樓:

你舉例的場景,不會。

因為單獨的char運算實際結果在彙編也是32&64去運算的,所以你乙個char在運算傳值的時候,相當於在做int運算,大部分編譯器都是。

char更節約記憶體,主要表現在結構體內,你的結構體儲存很多資訊,在記憶體對齊關閉的情況下,乙個結構體占用的體積可以更小,這才是典型的用char比int更節約記憶體。

3樓:TheBadZhang

我想你不是活在上個世紀七八十年代的吧,這點東西居然還要挑著算。除了陣列之類,有較多資料,一百萬個往上吧,才可能需要考慮資料型別,但是,一百萬個 char 也才1MB,一百萬個 int32 才 4MB,你說你省什麼呢。(當然,省也是個好習慣,但你這並不能就對你那些迴圈做出什麼花來)

4樓:易水寒

之所以定義char,sint,int,lint就是為了節省記憶體和提公升效率,不然都用最大型就好了。但是你提的使用方式並不能節省記憶體,也沒有效率提公升!

5樓:D Flip Flop

單個區域性變數,有可能一直在暫存器裡,根本不佔記憶體,而暫存器是任意型別都要占用乙個的。

區域性變數也有可能放在棧上,但是由於對齊,很多情況下用什麼資料型別也不影響棧高度;實際上,只要不用很深的遞迴,棧溢位是很少發生的,棧高度對程式的影響也很小。

省記憶體的情況確實會有,比如說你把int[1000000000]改成char[1000000000],那還是能省幾個G記憶體的。

有個常見的技巧就是整數集合的分區間壓縮,例如有序陣列表示的集合:

uint16_tn=

14;uint16_ta[

14]=;

可以壓縮成三個區間

uint16_tn=

14,n_itv=4

;uint16_tof[

5]=;

uint8_thi[

4]=;

uint8_tlo[

14]=;

/* 壓縮,要求集合非空 */k=

-1;for(i

=0;i

[i]=

a[i]

&0xffu;}

n_itv=k

+1;of

[n_itv]=

n;/* 解壓 */

for(k=

0;k

k)}就能表示整個集合了。

由於快取容量、記憶體頻寬等限制,在不增加計算量的前提下,省記憶體就約等於提公升效能。如果壓縮與解壓的開銷比較小,這種壓縮也是很有意義的。

6樓:

其實程式浪費記憶體,也能從其他地方找回來。

現在windows有記憶體壓縮技術,記憶體壓縮能節省很多空間。

磁碟也一樣,帶壓縮功能的fs也能節省空間。

過早優化得不償失。

7樓:Yue Liao

我想起有個問題下的答案,答主測試計算1+2+...+100的迴圈並輸出結果,編譯器編譯的情況是直接輸出5050。。

這種問題交給編譯器去操心吧,好的編譯器比你想象的要精明多了。

8樓:pansz

其實說一點就夠了:只有大批量使用的時候才考慮節省記憶體。

比方說,題主要儲存乙個長度在百萬以上級別的陣列,此時陣列儲存為 int 跟 char 會有明顯區別。

又比方說,你要儲存的數對應螢幕上的乙個畫素,而通常整個螢幕的畫素數量在百萬級別,所以單個畫素用更小的型別儲存能夠節省記憶體。

還有,做遊戲的程式設計師計算物體位置尺寸等圖形相關的引數時,習慣使用float替代double,因為遊戲在全螢幕的渲染運算量也會達到百萬級別以上,因此用float比double節省資源。——然而如果這個數僅僅是邏輯運算,例如攻擊力計算,這種邏輯運算不需要乘以整個螢幕尺寸為開銷,那麼依然是應當使用double,而不應使用float。

除了以上這種,運算被大規模重複的情形,其他情形不要僅僅為了節省記憶體的原因使用char。

常規情形中使用char都沒有什麼收益。很多情況下,都是暫存器與立即數操作,這些操作的最小單位都是機器字長(32位或者64位),使用小於機器字長的資料型別進行常規操作往往不會有時間或者空間收益

9樓:飛在天空的牛

做嵌入式的工作尤其是使用微控制器時通常需要用到,編譯時需要宣告按位元組對齊,不過會降低程式程式在16位(及以上)匯流排微控制器上執行的效率

10樓:原來我是匿名

手機回覆,示例就不舉了,但大家都是從小白過來的,還是簡要把問題回覆一下吧。

次數較少的迴圈:

int i;

for(i=0; i<255; i++)

如果使用char會不會節約記憶體呢?

unsigned char i;

for(i=0; i<255; i++)

答覆:不會。非編譯優化情況下,從執行效率考慮,不會採用緊縮編譯,故使用char和int是相同的儲存空間,char產生了空洞而已。

在編譯優化時,迴圈次數由暫存器實現,由於現代計算機(包括嵌入式計算機)暫存器已經為32位或64位,故控制迴圈的變數用int或char等無影響,只是用的指令稍有區別。

p.s如果再考慮此類變數是區域性量,就更沒有影響了。

再例如,函式的傳值

void f(int n)

如果使用char會不會更快呢?

void f(char n)

答覆:不會。多數處理器採用棧傳遞或暫存器傳遞引數,其有固定的格式要求。小於暫存器寬度的變數都會被重新格式化。故不會提高效能,反倒由於需要截斷等而可能會降低效能。

一般而言,變數型別的使用是基於需求的,對沒有應用邏輯對應的區域性量,可以考慮執行平台的約束,多數會預設為uint或者int。對char和short等,如果不是結構體的格式要求或者陣列等要求,可以考慮用int或long替代。(嵌入式平台在少數情況下才回關注這些差異,一般也不用)。

題主能夠關注到這個使用差異,說明還是很細心的,可以多了解一下計算機硬體的原理,自然就融會貫通了。

至於程式設計規範和風格的問題,可以考慮找一下現成的編碼標準,多找幾個,對比著看,再實踐一下,就不會有太多糾結了。

11樓:呆靈

前幾天32位微控制器上優化程式,把臨時變數從uint16改為uint之後,時間從170ms變為了110ms,也就是說32位機器,對於i這裡的變數,unit最快,其次是int ,byte,short(int16)最慢。

char在長陣列時能節約記憶體,一兩個變數對記憶體幾乎沒有影響。

12樓:California.US

不一定,有些平台的記憶體空間是16位的,也就是乙個位址對應2個位元組的空間。在使用C語言的時候,編譯器(例如gcc)在這個平台上實現的char的寬度就是16,而不是8。

這就和short甚至是int一樣了。

這時如果把char看成8位,就可能出現各種意想不到的bug(舉個例子:char a = 1<<7,這時a < 0 是TRUE還是FALSE呢?)。

13樓:

就題目而言,使用char代替更大的資料型別有可能可以節約記憶體。就題主舉的例子來說,不能節約記憶體。

大部分答案說得並不準確。我們要定義什麼叫做節約記憶體?我想題主是想說的,從資源管理器中看到的記憶體提交量,也就指的是系統提交(commit)的記憶體量。

(我們知道幾乎所有系統都提供虛擬記憶體功能,它可以讓程式將部分短期用不到的記憶體換出到硬碟上,剩下的駐留在記憶體中的那些資料大小,我們稱作記憶體的工作集(working set)大小。記憶體清理軟體重新設定工作集迫使系統記憶體換入到磁碟,達到記憶體清理的假象)

在程序模型中,堆、棧分別處於程序位址空間的不同位置,它們並不是一開始就擁有物理記憶體,而是它們的這一段位址處於未分配的狀態。只有你使用到了它,系統才會為它調撥物理記憶體,也就是我們說的記憶體使用增加。

系統調撥物理記憶體是以頁大小為單位來進行調撥的,在windows中一頁的大小是4kb,也就是說每次調撥物理記憶體都應該是4kb的整數倍。

了解到以上資訊,題主舉的例子:

int i;

這裡的i是乙個臨時變數,根據編譯器的不同,以及優化級別的不同,它會被分配在棧上面,或者是直接分配在暫存器中。

1、假設它分配在棧上面,棧已經實現調撥到了物理記憶體,即便把int改變為char,它也不會使已經調撥的記憶體減少。要記得,一次調撥至少得是4k大小,區區乙個int並不會產生任何影響。

2、假設它分配到了暫存器上面,比如rcx,那麼這和記憶體壓根就沒有關係了。

那麼什麼情況下真的會對記憶體產生比較顯著的影響呢?

int*

array

=new

int[

4096

];// 如果是C,用malloc代替new

char

*array2

=new

char

[4096

];大概就是類似於以上這樣的情況吧。

14樓:「已登出」

會不會變快首先樓主要知道你的機器是多少位的。我舉個例子就能明白,32位機一次最多處理32位的資料,如果你要給64位整數賦值,那麼要分兩次操作。

你的for迴圈可以很明確告訴你,在16 ,32,64位機沒有區別,如果你的機器是8位機,那一定會變快

至於你的函式呼叫,得看編譯器是如何壓棧的了。

建議樓主不要在乎這些細節,區域性變數占用的是暫存器或者棧記憶體。棧記憶體的分配不需要在乎,分配和釋放只是棧指標的移動而已,分配多少個位元組,速度都是相同的。函式結束後就會釋放掉。

只要保證不會棧溢位即可

15樓:百里憐雪

不能,很多人說過了。

另外,學習程式設計的建議是,這類基礎知識還是要看書,可以先找找本科計算機專業書籍有哪些,細讀。

你不是這個專業的,不代表不能學好。同樣,如果你能學好,也並不意味著你不讀該專業的書就能學到足夠的知識。

論壇上確實能學到不少知識,但通常利用各種論壇學的知識,是那些還沒來得及被人整理沉澱成專業書籍的。如果有了,讀書效果要好得多。

16樓:張老三

分析記憶體占用首先需要明確平台,64位 32位 16位 8位,不一樣的。平台不一樣導致編譯器優化邏輯也不一樣的。

你舉的兩個for迴圈例子都是使用的區域性變數,這是占用棧區記憶體,棧的單位大小跟平台位址匯流排一致的,即如果是8位cpu 則棧的單位是8位,32位cpu則棧單位是32位。上面例子如果執行在32位cpu中則無論char 還是int 都是占用乙個棧單元即32位,這種情況下大家都一樣。如果是8位cpu則char 型別占用8位,而int 則占用16位或32位(編譯器確定),這種情況下char就要節約記憶體。

然後函式傳值問題,通常編譯器都是優先使用通用暫存器R0~R3 四個暫存器不夠才使用棧傳參,但你舉的例子無論8位還是32位都可以直接使用通用暫存器傳參,所以傳參不占用記憶體資源。

其他的程式設計風格問題,各家不一樣各人不一樣,自己習慣來就好,只是通常在運算子兩邊加上空格以凸顯運算子。

增加幾個圖內更加明顯看出來

8位cpu :

char 變數工程編譯出來data區即記憶體占用 8位元組的通用暫存器,2位元組的 i,j ,1位元組的棧底。

int 變數工程編譯出來data區即記憶體占用 8位元組的通用暫存器,4位元組的 i,j ,1位元組的棧底。

(這裡特別說明下c51 比較特殊的是通常區域性變數不是放在棧區,而是直接占用具體的位址上,由編譯器標記和記錄生命期。)

8位cpu char 變數

8位cpu int 變數

32位cpu 可以看出來在char 還是int RW-data都沒有區別 ,除非使用64位的 longlong 才有區別。

(這裡備註下,採用全域性變數是因為區域性變數都分配到棧上,棧空間變化靜態不容易看出 int char longlong 的區別。)

32位char

32位 cpu int

32位cpu longlong

C語言char怎麼讀

Char 吃啊兒 Init 硬離希哦 那姆達 String 斯君 Int 硬特 Erlang 兒浪 Panel 盤挪哦 我老是喜歡念盤內哦 還有啥讀不來的。發出來啊! WANGJIEKE 凱爾 ker 因為來自單詞character ker ik tr 一開始我也覺得是讀 猹 後來上了C 課老師吐槽...

c語言中為什麼不能用char 指向字元陣列?

心不變情依舊 char 是二級指標,表示指標的指標,就是把不連續的空間連線起來,第乙個指標指向char 而char 可以表示一階陣列。 喵NLI 因為char z不是指標,是直接存放於棧中的陣列,這種情況下r z與r z都是獲取到z這個陣列的位址而不是二級指標 charz hello char y ...

是否可以採集落葉作為燃料來節約煤炭使用和降低森林火災風險?

有類似技術,但是也有不少缺點,商業運營的沒有,實驗裝置是有的。首先不是簡單的焚燒,因為熱值不夠,含水量太高,直接燒需要新增額外燃料。所以一般是通過氣化爐氣化來生成生物合成氣。合成氣含CO,H2,以及其餘多種有機物。後續產業鏈結甲醇 乙醇 生物柴油等。然後說下缺點,一次投資大,運營成本高。和類似其他產...