2016-09-29 115 views
0

所以我最近開始從Steven Kochan的「Programming in C」一書中學習,現在我正在寫第8章 - 「Functions」。 我的練習8.16有問題: 「修改程序8.14,以便用戶可以轉換任何數量的整數。當數字被輸入的值被輸入時,程序將終止輸入零。」 「。Do-while循環 - 終止條件有什麼問題?

方案8.14的代碼如下:

#include <stdio.h> 
#include <stdlib.h> 

int convertedNumber[64]; 
long int numberToConvert; 
int base; 
int digit = 0; 

void getNumberAndBase(void) 
{ 
    printf("Number to be converted? "); 
    scanf("%li", &numberToConvert); 

    printf("Base? "); 
    scanf("%i", &base); 

    if (base < 2 || base > 16) 
    { 
    printf("Bad base - must be between 2 and 16\n"); 
    base = 10; 
    } 
} 

void convertNumber(void) 
{ 
    do 
    { 
    convertedNumber[digit] = numberToConvert % base; 
    digit++; 
    numberToConvert /= base; 
    } 
    while (numberToConvert != 0); 
} 

void displayConvertedNumber (void) 
{ 
    const char baseDigits[16] = 
    { '0', '1', '2', '3', '4', '5', '6', '7', 
     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 

    int nextDigit; 

    printf ("Converted number ="); 

    for (--digit; digit >= 0; digit--) 
    { 
    nextDigit = convertedNumber[digit]; 
    printf("%c", baseDigits[nextDigit]); 
    } 
    printf("\n"); 
} 

int main (void) 
{ 
    void getNumberAndBase (void), convertNumber(void), 
    displayConvertedNumber (void); 

    getNumberAndBase(); 
    convertNumber(); 
    displayConvertedNumber(); 

    return 0; 
} 

我的想法是最初使用do-while循環各地的主要功能三種功能是這樣的:

do 
{ 
getNumberAndBase(); 
convertNumber(); 
displayConvertedNumber(); 
} 
while (numberToConvert != 0); 

但顯然它不起作用。這是本章的最後一部練習,我設法完成了其餘部分,但不是爲了這個世界,我能否找出這裏有什麼問題。 也許我只是想念一些明顯的東西。

+2

定義「顯然它不起作用」。發生什麼事?你是否遇到錯誤,崩潰,錯誤的結果......? – UnholySheep

+0

關於函數的章節並未教您使用參數和返回值嗎?壓抑。 –

回答

0

當您的do-while條件經過測試時,它始終爲零。方法convertNumber()有其自己的do-while,它繼續,直到numberToConvert爲零。

do 
{ 
    getNumberAndBase(); 
    convertNumber(); // Sets numberToConvert to zero before returning 
    displayConvertedNumber(); 
} 
while (numberToConvert != 0); 

void convertNumber(void) 
{ 
    do { 
    ... 
    } while (numberToConvert != 0); 
} 

問題的一部分是正在使用成員變量來傳遞方法的返回值。這些方法具有不明顯的副作用。

請考慮從方法返回值。

long int numberToConvert = 0; 
do 
{ 
    numberToConvert = getNumberAndBase(); 
    long int convertedNumber = convertNumber(numberToConvert); 
    displayConvertedNumber (convertedNumber); 
} 
while (numberToConvert != 0); 

現在局部變量numberToConvert是由convertNumber()方法的影響,並可以決定從當地實際情況的循環行爲。

+0

比方說,「convertNumber'的'後置條件是'numberToConvert'是零」。 –

+0

@EugeneSh。 - 也是如此。更大的問題是不必要的使用成員變量來傳遞函數結果。 –

0

numberToConvert已被convertNumber()使用,所以我們不要打擾它。

把整個街區

getNumberAndBase(); 
convertNumber(); // Sets numberToConvert to zero before returning 
displayConvertedNumber(); 

一個while(1)循環中,並把支票上numberToConvertgetNumberAndBase()功能。一旦獲得0值,就跳出循環。

可以肯定的,你可以使用另一個do...while循環,但不知爲何,你需要利用numberToConvert掃描價值,滿足條件

」 ......做出了規定的程序時零終止鍵入作爲要轉換的數字的值。「

這就是說,

  • 務必檢查的scanf()的返回值,以確保成功。
  • 不要簡單地使用全局變量,一旦程序開始變大,它們可能會帶來隱藏的麻煩。定義局部變量並儘可能傳遞它們(或指向它們的指針)。

更高水平的封裝是我們所需要的。 :)

0

這項工作是困難的,因爲它需要使用全局變量 - 這對排序正確使用功能的作品。

總之,這裏是我的解決方案。請注意,每次要轉換數字時,必須將gDigit設置爲0。

/* Exercise 7.16 
    Modify Program 7.15 so that the user can convert any number of integers. 
    Make provision for the program to terminate when a zero is typed in as 
    the value of the number to be converted. 

    notes: includes the modified version of Program 7.15 from Exercise 7.15 

    the statement gDigit = 0 has been moved from the start of the program to 
    the start of the convertNumber() function -- gDigit must be set to 0 each 
    time a number is to be converted 
*/ 

#include <stdio.h> 

int gConvertedNumber[64]; 
long int gNumberToConvert; 
int gBase; 
int gDigit; 

void getNumber (void) 
{ 
    printf ("\nNumber to be converted (0 to exit)? "); 
    scanf ("%li", &gNumberToConvert); 
} 

void getBase (void) 
{  
    do { 
     printf ("Base (between 2 and 16)? "); 
     scanf ("%i", &gBase); 
    } 
    while (gBase < 2 || gBase > 16); 
} 

void convertNumber (void) 
{ 
    gDigit = 0; 

    do { 
     gConvertedNumber[gDigit] = gNumberToConvert % gBase; 
     ++gDigit; 
     gNumberToConvert /= gBase; 
    } 
    while (gNumberToConvert != 0); 
} 

void displayConvertedNumber (void) 
{ 
    const char baseDigits[16] = 
     { '0', '1', '2', '3', '4', '5', '6', '7', 
      '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 

    printf ("Converted number = "); 

    for (--gDigit; gDigit >= 0; --gDigit) 
     printf ("%c", baseDigits[gConvertedNumber[gDigit]]); 

    printf ("\n"); 
} 

int main (void) 
{ 
    void getNumber (void); 
    void getBase (void); 
    void convertNumber (void); 
    void displayConvertedNumber (void); 

    while (1) { 
     getNumber(); 
     if (gNumberToConvert == 0) 
      break; 
     getBase(); 
     convertNumber(); 
     displayConvertedNumber(); 
    } 

    return 0; 
}