![](/img/trans.png)
[英]Original C hello, world program from Kernighan and Ritchie not compiling
[英]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位整數,通常是帶符號的。 字符(如1
和9
與整數(如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中,字符0
到9
的代碼值按升序排列。 因此,如果滿足上述條件,則意味着c
是數字字符。
++ndigit[c - '0'];
在上面的語句中, c - '0'
是轉換為整數值的數字字符。 因此,如果c
的值為'8'
,則c - '0'
計算結果為8
。 接下來,它在索引為8
的數組ndigit
中獲取值,該值保留數字8
計數,並將其遞增1
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.