簡體   English   中英

Ritchie和Kernighan混淆的C程序

[英]C program confusing from Ritchie and Kernighan

我到處都讀到,如果您是計算機科學專業的學生,​​那么在大學畢業之前,C是必不可少的語言。 我已經拿到了我的教授推薦的Ritchie and Kernighan第二版。 我對該程序的工作方式感到困惑。 如果有人可以解釋,那就太好了! 該程序計算每個數字,空格和其他字符的出現次數。 我為已經了解的事情寫了評論,並且在不了解它如何工作的地方添加了問題。

#include <stdio.h>

int main()
{
     int c, i, nwhite, mother;   //Declaring variables
     int ndigit[10];             //Declaring an array that holds indexes from 0-9

     nwhite = nother = 0;        //Initializes two variables to 0

     for (i = 0; i < 10; ++i)    //Does this for loop keep going through and for each index
             ndigit[i] = 0;      //0-9 set the value of it to 0?

     white ((c = getchar()) !=EOF)  //While loop to check if char at EOF
     {
          if (c>='0' && c <= '9')        //Completely lost on how this works?
               ++ndigit[c - '0'];
          else if (c == ' ' || c == '\n' || c == '\t')     //Checks for white space 
               ++nwhite;
          else                                   //If nothing else increment char variable
               ++nother;

     printf("digits ");               //First for loop traverses and prints each value of
     for (i=0; i<10; ++i)             //the index. The next printf prints white space and
          printf(" %d", ndigit[i]);   //other characters
      printf(", white space = %d, other = other = %d\n", nwhite, nother);
}

是的,這會遍歷整個ndigit數組並將每個元素設置為0。

for (i = 0; i < 10; ++i)   
    ndigit[i] = 0; 

這里:

if (c>='0' && c <= '9')
    ++ndigit[c - '0'];

條件(上如果直插式)可能是最困難的事情理解:

像這樣成像:

if( A and B)
    ...

有:

A = c>'0'

B = c<= '9'

也就是說,如果c在0到9之間(包括)。

希望這可以幫助。

(c >= '0' && c <= '9')        //Completely lost on how this works?

C語言中的char類型只是一個8位整數,通常是帶符號的。 字符(如19與整數(如63)之間的對應關系由ASCII碼定義。 如果c是數字,則上面截斷的代碼的值為1。 用C寫'1'等效於寫49

聲明的整數數組的類型為auto,在C自動存儲類中,整數數組將具有垃圾值。 因此,這些分配為零。

for (i = 0; i < 10; ++i)   
   ndigit[i] = 0; 

對於if語句,您正在檢查給定字符是否在0-9之間。 由於其getchar()-(獲取字符),因此將值與單引號進行比較

if (c>='0' && c <= '9') 

您也可以將此語句更改為

if (c>=48 && c <= 57)

由於ASCII 字符 “ 0”為48,而“ 9”為57

++ndigit[c - '0'];

您要對輸入到數組中的數字進行計數,即假設輸入為5,則將索引5處的數組計數增加1。

這里提到c-'0'是因為,如上所述,'5'的ASCII字符為53。因此,以上語句的結果為c-'0' = 5 (數組的索引5)

 int ndigit[10];             //Declaring an array that holds indexes from 0-9

 for (i = 0; i < 10; ++i)    //Does this for loop keep going through and for each index

在C數組中,索引從0開始,因此在這種情況下, ndigit的有效索引為0到9(含0和9)。 for循環開始從i = 0和增量i被一個( ++i ),只要i < 10 ,所以循環體獲取的值來執行i從0到9,包括端值。

在此程序中,由讀者自己確定這兩個10字面是同一回事。 可以說,最好是#define一個常量並在兩個地方都使用它(但是在這種情況下,可以原諒,因為小數位數恆定為10)。

 while ((c = getchar()) !=EOF)  //While loop to check if char at EOF

getchar返回一個字符從標准輸入讀取, EOF (其具有從任何不同的值char )如果標准輸入是在文件末尾。 沒有EOF字符可表示此情況。

      if (c>='0' && c <= '9')        //Completely lost on how this works?

十進制數字0到9的字符值在ASCII和大多數其他字符集中是連續的,因此此代碼利用了這一點並檢查c是否等於或大於'0' 並且&& )也等於或小於而不是'9' 換句話說,這將檢查c是否在'0''9'之間的范圍內(包括'0''9' '0''9'是字符文字,具有字符集中相應字符的整數值–這樣, if (c>=48 && c<=57) ,程序員不必知道並寫入它們的值。該代碼適用於不兼容的字符集,只要數字字符具有連續的值即可。

           ++ndigit[c - '0'];

這將計算每個數字出現的次數。 同樣,由於代表數字的字符是連續的,因此從讀取的字符中減去第一個數字的值( '0' )得出對應字符的值0到9,這也是數組ndigit的有效索引,如以上討論。 當然,該減法僅適用於數字字符,這就是前面的if對此進行檢查的原因。

例如,在ASCII中, '0'值為48, '1'為49,依此類推。因此,如果c'1' ,則減法c - '0''1'-'0' ,即,49-48或1。

++運算符增加ndigit數組的相應索引中的ndigit (第一個for循環將ndigit的初始值設置為零。)

EOF End-of-file的縮寫-是在stdio.h頭文件中定義的宏。 宏是已命名的代碼片段。 無論在何處使用該名稱,該名稱都將替換為宏的內容。 它是一個值,表示當無法從源中讀取更多字符時的條件,在這種情況下,該源為stdin標准輸入流,通常是鍵盤。 簡而言之,對於任何字符c ,條件ch == EOF始終為false。 因此,在您通過* nix系統上的Ctrl+D和Windows系統上的Ctrl+Z發出EOF信號之前,以下條件將一直從stdin讀取:

white((c = getchar()) != EOF) {
}

接下來,此條件檢查讀取的字符c是否為數字字符,即十進制數字。

if(c>='0' && c <= '9') {  // check if c is a numeric character.
} 

C中的字符實際上是整數值(認為它們是1-byte整數),並且等於相應字符的ASCII碼(盡管C標准沒有強制要求)。 在ASCII中,字符09的代碼值按升序排列。 因此,如果滿足上述條件,則意味着c是數字字符。

++ndigit[c - '0'];

在上面的語句中, c - '0'是轉換為整數值的數字字符。 因此,如果c的值為'8' ,則c - '0'計算結果為8 接下來,它在索引為8的數組ndigit中獲取值,該值保留數字8計數,並將其遞增1

暫無
暫無

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

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