- 相關推薦
C語言初始化效率問題及關鍵字解釋
C語言是一門通用計算機編程語言,應用廣泛。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。下面是小編整理的C語言初始化效率問題及關鍵字解釋,希望能夠幫助到大家。
一、初始化效率
1、在靜態變量的初始化中,我們可以把可執行程序文件想要初始化的值放在當程序執行時變量將會使用的位置。當可執行文件載入到內存時,這個已經保存了正確初始值的位置將賦值給那個變量,完成這個任務并不需要額外的時間,也不需要額外的指令,變量將會得到正確的值、
2、自動變量當程序鏈接時還無法判斷自動變量的存儲位置。事實上,函數的局部變量在函數的每次調用中可能占據不同的位置。基于這個理由,自動變量沒有缺省的初始值,而顯示的初始化將在代碼塊的其實出插入一條隱式的賦值語句。
一句話總結;局部變量的初始化與分開寫毫無區別
即什么時候使用變量什么時候聲明,盡量重用,不要讓他隱式初始化,浪費內存static 關鍵字的修飾。
當它用于函數定義時,或用于代碼塊之外的變量聲明時,static關鍵字用于修改標識符的鏈接屬性,從external改為internal,但標識符的存儲類型和作用域不受影響。用這種方式聲明的函數或變量只能在聲明他們的源文件中訪問。
總結:
一下以文件解釋
int a;
//a 變量存儲在靜態內存
特點:
在程序運行之前創建
可以被其他的C文件訪問以及它的下方函數使用
初始化值為0
=================
static int a;
特點:在程序運行之前存在
靜態內存存儲
不能被其他文件訪問
================
代碼塊中的變量
static int a ;
靜態變量
與int a ;(局部變量)
的區別是:
一個存儲在靜態內存 也就是普通內存
另一個是局部變量,也就是運行時堆棧
函數上添加static的話:
不能被其他的文件訪問該函數
幾個關鍵字的處理
static 靜態內存
auto 運行時堆棧
register 硬件寄存器
external 引用外部文件變量函數
internal 引用內部文件變量函數
=======================
關于代碼塊變量被static修飾
保證該函數多次調用時,我們為了防止該變量不變
進行的處理比如我們進行了多次的調用
二、關鍵字解釋
變量的存儲類型(storage class )是指存儲變量值的內存類型。變量的存儲類型決定變量何時創建、何時銷毀以及它的值將保持多久。有三個地方可以用于存儲變量:普通內存、運行時堆棧、硬件寄存器。在這三個地方存儲的變量具有不同的特性。
變量的缺省存儲類型取決于它的聲明位置。凡是在任何代碼塊之外聲明的變量總是存儲于靜態內存中,也就是不屬于堆棧的內存,這類變量成為靜態變量。對于這類變量,你無法為他們制定其他存儲類型。
靜態變量在程序運行之前創建,在程序的整個執行期間始終存在。它始終保持原先的值,除非給它賦一個不同的值或者程序結束。
在代碼塊內部聲明的變量的缺省存儲類型是自動的(automatic),也就是說他存儲于堆棧中,成為自動變量。有一個關鍵字auto就是用修飾這種存儲類型的,但它極少使用,因為代碼塊中的變量在缺省情況下就是自動變量在程序執行到聲明自動變量的代碼塊時,自動變量才被創建,當程序的執行流離開該代碼時,這些自動變量便自行銷毀。如果該代碼塊被數次執行,例如一個函數被反復調用,這些自動變量每次都將重新創建。在代碼塊再次執行時,這些自動變量在堆棧中所占據的內存位置有可能和原先的位置相同,也可能不同。及時他們所占據的位置相同,你也不能保證這塊呢村同時不會有其他的用途,因此,我們可以說自動變量在代碼塊執行完畢后就消失。當代碼塊再次執行時,他們的值一般并不是上次執行時的值。
對于在代碼塊內部聲明的變量,如果給它加上關鍵字static,可以使他的存儲類型從自動變為靜態。具有靜態存儲類型的變量在整個程序執行過程中一直存在,而不僅僅在聲明它的代碼塊的執行時存在。注意,修改變量的存儲類型并不標示修改該變量的作用域,它任然只能在該代碼塊內部按名字訪問。函數的形式參數不能聲明。
最后,關鍵字register可以用于自動變量的聲明,提示他們應該存儲于機器的硬件寄存器而不是內存中,這類變量稱為寄存器變量。通常,寄存器變量比存儲于內存的變量訪問起來效率更高。但是,編譯器并不一定要理財register關鍵字,如果有太多的變量被聲明為register,它只選取前幾個實際存儲于寄存器中,其余的就按普通自動比那輛處理。如果一個編譯器自己具有一套寄存器優化方法,它可能忽略register關鍵字,
使用:使用說明,為了加快程序的編譯速度,你希望把使用頻率最高的那些變量聲明為寄存器變量,在有些計算機中,如果你把指針聲明為寄存器變量,程序的效率將能得到提高,有其是那些頻繁的執行間接訪問操作的指針,你可以把函數的形式參數聲明為寄存器變量,編譯器會在函數的起始位置生成指令,把這些值從堆棧復制到寄存器中。但是,完全有可能,這個優化措施所節省的時間和控件的開銷還抵不上復制這幾個值所用的開銷。
寄存器變量的創建和銷毀時間和自動變量相同,但它需要一些額外的工作。在一個使用寄存器變量的函數返回之前,這些寄存器先前存儲的值必須恢復,確保調用者的寄存器變量未被破壞。許多機器使用運行時堆棧來完成這個任務。當函數開始執行時,它把需要使用的所有寄存器的內容都保存到堆棧中,當函數返回時,這些值再復制回寄存器中。在許多機器的硬件實現中,并不為寄存器指定的地址。同樣由于寄存器值的保存和恢復某一個特定的寄存器在不同的時刻所保存的值不一定相同。基于這些理由,機器并不像你提供寄存器變量的地址。
拓展:C語言的reduce方法應用
一般而言,可以通過reduce方法實現的邏輯都可以通過forEach方法來變相的實現,雖然不清楚瀏覽器的js引擎是如何在C++層面實現這兩個方法,但是可以肯定的是reduce方法肯定也存在數組的遍歷,在具體實現細節上是否針對數組項的操作和存儲做了什么優化,則不得而知。
數組的reduce方法的應用
reduce方法有兩個參數,第一個參數是一個callback,用于針對數組項的操作;第二個參數則是傳入的初始值,這個初始值用于單個數組項的操作。需要注意的是,reduce方法返回值并不是數組,而是形如初始值的經過疊加處理后的操作。
reduce方法最常見的場景就是疊加。
var items = [10, 120, 1000];// our reducer functionvar reducer = function add(sumSoFar, item) { return sumSoFar + item; };// do the jobvar total = items.reduce(reducer, 0);console.log(total); // 1130
可以看出,reduce函數根據初始值0,不斷的進行疊加,完成最簡單的總和的實現。
前文中也提到,reduce函數的返回結果類型和傳入的初始值相同,上個實例中初始值為number類型,同理,初始值也可為object類型。
var items = [10, 120, 1000];// our reducer functionvar reducer = function add(sumSoFar, item) { sumSoFar.sum = sumSoFar.sum + item; return sumSoFar;};// do the jobvar total = items.reduce(reducer, {sum: 0});console.log(total); // {sum:1130}
多重疊加
使用reduce方法可以完成多維度的數據疊加。如上例中的初始值{sum: 0} ,這僅僅是一個維度的操作,如果涉及到了多個屬性的疊加,如{sum: 0,totalInEuros: 0,totalInYen: 0} ,則需要相應的邏輯進行處理。
在下面的方法中,采用分而治之的方法,即將reduce函數第一個參數callback封裝為一個數組,由數組中的每一個函數單獨進行疊加并完成reduce操作。所有的一切通過一個manager函數來管理流程和傳遞初始參數。
var manageReducers = function(reducers) { return function(state, item) { return Object.keys(reducers).reduce( function(nextState, key) { reducers[key](state, item); return state; }, {} ); }};
上面就是manager函數的實現,它需要reducers對象作為參數,并返回一個callback類型的函數,作為reduce的第一個參數。在該函數內部,則執行多維的疊加工作( Object.keys() )。
通過這種分治的思想,可以完成目標對象多個屬性的同時疊加,完整代碼如下:
var reducers = { totalInEuros : function(state, item) { return state.euros += item.price * 0.897424392; }, totalInYen : function(state, item) { return state.yens += item.price * 113.852; }};var manageReducers = function(reducers) { return function(state, item) { return Object.keys(reducers).reduce( function(nextState, key) { reducers[key](state, item); return state; }, {} ); }};var bigTotalPriceReducer = manageReducers(reducers);var initialState = {euros:0, yens: 0};var items = [{price: 10}, {price: 120}, {price: 1000}];var totals = items.reduce(bigTotalPriceReducer, initialState);console.log(totals);
總結
以上就是Javascript中內建函數reduce應用的全部內容,希望本文的內容對大家的學習或者工作能有所幫助,如果有疑問大家可以留言交流。
【C語言初始化效率問題及關鍵字解釋】相關文章:
C語言關鍵字及其解釋03-10
C語言關鍵字RESTRICT介紹10-25
C語言中volatile關鍵字分析03-30
C語言必須知道的關鍵字12-03
C語言的關鍵字和控制語句有哪些01-04
C語言標準定義的32個關鍵字11-30
C語言如何提高程序效率04-10
C語言八皇后問題12-04
C語言的可變參數問題03-20