2016-02-08 36 views
2

我有一個API來實現對EEPROM的寫入操作。下面是它的聲明:在C中的uint8和char之間的轉換

CYBLE_API_RESULT_T CyBle_StoreAppData (uint8 * srcBuff, const uint8 destAddr[], uint32 buffLen, uint8 isForceWrite); 

它運作良好時,我調用此函數,併發送一個陣列參數已被宣佈爲uint8srcBuff

問題是,我需要發送char數組指針。我在想char已經是uint8,但是如果我發送一個char數組指針而不是uint8,我會得到一個編譯器警告。爲什麼我不能使用char而不是uint8?下面是調用該函數的2個例子:

static const uint8  datastack_ROM[dedicatedRomSize] = {0}; 
uint8     Container_ID[10]; 
char     Prefix[10]; 

//Call the function with Container_ID which has been declared as uint8. This is working. 
CyBle_StoreAppData(Container_ID,datastack_ROM,10,0); 

//Call the function with Prefix which has been declared as char. This is NOT working. 
CyBle_StoreAppData(Prefix,datastack_ROM,10,0); 

下面是第二個電話警告:

passing char[10] to parameter of type 'uint8 *' converts between pointers to integer types with different sign.

是不是charuint8一樣嗎?

+1

錯誤消息中的重要內容是關於「不同符號」的部分。這意味着你的'char'類型是'signed',而'uint8'是(假設在這裏)'unsigned'。這可能不會是一個大問題,所以你應該只能夠投射你的指針:'CyBle_StoreAppData((uint8 *)Prefix,...)' –

+0

這似乎違反了約束條件,請注意:http:// stackoverflow。com/questions/30535814/pass-unsigned-char-pointer-to-atoi-without-cast –

+0

@GiorgiMoniava我看過類似的問題,但我想我找不到那個。我怎麼能提到有類似的問題呢?還是我需要那樣做? –

回答

1

這兩種類型都是8位長。不同之處在於簽名。

  • uint8類型是無符號的。
  • char類型應在您的情況下簽名。實際上,它依賴於編譯器,但大多數編譯器認爲char類型是默認簽名的,並且可以選擇在需要時強制char類型作爲無符號類型。見C99 standard document reference§6.2.5p15:

實現應定義字符具有相同的範圍,表示和行爲要麼簽署char或unsigned char。

在limits.h中定義的CHAR_MIN將具有值0或SCHAR_MIN中的一個,並且可用於區分這兩個選項。

+0

我不認爲它是依賴於編譯器的。我找到了這個鏈接[link](https://developer.mbed.org/handbook/C-Data-Types)。但是,如果我聲明'Container_ID'爲無符號,我不能使用字符串函數,我將它們用於另一項工作。所以我應該像在@ Joachim的回答中那樣施展它? –

+0

查看我的編輯,我添加了對C標準的引用。但是,你可以按照提議進行施展。 – greydet

+0

謝謝:)這是解釋性的。我確認我的編譯器認爲已簽名。所以我使用了投射操作,並且工作得很好。謝謝你們。 –

0

uint8_t很可能定義爲無符號字符。

char它是自己的類型,其行爲或者完全像signed char或unsigned char(注意,這些是三種不同的類型)。

在這種情況下,它的行爲類似signed char,並且您會收到轉換警告。

+0

我不認爲這是編譯器依賴。我找到了這個鏈接[link](https://developer.mbed.org/handbook/C-Data-Types)。但是,如果我聲明'Container_ID'爲無符號,我不能使用字符串函數,我將它們用於另一項工作。所以我應該像在@ Joachim的回答中那樣施展它? –

+0

@abdullahcinar是的,你可以投它,假設你的架構每字節8位和2的補碼,這幾乎可以肯定它。 – 2501

+0

是的,我檢查了它,這是真的。所以我可以繼續。非常感謝所有對這個問題有回答的人。 –

1
uint8     Container_ID[10]; 

那是有可能的值一個無符號的8位整數0255

char     Prefix[10]; 

在你的情況有符號的8位字符以整數值-127+128

因爲他們是不一樣的符號類型,你會得到一個轉換警告,你應該。

1

正如this中突出顯示的答案那樣的混合參數是違反約束的。

您將一個無符號char *參數傳遞給一個函數,該函數需要一個 char *參數。這兩種類型不兼容,並且不存在從一個到另一個的隱式轉換。符合標準的編譯器可能會發出警告(即計爲診斷),然後繼續執行 生成可執行文件,但該可執行文件的行爲未定義爲 。

雖然這個問題的答案是char* VS無符號char*我相信同樣應該char*uint8_t*舉行。

1

charuint8有兩個共同點,這很重要:它們都是8位整數。現在有兩個問題

  • 是/這個/這8位整數是否有符號或無符號?

而且更重要的是

  • 它在你的情況有關係嗎?

I.e.你想發送一個由整數組成的數組嗎?讓它們被認爲是非常重要的?舉例來說,如果函數會做這樣的事情,

if (charvalue < 0) { ... 

,或者如果你功能要注意字節的符號性(如果那會是可能的);如果函數會做到這一點,並用符號會的問題:發送255是積極的,但考慮到字節簽署,這會被解讀爲-1 ...

但由於該功能將uint8 *這沒有意義(實際上是函數內部的開發者可能已經使用char單獨治療字節,用自己的符號性,但在這種情況下,具有類似功能的簽名是非常誤導!)

所以電子 PROM是治療字節無符號,並且您可以安全地將賦予該函數的指針轉換爲刪除警告,

CyBle_StoreAppData((uint8 *)Prefix,datastack_ROM,10,0); 

或者乾脆

uint8 Prefix[10]; 

如果不會引起其他問題/你的代碼的其餘部分的警告。