簡體   English   中英

char a[50][50] 在 C 中是什么意思?

[英]What does char a[50][50] mean in C?

我正在做與字符串有關的作業。 這是代碼


int main(){
    char a[50][50];
    int n;
    printf("Enter the value of n\n");
    scanf("%d",&n);
    printf("Enter %d names\n",n);
    fflush(stdin);
    for(int i=0; i<n; i++){
        gets(a[i]);
    }

我試圖將字符 a[50][50] 更改為字符 a[50],但整個程序沒有運行,並出現以下錯誤消息:“從 'char' 到 '*char' 的無效轉換我不知道”真的不明白這是如何工作的。

char a[50][50] a聲明a包含 50 個char的 50 個數組的數組。

那么a[0]是一個包含 50 個char的數組, a[1]a[2] a[3] ,依此類推直到a[49] 有 50 個單獨的數組,每個數組都有 50 個char

由於a[0]是一個包含 50 個char的數組,因此a[0][0]是一個char 通常, a[i][j]是數組i字符j

gets(a[i])表示從輸入中讀取字符並將它們放入a[i] 為此, a[i]必須是一個char數組—— gets讀取多個字符並將它們放入數組中。 如果a[i]是單個字符, gets將無法工作。

盡管gets(a[i])表示將字符放入a[i] ,但它的工作原理是傳遞地址而不是傳遞數組。 當數組在表達式中使用而不是用作sizeof的操作數或地址運算符& ,C 會自動將其轉換為指向其第一個元素的指針。 由於a[i]是一個數組,它會自動轉換為指向其第一個元素的指針(指向a[i][0]的指針)。 gets接收這個指針並用它來填充它從標准輸入流中讀取的字符。

char a[50][50]聲明a作為50元件陣列的50個元素的數組char 這意味着每個a[i]都是一個包含 50 個元素的char數組。 它將在內存中布置,如:

   +---+
a: |   | a[0][0]
   +---+
   |   | a[0][1]
   +---+
   |   | a[0][2]
   +---+
    ...
   +---+
   |   | a[0][49]
   +---+
   |   | a[1][0]
   +---+
   |   | a[1][1]
   +---+
    ...
   +---+
   |   | a[1][49]
   +---+
   |   | a[2][0]
   +---+ 
    ...

該代碼被存儲多達50,每個多達49個字符長,在a (IOW,每a[i]可以存儲49個字符的字符串)。 在 C 中,字符串是包含 0 值終止符的字符值序列。 例如,字符串"hello"表示為序列{'h', 'e', 'l', 'l', 'o', 0} 尾隨0標記字符串的結尾。 字符串處理函數和輸出函數(如帶有%s說明符的putsprintf需要該 0 終止符才能正確處理字符串。

字符串存儲在字符類型的數組中,可以是char (對於 ASCII、UTF-8 或 EBCDIC 字符集)或wchar_t用於“寬”字符串(需要超過 8 位左右進行編碼的字符集)。 一個 N 字符的字符串需要一個至少N+1 個元素寬的數組來解釋 0 終止符。

除非它是sizeof或一元&運算符的操作數,或者是用於初始化字符類型數組的字符串字面量,否則類型為“ T N 元素數組”的表達式將被轉換(“衰減”)為表達式類型為“指向T指針”,表達式的值將是數組第一個元素的地址。

你打電話時

gets( a[i] );

表達式a[i]從類型“50 元素的char數組”轉換為“指向char指針”,表達式的值是數組第一個元素的地址( &a[i][0]1 . gets將從標准輸入讀取字符並將它們存儲到從該地址開始的數組中。 請注意, gets不再是標准 C 庫的一部分——它在標准的 2011 版本中被刪除,因為它不安全。 C 不需要對數組訪問進行任何類型的邊界檢查 - 如果您輸入的字符多於目標緩沖區可容納的大小(在本例中為 50),這些額外的字符將立即寫入內存中的最后一個元素數組,這可能會導致各種混亂。 緩沖區溢出是一種流行的惡意軟件利用。 此時應更換gets通話用

fgets( a[i], 50, stdin );

它將從標准輸入讀取最多 49 個字符到a[i] 請注意,任何多余的字符都會留在輸入流中。

此外,沒有為輸入流2定義fflush的行為 - 除了使用getcharfgetc讀取它之外,沒有好的、安全的、可移植的方法來清除多余的輸入。


  1. 這就是為什么你得到了你沒有當您更改錯誤消息achar [50][50]char [50] -在這種情況下, a[i]有一個類型char ,不char * ,和值a[i]不是地址
  2. 微軟的 Visual Studio C 編譯器是一個明顯的例外——它會從輸入流中清除多余的輸入。 但是,這是特定於 MSVC 的,不能跨不同編譯器移植。 該操作在“刷新”語義方面也有點荒謬。

基本上,在 C 中,這表示長度為 0 到 50 的數組,其中包含數組的每個單元格中的字符值 50

該程序似乎在數組a存儲了n名稱。 它首先詢問姓名的數量,然后詢問姓名。 該方法char *gets(char *str)存儲在一個條目中的每個不同的線a

n有 2 個維度。 第一個是指名稱的數量,第二個是指每個名稱的長度。 類似於n[number_of_names][lenght_of_name]

但是,如果用戶提供 n > 50,或者名稱包含超過 50 個字符,它可能會崩潰。

此外, gets()是危險的。 請參閱此其他帖子

編輯:a更改為一維會使程序嘗試在字符內存儲整行,因此出現錯誤

暫無
暫無

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

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