簡體   English   中英

需要幫助來理解C中表達評估的順序

[英]Need help in understanding order of evaluation of expression in C

我很難理解下面的代碼如何評估表達式。 我不明白代碼在這里如何工作

while (isdigit(s[++i] = c = getch()))
        ;

以及為什么我們需要

s[1] = '\0';

完整代碼

#include <ctype.h>
int getch(void); 
void ungetch(int);
/* getop: get next character or numeric operand */ 

int getop(char s[])
{    
    int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t');
    s[1] = '\0';

    if (!isdigit(c) && c != '.')
        return c; /* not a number */ 

    i = 0;

    if (isdigit(c)) /* collect integer part */ 
        while (isdigit(s[++i] = c = getch()));

    if (c == '.') /* collect fraction part */        
        while (isdigit(s[++i] = c = getch()));

    s[i] = '\0';
    if (c != EOF)
        ungetch(c);

    return NUMBER;    
}

感謝您的任何幫助!

=正確關聯,因此isdigit(s[++i] = c = getch())將被分組為
isdigit( s[++i] = (c = getch()) ) getch將讀取一個char並將其分配給c ,然后將c分配給s[++i]

  1. 這就是所謂的鏈式分配,請參閱wiki 要了解它,您只需要知道C中的賦值就是有價值的! 因此,就像@hacks所提到的,您可以將其等同於從右到左的多個連續分配的單線。

2。

s[1] = '\0'; 

這是一個安全問題,也是一種常規的編碼實踐:在C語言中,始終用'\\ 0'填充字符串的結尾。由於輸入參數s []應該是char數組,因此需要對其進行填充。

注意

s[1] will be overwritten if s[0] is a digit or '.',

在這種情況下,將執行第二個或第三個while循環。 和以前一樣,您還需要在s [i]上加上'\\ 0';

整個功能都有一個設計缺陷,即無法防止緩沖區溢出。 它需要知道s所指向的緩沖區的大小,以避免這種情況。

無論如何, while (isdigit(s[++i] = c = getch())); 具有以下含義:

for (;;)
{
    ++i;
    c = getch();
    s[i] = c;

    if ( ! isdigit(s[i]) )
        break;
} 

使用c而不是只寫s[++i] = getch()是有原因的。

在這里,我假設getch (不是標准函數)是指某個函數,該函數具有與getchar相同的返回規范,即它返回unsigned char值或EOF

int c; 需要,以便可以檢測到EOF 如果我們沒有c ,則無法在函數末尾執行if ( c != EOF )測試。 進行s[i] == EOF無效,因為它可能會誤認為EOF的有效字符(或者EOF可能超出char的范圍)。

但是,代碼仍然存在錯誤。 isdigit函數需要相同類型的int值; 即在我的解壓縮版本中,最終測試應為:

if ( !isdigit(c) )

我猜想代碼編寫者知道EOF的問題,但要么不了解isdigit ,要么假設他的代碼只能在接受負字符的實現上運行。

編寫得更緊湊,該行可以替換為:

i = 1;
// ...

while ( isdigit(c = getch()) )
    s[i++] = c;

暫無
暫無

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

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