高级C语言教程
8K的字節,看上去沒有問題,但是編譯器對局部變量有兩種優化的方法,第一種:對于簡單的數據類型的變量比如(char ,int,short或者指變量等)編譯器會盡可能的采用CPU內部通用寄存器,因為內部通用寄存器的訪問速度遠遠高于外部存儲器的訪問速度;第二種方式是對于那些那些沒有辦法使用寄存器 表示的變量或者數組/結構體等變量采用當前堆棧空間存儲,,顯然8K在嵌入式程序中和可能耗盡堆棧的資源。
深刻的理解存儲器,每一個存儲器都有兩個屬性:以上存儲器里面存儲的內容;而是存儲器的地址。
嵌入式開發的一個重要的特點就是交叉編譯,也就是開發工具運行環境和被調試的程序不是運行在同一個硬件平臺(處理器上)。
變量的存儲類型?存儲變量值的存儲類型,變量存儲類型決定了變量何時創建、何時銷毀以及其值能夠保存多久,在C語言中的變量能夠存放3個不同的地方:普通內存、運行時的堆棧、CPU內部的通用寄存器,,堆棧當然也是內存,但是相對于簡單的內存來說堆棧變化更加的頻繁,堆棧往往是用來存放暫存數據的。
變量的存儲類型首先取決于它的聲明位置,凡是在函數外聲明的變量都是全局變量(默認情況下全局變量的作用域僅限于聲明該變量的C文件中,如果希望在該C文件之外能夠訪問這個變量,程序員就需要在引用該變量的C文件之中進行外部extern進行聲明),編譯器在編譯的過程中將全局變量映射到普通內存之中,在程序的整個執行期間該變量始終占用編譯器為它分配的內存空間,它始終保持原來的值直到對這個變量進行賦值操作或者程序結束,所以有時我們也稱全局變量為靜態的。
static關鍵字可能是C語言中較多義的一個關鍵字,該關鍵字的具體含義取決于該關鍵字的不同的上下文,static關鍵字的三個不同的用途:
1.如果static對函數內部的局部變量聲明時,static關鍵字的作用是改變局部變量的存儲類型,從自動變量改為靜態變量,也就是說這個局部變量不在存儲在堆?;蛘呒拇嫫髦?#xff0c;而是編譯的時候由編譯器分配一個靜態的地址空間,但是這個變量的作用域不受影響,依然僅局限于聲明它的函數內部才能夠訪問,需要說明的是一旦函數內部的局部變量被聲明為static,這個函數就有可能不得重入;
2.如果static關鍵字被用于函數的定義的時候,這個函數就只能在定義的C文件之中使用,該C文件之外的代碼將無法調用這個函數;
3.如果使用static對全局變量進行聲明時,static關鍵字是的作用,類似于聲明函數的情況,這個全局變量的作用域將局限在聲明該變量的C文件內部,這個C文件之外的代碼將無法訪問這個變量(事實上采用指針的方式能夠訪問,但是既然聲明成static的類型為什么要違背當初聲明變量的初衷呢)。
struct關鍵字
面對一個C程序的時候,只看其中struct的使用情況我們就可以對其編寫者的編程經驗進行評估,從一定的程度上來說會不會使用struct、怎樣使用struct是區別一個開發人員是否具備豐富開發經驗的標志。
結構是有若干的(可不同類型的)數據項組合成符合數據對象,這些數據稱為結構的成分或成員。
(1)牛逼的位域
有些信息在存儲時,并不需要占用一個完整的字節,而只需占一個或幾個二進制位。例如在存放一個開關量時,只有0和1兩種狀態,用一個二進制位即可。為了節省存儲空間并使處理簡便,C語言又提供了一種數據結構,稱為”位域”或者”位段”。所謂”位域”是把一個字節中的二進制位劃分為幾個不同的區域,并說明每個區域的的位數。每個域有一個域名,允許在程序中按照域名進行操作。這樣就可以將幾個不同的對象用一個字節的二進制進行表示。。位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為:
struct 位域結構名
{位域列表};
例如:
由于位域不允許跨兩個字節,因此位域的長度不能大于1字節長度,也就是說不能超過8位二進制位。
結構體內部的成員的對齊
在計算結構體長度時(尤其使用sizeof),需要注意根據不同的編譯器和處理器,結構體內部的成員有不同的對其方式,這回引起結構體長度的不確定性。
結構體的某個成員相對于結構體首地址的偏移量可以通過宏offsetof()來獲取,這個宏在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枚舉是一種用于定義一組常量的機制,以這種方式定義的常量一般稱為枚舉常量,,一個枚舉說明不但引入一組常量名,同事還為每一組常量確定了一組整數值,在默認的情況下其第一個常量自動的賦值0,隨后的常量值順序的遞增。
(1)賦值的枚舉常量,與給變量賦值一樣,如果給一個枚舉常量賦值,跟隨其后的沒有指定值的枚舉常量也將跟著順序遞增取值,直到下一個有指定值的常量為止。
const關鍵字,ANSI中允許程序員利用const關鍵字聲明一個變量是“只讀”的。
const int a; int const a; //含義是一樣的,都是聲明整數變量a是只讀的,可以根據自己好理解的形式進行編寫; const int *a; //聲明一個指向整數的指針變量a,這個指針的值是可以改變的,但是這個指針所指向的數值(*a)是不可以改變的; int * const a; //聲明一個指向整數的指針變量a,這個指針的值是只讀的,但是所指向整數數值(*a)是可以改變的; int const * const a; //聲明一個指針變量a,不管這個指針變量的值還是指針變量所指向的整數值都是只讀的,是不可改變的;sizeof是一個C語言的關鍵字,許多程序員以為sizeof是一個函數,而實際上它是一個關鍵字,同時也是一個操作符sizeof關鍵字的作用就是返回一個對象或者類型所占的內存字節數
sizeof中看指針與數組的區別
volatile關鍵字
一個定義為volatile的變量可能會被意想不到的改變,這樣編譯器就不會假設這個變量的值了。精確的說就是,優化器在使用到這個變量時必須每次都小心的重新的讀取這個變量的數值,而不是使用保存在寄存器里面的備份。
總結
- 上一篇: 作者:王题(1976-),男,中国联合网
- 下一篇: 第三届“空间信息网络”学术论坛诚邀您的参