天天看點

sizeof函數的使用及其在DSP中的應用1 簡介2 用法3 DSP中sizeof的用法4 sizeof的用法問題5 其他相關問題

sizeof函數的使用及其在DSP中的應用

  • 1 簡介
  • 2 用法
    • 2.1 基本資料類型的sizeof
    • 2.2 指針變量的sizeof
    • 2.3 數組的sizeof
    • 2.4 結構體的sizeof
  • 3 DSP中sizeof的用法
  • 4 sizeof的用法問題
    • 4.1 問題描述
    • 4.2 問題分析
    • 4.3 經驗總結
  • 5 其他相關問題

1 簡介

sizeof是C/C++中的一個操作符(operator),簡單的說其作用就是傳回一個對象或者類型所占的記憶體位元組數。

2 用法

C語言中,對 sizeof() 的處理都是在編譯階段進行,是以它可以被當作常量表達式使用。其作用就是傳回一個對象或者類型所占的記憶體位元組數。

這裡的類型是指資料類型,比如int、long、數組、指針、結構體等。

這裡的對象可以是變量、資料類型、函數調用。

記憶體位元組數來源于儲存器中的概念。存儲器的容量是以位元組為基本機關的。也就是說一個記憶體位址代表一個位元組的存儲空間。

sizeof計算對象的大小也是轉換成對對象類型的計算,也就是說,同種類型的不同對象其sizeof值都是一緻的。sizeof對一個表達式求值,編譯器根據表達式的最終結果類型來确定大小,一般不會對表達式進行計算。

特别的,sizeof也可以對一個函數調用求值,其結果是函數傳回類型的大小,函數并不會被調用;函數、不能确定類型的表達式以及位域(bit-field)成員不能被計算sizeof值。

具體用法如下:

sizeof(type_name);//sizeof(類型);
sizeof object;//sizeof對象;
           

舉例說明:

int i;
sizeof(i);//ok
sizeof i;//ok
sizeof(int);//ok
sizeof int;//error
           

下面依次舉例介紹部分資料類型和對象的具體應用。

2.1 基本資料類型的sizeof

這裡的基本資料類型指short、int、long、float、double這樣的簡單内置資料類型,由于它們都是和系統相關的,是以在不同的系統下取值可能不同。

一般的,在32位編譯環境中,sizeof(int)的取值為4。

2.2 指針變量的sizeof

指針變量,是指可以用來存放另一個對象的位址的變量。指針變量裡面存放的是指針,即位址。在不同的系統中,位址的表示位數不同。如在32位系統中,位址是32位表示的。

當一個位元組8位時,在32為系統中,說一個儲存器的位址範圍一般是說 0x 00 00 00 00 ~ 0x 00 00 4F 00;而在16位系統中,位址是該範圍是說0x 00 00~ 0x 4F 00。

綜上,在32位計算機中,一個指針變量的sizeof傳回值通常是4,在64位系統中指針變量的sizeof的傳回值通常為8。

指針變量的在C語言中的定義是為了為指向的對象預配置設定記憶體位址。指針變量的sizeof值與指針所指的對象沒有任何關系,是以同一系統中所有的指針變量所占記憶體大小相等。

2.3 數組的sizeof

數組的sizeof值等于數組所占用的記憶體位元組數。

注意:字元串數組,最後一個還有終止符。

2.4 結構體的sizeof

結構體在記憶體中是按照一定的原則進行存儲的。

原則1:資料成員對齊規則:結構(struct或聯合union)的資料成員,第一個資料成員放在offset為0的地方,以後每個資料成員存儲的起始位置要從該成員大小的整數倍開始(比如int在32位機為4位元組,則要從4的整數倍位址開始存儲)。

原則2:結構體作為成員:如果一個結構裡有某些結構體成員,則結構體成員要從其内部最大元素大小的整數倍位址開始存儲。(struct a裡存有struct b,b裡有char,int,double等元素,那b應該從8的整數倍開始存儲。)

原則3:收尾工作:結構體的總大小,也就是sizeof的結果,必須是其内部最大成員的整數倍,不足的要補齊。

是以

1 結構體sizeof的結果不是簡單的加所有成員的位元組數相加;

2 結構體sizeof的結果和不同資料類型在結構體中的位置有關;比如:

struct A{
	int a;
    char b;
    short c;
   };
           
struct B{
	char b;
	int a;
	short c;
    };
           

在32位作業系統中,sizeof(A)的結果是8;sizeof(A)的結果是12。

這是因為在記憶體中的存儲如下:

a b c

A的記憶體布局:1111, 1*, 11

b a c

B的記憶體布局:1***, 1111, 11**

其中,*表示補充。

3 DSP中sizeof的用法

sizeof傳回的是記憶體位元組數。記憶體位元組數來源于儲存器中的概念。存儲器的容量是以位元組為基本機關的。也就是說一個記憶體位址代表一個位元組的存儲空間。

對于其他一般的處理器,一個記憶體位址是8位。但在DSP中,一個記憶體位址不一定是8位。以TI的C2000為例,一個記憶體位址是16位。

下圖為28033的記憶體映射圖:

sizeof函數的使用及其在DSP中的應用1 簡介2 用法3 DSP中sizeof的用法4 sizeof的用法問題5 其他相關問題

圖中,一個記憶體位址對應16位,以L0 SARAM為例,位址0x00 8000~0x00 8800,記憶體位址長度為0x800 = 2K,而一個記憶體位址16位,是以L0 SARAM的存儲大小為2K x 16。

4 sizeof的用法問題

4.1 問題描述

在TI的C2000中,使用sizeof得到結構體的記憶體位元組數,當結構體中隻定義一個Uint16的變量時,sizeof的傳回值為1;結構體中有一個int32 和int16時,傳回值為4。

如下:

struct {
		Uint32	Ver0;
		Uint16	Ver1;
} infoVersion_P;	   
           

sizeof(infoVersion_P)的結果是4。

struct {
    Uint16	Ver1;
} infoVersion_P1;	   
           

sizeof(infoVersion_P1)的結果是1。

4.2 問題分析

DSP使用的是28033,該晶片一個位址對應16位。是以結構體隻有Uint16一個成員的時候,sizeof的傳回值是1。

結構體在存儲的時候,記憶體對齊。是以,結構體中有一個int32 和int16時,占用的是4個位址。是以sizeof的傳回值是4。

4.3 經驗總結

要使用sizeof來傳回結構體的記憶體位元組數時,定義的結構體最好按照32位,便于後期和其他人維護。

5 其他相關問題

在查詢資料時發現,C2000中除了一個位址對應16位是非正常的,還有關于char也是非正常的。char是16位的定義。

還是以28033為例,其使用的CPU如資料手冊所示:

sizeof函數的使用及其在DSP中的應用1 簡介2 用法3 DSP中sizeof的用法4 sizeof的用法問題5 其他相關問題

而該CPU中關于資料類型的定義如下:

sizeof函數的使用及其在DSP中的應用1 簡介2 用法3 DSP中sizeof的用法4 sizeof的用法問題5 其他相關問題

使用編譯器甄别,分别給一個char變量指派16位和32為數值,指派16為數值,編譯器正常無問題;指派32為,編譯器報錯。是以,char确實是16位的。

繼續閱讀