簡體   English   中英

我可以使用 int8_t 代替 char 嗎?

[英]Can I use int8_t instead of char?

我做了一個如下所示的短代碼。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
 
int32_t main(int32_t argc, int8_t *argv[])
{
   int32_t i;
 
   if (argc < 1)
   {
      printf("Error\n");
   }
 
   for (i = 0 ; i < argc ; i++)
   {
      printf("argv[%d] = %s\n", i, argv[i]);
   }
 
   return 0;
}

並編譯如下,然后我看到如下警告。

$ gcc -W -Wall main.c
main.c:6:9: warning: second argument of ‘main’ should be ‘char **’ [-Wmain]
 int32_t main(int32_t argc, int8_t *argv[])

使用 int8_t 的最佳實踐是什么?

從根本上講,我相信您是在問一個風格問題,這意味着您不太可能得到明確的答案。 關於風格的意見,嗯,意見。

有些人認為您應該在大多數情況下使用 C 的“自然”類型—— charshortintlong及其unsigned變體,並且只有在絕對必要時才應該使用精確大小的類型,例如int32_t

有些人認為“自然”類型所隱含的可變性是錯誤的源頭,他們認為您應該始終使用精確大小的類型。

現在,話雖如此,寫作的具體情況

int32_t main(int32_t argc, int8_t *argv[])

客觀上是錯誤的,至少有三個原因:

  1. int類型為 16 位的平台上,這會錯誤地將main的返回類型和argc參數的類型聲明為 32 位類型。
  2. char類型為無符號的平台上,這會錯誤地將argv聲明為有符號字符指針數組。 這可能就是 gcc 為您抱怨的問題。
  3. 在更哲學的層面上, main不是您可以選擇的 function 的 function 簽名。 其他人聲明main ,其他人正在調用main ,您的工作只是為main提供定義。 因此,您只需使用其他人指定的類型,即使您的規則是盡可能使用精確大小的類型。 在這里,你不能。

底線:請使用這兩個(等效)forms 之一作為main用 arguments:

int main(int argc, char *argv[])

int main(int argc, char **argv)

除非您正在編寫“獨立”代碼,否則任何其他內容都會令人困惑、誤導、不標准或錯誤。 (定義一個不帶 arguments 的main也是可以接受的。)

使用 int8_t 的最佳實踐是什么?

我會說,當您真的非常需要一個很小的 8 位簽名 integer 時,或者當您將 memory 操作為有符號字節時。 但我不會 go 到處使用int8_t而不是char ,因為它會給你帶來很多問題,而且它不會給你買任何東西。

您發布的是main()的實現定義形式。 僅在兩種情況下允許:

  • 要么與int main (int argc, char** argv) 100% 兼容,要么
  • 這是編譯器文檔告訴您可以使用的實現定義的形式。

決定 main() 可接受的 forms 的是 C 標准和編譯器,而不是程序員。

值得注意的是int8_t可能與char兼容,也可能不兼容,因為char具有實現定義的簽名。

使用 int8_t 的最佳實踐是什么?

當您需要一個非常小的簽名 integer 時。 這與char不同。 char有三種口味:

signed char
unsigned char
char

如果您知道您想要一個已簽名的int8_t ,請使用它。 如果您正在處理標准字符串 API:s,如main ,請使用char

int8_t甚至不需要存在。 它是特定於實現的。 有些平台不存在。

您使用int32_t而不是int也是如此。 它不一定存在,即使它存在,它也不總是inttypedef - 所以如果你想保持可移植性,請使用int

你的方法有很多缺點:

  • main()的原型與任何標准原型都不兼容,即使int具有 32 位並且如果char是有符號的,因為charsigned char是不同但兼容的類型,但char *signed char *是不兼容的類型。

  • 如果intint32_t不同,則原型肯定與標准原型不兼容,並且行為未定義。

  • printf("argv[%d] = %s\n", i, argv[i]); 如果類型intint不完全相同,則會有未定義的行為。 您可以使用<inttypes.h>中的宏,但它們相當麻煩並且代碼可讀性較差。

因此,您的main function 的原型應該是int main(int argc, char *argv[])並且為了保持一致性, i應該使用與argc相同的類型定義: int

生成的代碼非常簡單易讀:

#include <stdio.h>
 
int main(int argc, char *argv[]) {
    int i;
 
    if (argc < 1) {
        printf("Error\n");
    }
 
    for (i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
 
    return 0;
}

我認為關於int8_tchar的最佳實踐是對main和所有庫函數使用未更改的標准原型。 還建議將char用於文本的實際字符,而將int8_tuint8_t用於從二進制內容讀取的有符號和無符號字節。 字符串文字應被視為const並通過const char *進行操作。 無論 char 類型的符號性如何,代碼都應以定義的方式運行。 這不僅僅是風格問題,這是提高代碼可讀性和堅固性、避免混淆和一些錯誤的明智習慣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM