2010-04-09 89 views
3

下面是找到一個結構的大小,而無需使用sizeof操作符的程序:爲什麼我的homeopen sizeof運算符需要char *轉換?

struct MyStruct 
{ 
    int i; 
    int j; 
}; 

int main() 
{ 
    struct MyStruct *p=0; 
    int size = ((char*)(p+1))-((char*)p); 
    printf("\nSIZE : [%d]\nSIZE : [%d]\n", size); 
    return 0; 
} 

爲什麼類型轉換爲char *必需的?

如果我不使用char *指針,輸出爲1 - 爲什麼?

+0

提醒:結構的大小可能不等於其成員(字段)大小的總和。編譯器允許在結構中的成員之間插入填充字節。一個例子是在地址上對齊處理器有效的變量來獲取。 – 2010-04-09 17:22:06

回答

2

由於指針運算以指向的類型爲單位進行工作。例如:

int* p_num = malloc(10 * sizeof(int)); 
int* p_num2 = p_num + 5; 

這裏,p_num2沒有一點五個字節超越p_num,它分5個整數超越p_num。如果在您的機器上整數是四個字節寬,則存儲在p_num2中的地址將比p_num中存儲的地址長20個字節。其原因主要是指針可以像數組一樣索引。 p_num[5]*(p_num + 5)完全等價,所以指針算術總是以字節爲單位是沒有意義的,否則p_num[5]會給你一些在第二個整數中間開始的數據,而不是像你那樣給你第六個整數期望。

爲了移動的字節特定數目超出一個指針,就需要轉換指針以指向被保證是完全1個字節寬類型(一個char)。

而且,你這裏有一個錯誤:

printf("\nSIZE : [%d]\nSIZE : [%d]\n", size); 

你有兩種格式說明,但在格式字符串後只有一個參數。

2

如果我不使用char *指針,則輸出爲1 - 爲什麼?
因爲operator-服從與operator+相同的指針算術規則。當您向指針中添加一個指針時,您增加了sizeof(MyStruct),但是如果沒有該指針,您將在指針的operator-中將sizeof(MyStruct)的字節差值除以sizeof(MyStruct)

爲什麼不使用sizeof()內置運算符?

+1

如果確實使用'sizeof',請務必在指向的對象上使用它,而不是指針本身。 'sizeof(p)'會給你一個指針的大小,其中'sizeof(* p)'會給你一個'MyStruct'的大小。 – 2010-04-09 14:52:46

2

因爲你想要你的結構的大小以字節爲單位。而指針算術隱式使用字體大小。

int* p; 
p + 5; // this is implicitly p + 5 * sizeof(int) 

通過鑄造到char *你規避了這種行爲。

+1

好吧,'sizeof'返回大小,以'char'存儲的大小爲單位(即sizeof(char)總是1)。這是典型實現中的字節數,但並不是必需的...... – dmckee 2010-04-09 14:53:08

+0

這是真的,但每當你要求字節類型時,你都會得到無符號字符的答案:) – 2010-04-09 14:56:19

1

指針運算是根據指針類型的大小定義的。這允許(例如)指針算術和數組下標之間的等價性 - *(ptr+n)相當於ptr[n]。當你減去兩個指針時,你會看到他們指向的項目數量的差異。投到pointer to char意味着它告訴你這些地址之間的字符數。由於C使得charbyte基本上等同(即一個字節是一個字符所需的存儲空間),這也是第一項所佔用的字節數。

相關問題