2014-02-07 45 views
0

在我介紹操作系統的過程中,我們的任務是確定一個系統是大還是小的。我已經找到了很多關於如何去做的結果,並且我已經盡我所能來重建自己的代碼版本。我懷疑這是不是做的最好的方式,但它似乎工作:鑄造char *對int的引用做了什麼? (使用C)

#include <stdio.h> 
int main() { 
    int a = 0x1234; 
    unsigned char *start = (unsigned char*) &a; 
    int len = sizeof(int); 

    if(start[0] > start[ len - 1 ]) { 
     //biggest in front (Little Endian) 
     printf("1"); 
    } else if(start[0] < start[ len - 1 ]) { 
     //smallest in front (Big Endian) 
     printf("0"); 
    } else { 
     //unable to determine with set value 
     printf("Please try a different integer (non-zero). "); 
    } 
} 

我已經看到了這行代碼(或某些版本),在幾乎所有的答案,我已經看到了:

unsigned char *start = (unsigned char*) &a; 

這裏發生了什麼事?我通常理解施法,但如果將一個int轉換爲char指針,會發生什麼?我知道:

unsigned int *p = &a; 

分配的A到P的內存地址,並可以通過你提領p影響的值。但我完全失去了與char發生的事情,更重要的是,不知道爲什麼我的代碼工作。

感謝您幫助我完成我的第一篇SO文章。 :)

+3

您正在將'int'的地址('int'指針)轉換爲'unsigned char'指針。這意味着當你使用'* start'時,你讀取一個字節的數據,而使用'a'最可能讀取四個字節的數據。 –

+0

@JonathanLeffler所以基本上這樣工作,因爲字符總是1個字節 - 完全非操作系統依賴於?最後,我是否在條件語句中比較地址號碼或地址中存儲的值? –

回答

1

當您在不同類型的指針之間進行轉換時,結果通常是實現定義的(取決於系統和編譯器)。沒有保證,您可以訪問指針或它正確對齊等。

但是,對於特殊情況下,當您投射到指向字符的指針時,標準實際上保證您得到指向最低尋址字節的指針對象(C11 6.3.2.3§7)。

因此,編譯器將實現您發佈的代碼,以便您獲得指向int的最低有效字節的指針。正如我們可以從您的代碼中看出的那樣,該字節可能包含取決於字節數的不同值。

如果你有一個16位的CPU,char指針將指向包含0x12的存儲器,以防大端存儲,或0x34存儲小端存儲。

對於一個32位CPU,int將包含0x000,所以你會得到0x00的情況下大endian和0x34的情況下little endian。

+0

謝謝!這正是我需要清理的東西。 –

1

如果你參考一個整數指針,你將得到4個字節的數據(取決於編譯器,假設gcc)。但是,如果只需要一個字節,則將該指針轉換爲字符指針並將其引用。你會得到一個字節的數據。 Casting意味着你正在對編譯器說,讀取的字節數量太多而不是原始數據類型。

+0

謝謝!我會「投票」,但我還沒有足夠的聲望。 –

0

存儲在內存中的值是一組'1和'0,它們本身並不意味着什麼。數據類型用於識別解釋這些值的含義。因此,讓我們說,在特定的存儲位置,存儲的數據是以下一組比特ad infinitum01001010 ....。這個數據本身就沒有意義。

指針(非空指針)包含2條信息。它包含一組字節的起始位置,位組位的解釋方式。有關詳細信息,請參閱:http://en.wikipedia.org/wiki/C_data_types及其中的參考資料。

所以,如果你有

一個char *c, 的short int *i, 和float *f

這看看上面提到的位,cif是相同的,但*c採取第一8位並以某種方式解釋它。所以你可以做一些事情,比如printf('The character is %c', *c)。另一方面,*i取前16位並以某種方式解釋它。在這種情況下,說printf('The character is %d', *i)將是有意義的。再次,對於*f,printf('The character is %f', *f)是有意義的。

當你用這些數學做數學的時候真正的不同。例如,

c++由1個字節前進指針,

i++由4個字節,

f++由8個字節進入它前進它。

更重要的是,對於

(*c)++(*i)++(*f)++用於在做加法的算法是完全不同

在你的問題,當你從一個指向另一個做一個鑄件,你已經知道算法你要使用在該位置操作目前位,如果你解釋這些位會更容易作爲unsigned char而不是unsigned int。根據操作員正在查看的數據類型,相同的操作+,-等將採取不同的操作。如果你曾經在物理問題上工作過,座標轉換使解決方案變得非常簡單,那麼這是與該操作最接近的類比。你正在將一個問題轉化爲另一個更容易解決的問題。

+0

謝謝!我會「投票」,但我還沒有足夠的聲望。 –

+0

沒問題。玩得開心編程:) – ssm