高级C语言教程
8K的字節(jié),看上去沒(méi)有問(wèn)題,但是編譯器對(duì)局部變量有兩種優(yōu)化的方法,第一種:對(duì)于簡(jiǎn)單的數(shù)據(jù)類型的變量比如(char ,int,short或者指變量等)編譯器會(huì)盡可能的采用CPU內(nèi)部通用寄存器,因?yàn)閮?nèi)部通用寄存器的訪問(wèn)速度遠(yuǎn)遠(yuǎn)高于外部存儲(chǔ)器的訪問(wèn)速度;第二種方式是對(duì)于那些那些沒(méi)有辦法使用寄存器 表示的變量或者數(shù)組/結(jié)構(gòu)體等變量采用當(dāng)前堆棧空間存儲(chǔ),,顯然8K在嵌入式程序中和可能耗盡堆棧的資源。
深刻的理解存儲(chǔ)器,每一個(gè)存儲(chǔ)器都有兩個(gè)屬性:以上存儲(chǔ)器里面存儲(chǔ)的內(nèi)容;而是存儲(chǔ)器的地址。
嵌入式開(kāi)發(fā)的一個(gè)重要的特點(diǎn)就是交叉編譯,也就是開(kāi)發(fā)工具運(yùn)行環(huán)境和被調(diào)試的程序不是運(yùn)行在同一個(gè)硬件平臺(tái)(處理器上)。
變量的存儲(chǔ)類型?存儲(chǔ)變量值的存儲(chǔ)類型,變量存儲(chǔ)類型決定了變量何時(shí)創(chuàng)建、何時(shí)銷毀以及其值能夠保存多久,在C語(yǔ)言中的變量能夠存放3個(gè)不同的地方:普通內(nèi)存、運(yùn)行時(shí)的堆棧、CPU內(nèi)部的通用寄存器,,堆棧當(dāng)然也是內(nèi)存,但是相對(duì)于簡(jiǎn)單的內(nèi)存來(lái)說(shuō)堆棧變化更加的頻繁,堆棧往往是用來(lái)存放暫存數(shù)據(jù)的。
變量的存儲(chǔ)類型首先取決于它的聲明位置,凡是在函數(shù)外聲明的變量都是全局變量(默認(rèn)情況下全局變量的作用域僅限于聲明該變量的C文件中,如果希望在該C文件之外能夠訪問(wèn)這個(gè)變量,程序員就需要在引用該變量的C文件之中進(jìn)行外部extern進(jìn)行聲明),編譯器在編譯的過(guò)程中將全局變量映射到普通內(nèi)存之中,在程序的整個(gè)執(zhí)行期間該變量始終占用編譯器為它分配的內(nèi)存空間,它始終保持原來(lái)的值直到對(duì)這個(gè)變量進(jìn)行賦值操作或者程序結(jié)束,所以有時(shí)我們也稱全局變量為靜態(tài)的。
static關(guān)鍵字可能是C語(yǔ)言中較多義的一個(gè)關(guān)鍵字,該關(guān)鍵字的具體含義取決于該關(guān)鍵字的不同的上下文,static關(guān)鍵字的三個(gè)不同的用途:
1.如果static對(duì)函數(shù)內(nèi)部的局部變量聲明時(shí),static關(guān)鍵字的作用是改變局部變量的存儲(chǔ)類型,從自動(dòng)變量改為靜態(tài)變量,也就是說(shuō)這個(gè)局部變量不在存儲(chǔ)在堆棧或者寄存器中,而是編譯的時(shí)候由編譯器分配一個(gè)靜態(tài)的地址空間,但是這個(gè)變量的作用域不受影響,依然僅局限于聲明它的函數(shù)內(nèi)部才能夠訪問(wèn),需要說(shuō)明的是一旦函數(shù)內(nèi)部的局部變量被聲明為static,這個(gè)函數(shù)就有可能不得重入;
2.如果static關(guān)鍵字被用于函數(shù)的定義的時(shí)候,這個(gè)函數(shù)就只能在定義的C文件之中使用,該C文件之外的代碼將無(wú)法調(diào)用這個(gè)函數(shù);
3.如果使用static對(duì)全局變量進(jìn)行聲明時(shí),static關(guān)鍵字是的作用,類似于聲明函數(shù)的情況,這個(gè)全局變量的作用域?qū)⒕窒拊诼暶髟撟兞康腃文件內(nèi)部,這個(gè)C文件之外的代碼將無(wú)法訪問(wèn)這個(gè)變量(事實(shí)上采用指針的方式能夠訪問(wèn),但是既然聲明成static的類型為什么要違背當(dāng)初聲明變量的初衷呢)。
struct關(guān)鍵字
面對(duì)一個(gè)C程序的時(shí)候,只看其中struct的使用情況我們就可以對(duì)其編寫者的編程經(jīng)驗(yàn)進(jìn)行評(píng)估,從一定的程度上來(lái)說(shuō)會(huì)不會(huì)使用struct、怎樣使用struct是區(qū)別一個(gè)開(kāi)發(fā)人員是否具備豐富開(kāi)發(fā)經(jīng)驗(yàn)的標(biāo)志。
結(jié)構(gòu)是有若干的(可不同類型的)數(shù)據(jù)項(xiàng)組合成符合數(shù)據(jù)對(duì)象,這些數(shù)據(jù)稱為結(jié)構(gòu)的成分或成員。
(1)牛逼的位域
有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié),而只需占一個(gè)或幾個(gè)二進(jìn)制位。例如在存放一個(gè)開(kāi)關(guān)量時(shí),只有0和1兩種狀態(tài),用一個(gè)二進(jìn)制位即可。為了節(jié)省存儲(chǔ)空間并使處理簡(jiǎn)便,C語(yǔ)言又提供了一種數(shù)據(jù)結(jié)構(gòu),稱為”位域”或者”位段”。所謂”位域”是把一個(gè)字節(jié)中的二進(jìn)制位劃分為幾個(gè)不同的區(qū)域,并說(shuō)明每個(gè)區(qū)域的的位數(shù)。每個(gè)域有一個(gè)域名,允許在程序中按照域名進(jìn)行操作。這樣就可以將幾個(gè)不同的對(duì)象用一個(gè)字節(jié)的二進(jìn)制進(jìn)行表示。。位域的定義和位域變量的說(shuō)明位域定義與結(jié)構(gòu)定義相仿,其形式為:
struct 位域結(jié)構(gòu)名
{位域列表};
例如:
由于位域不允許跨兩個(gè)字節(jié),因此位域的長(zhǎng)度不能大于1字節(jié)長(zhǎng)度,也就是說(shuō)不能超過(guò)8位二進(jìn)制位。
結(jié)構(gòu)體內(nèi)部的成員的對(duì)齊
在計(jì)算結(jié)構(gòu)體長(zhǎng)度時(shí)(尤其使用sizeof),需要注意根據(jù)不同的編譯器和處理器,結(jié)構(gòu)體內(nèi)部的成員有不同的對(duì)其方式,這回引起結(jié)構(gòu)體長(zhǎng)度的不確定性。
結(jié)構(gòu)體的某個(gè)成員相對(duì)于結(jié)構(gòu)體首地址的偏移量可以通過(guò)宏offsetof()來(lái)獲取,這個(gè)宏在stddef.h中定義如下:
大小端模式:
#include <stdio.h>void Get_Cont(void); typedef unsigned char BYTE;int main() {unsigned int num,*p;p = #*(BYTE *)p = 0xff;Get_Cont();if(num == 0xff){printf("The endian of cpu is little\n");goto massge;}else{printf("The endian of cpu is big\n");}printf("Hello, World!\n");massge:printf("The endian of cpu is little\n");return 0; }void Get_Cont(void) {printf("Get_Count!\n"); }輸出
Get_Count! The endian of cpu is little The endian of cpu is little枚舉是一種用于定義一組常量的機(jī)制,以這種方式定義的常量一般稱為枚舉常量,,一個(gè)枚舉說(shuō)明不但引入一組常量名,同事還為每一組常量確定了一組整數(shù)值,在默認(rèn)的情況下其第一個(gè)常量自動(dòng)的賦值0,隨后的常量值順序的遞增。
(1)賦值的枚舉常量,與給變量賦值一樣,如果給一個(gè)枚舉常量賦值,跟隨其后的沒(méi)有指定值的枚舉常量也將跟著順序遞增取值,直到下一個(gè)有指定值的常量為止。
const關(guān)鍵字,ANSI中允許程序員利用const關(guān)鍵字聲明一個(gè)變量是“只讀”的。
const int a; int const a; //含義是一樣的,都是聲明整數(shù)變量a是只讀的,可以根據(jù)自己好理解的形式進(jìn)行編寫; const int *a; //聲明一個(gè)指向整數(shù)的指針變量a,這個(gè)指針的值是可以改變的,但是這個(gè)指針?biāo)赶虻臄?shù)值(*a)是不可以改變的; int * const a; //聲明一個(gè)指向整數(shù)的指針變量a,這個(gè)指針的值是只讀的,但是所指向整數(shù)數(shù)值(*a)是可以改變的; int const * const a; //聲明一個(gè)指針變量a,不管這個(gè)指針變量的值還是指針變量所指向的整數(shù)值都是只讀的,是不可改變的;sizeof是一個(gè)C語(yǔ)言的關(guān)鍵字,許多程序員以為sizeof是一個(gè)函數(shù),而實(shí)際上它是一個(gè)關(guān)鍵字,同時(shí)也是一個(gè)操作符sizeof關(guān)鍵字的作用就是返回一個(gè)對(duì)象或者類型所占的內(nèi)存字節(jié)數(shù)
sizeof中看指針與數(shù)組的區(qū)別
volatile關(guān)鍵字
一個(gè)定義為volatile的變量可能會(huì)被意想不到的改變,這樣編譯器就不會(huì)假設(shè)這個(gè)變量的值了。精確的說(shuō)就是,優(yōu)化器在使用到這個(gè)變量時(shí)必須每次都小心的重新的讀取這個(gè)變量的數(shù)值,而不是使用保存在寄存器里面的備份。
總結(jié)
- 上一篇: 作者:王题(1976-),男,中国联合网
- 下一篇: 第三届“空间信息网络”学术论坛诚邀您的参