繁体   English   中英

同时执行循环-终止条件怎么了?

[英]Do-while loop - what's wrong with the terminating condition?

因此,我最近开始从Steven Kochan的“用C编程”一书中学习,目前我正在学习第8章-“函数”。 我对练习8.16存有疑问:“修改程序8.14,以便用户可以转换任何数目的整数。规定要在键入零作为要转换的数字的值时终止程序。”

程序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);

但显然不起作用。 这是本章的最后一个练习,我设法完成了其余的工作,但我不能为全世界找出问题所在。 可能我只是缺少一些明显的东西。

测试您的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()方法的影响,您可以从局部上下文确定循环行为。

numberToConvert convertNumber()已使用convertNumber() ,因此请不要打扰。

把整个块

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

while(1)循环中,并检查getNumberAndBase()函数中的numberToConvert值。 获得0值后就跳出循环。

当然,您可以使用另一个do...while循环,但是以某种方式需要使用numberToConvert扫描值来满足条件

“ ...规定当输入零作为要转换的数字时,程序将终止。”

那就是

  • 始终检查scanf()的返回值以确保成功。
  • 不要简单地使用全局变量,一旦程序开始变大,它们就会带来隐藏的麻烦。 定义局部变量,并尽可能长地传递它们(或指向它们的指针)。

我们只需要更高水平的封装。 :)

这项工作很困难,因为它需要使用全局变量-这类工作不利于正确使用函数。

无论如何,这是我的解决方案。 请注意,每次转换数字时,必须将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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM