填充整数数组与填充浮点数相同吗?

我刚刚被介绍给C,我被分配编写了一个程序,可以模仿杂货店的自助退房线。 这涉及我必须根据用户输入填充杂货项目的价格数组,并将它们添加并复制到文件中。

填充整数数组的最简单方法是使用for循环。 但是对于float类型的数组会有什么不同吗?

它看起来像这样吗? 或者这是不正确的?

int size, i; float items[size]; printf("How many items are you checking out today?"); scanf("%d", &size); for(i=0;i<size;i++){ printf("Enter the price of an item\n"); scanf("%f", items[i]); } 

我是这个网站的新手,所以提前感谢

我建议在声明变量时始终初始化变量,以防止意外发生“垃圾”值。 另外,我真的不建议预先声明你的循环计数器。 你在许多旧代码中看到它(由于编译器的限制,它曾经是必需的),但现在我认为它是代码噪声。 它看起来像这样:

 for (int i = 0; i < size; i++) { // stuff } 

此外,您的代码有一个很大的问题。 你正在使用所谓的可变大小数组,它们不是一个好主意 。 您通常希望在编译时声明数组大小,或者使用malloc为数组动态分配空间。

但是,回到初始化,这就是如何在声明中设置堆栈分配数组中的每个元素:

 #define SIZE 4 int main(void) { float items[SIZE] = { 0 }; } 

如果动态分配数组,我建议使用callocmemset将数组元素设置为默认值,原因相同。

要回答关于填充数组的问题,是的,关于如何实际执行它没有区别。 在两种情况下,for循环都可以正常工作。 只记得检查scanf的返回值。

正如已经正确指出的那样,你不能声明float items[size]; 直到size有效地初始化为正整数值。 由于您尝试访问未初始化的值,尝试在size包含值之前声明items调用Undefined Behavior 。 (代码的有效操作已经结束,它可以执行从正确运行到StackOverflow或SegFaulting的任何操作)

无论何时进行用户输入, 必须考虑输入缓冲区中保留的每个字符(此处为stdin )。 由于scanf处理输入匹配失败的方式,在使用scanf (或系列)进行输入时尤其如此。 当两者都发生时, 不会再读取任何字符,并且任何有问题的字符在输入缓冲区中都未被读取 – 只是等待您在下一次尝试读取时再次咬你(如果您在循环内接收输入,通常会导致无限循环)

(这是推荐用于输入用户输入的fgets面向行的function的主要原因之一)

如果使用正确,可以使用scanf 。 这意味着 每次都要负责检查scanf返回 。 你必须处理三个条件

  1. (return == EOF)用户通过按Ctrl + d生成手动EOF取消输入(或在Windows Ctrl + z上生成 ,但看到CTRL + Z在Windows 10中不生成EOF );
  2. (return == expected No. of conversions)表示读取成功 – 然后由您来检查输入是否满足任何其他条件(例如正整数,正浮点等); 和
  3. 否则,您必须处理匹配输入失败,并且必须考虑输入缓冲区中可能留下的每个字符。 (通常你会在输入缓冲区中向前扫描,直到发现'\n'EOF丢弃任何剩余的无关字符)

如果您完成了工作,则可以根据需要成功使用scanf

接下来,一般要注意不要使用浮动点作为货币 (当你因为舍入错误而开始赔钱时,人们会变得非常生气)虽然你的示例程序很好 – 只要明白,在真实的货币处理程序中,你会处理货币作为无符号值乘以100 (或任何需要的),以确保所有金额都可以准确表示。

scanf要求放在一起,您可以安全地执行以下操作:

 #include  /* function to empty extraneous characters from stdin * (like the '\n' generated by pressing [Enter]) */ void empty_stdin() { int c = getchar(); while (c != '\n' && c != EOF) c = getchar(); } int main (void) { int size = 0, i; float total = 0.0; for (;;) { /* loop continually until valid size entered */ int rtn; printf ("How many items are you checking out today?: "); rtn = scanf ("%d", &size); if (rtn == EOF) { /* handle EOF */ fprintf (stderr, "(user canceled input)\n"); return 1; } else if (rtn == 1 && size > 0) { /* valid int received */ empty_stdin(); break; } /* otherwise, handle error */ fprintf (stderr, "error: invalid input.\n\n"); empty_stdin (); /* remove any chars from stdin up to '\n' */ } float items[size]; /* declare VLA of size floats */ for (i = 0; i < size; i++) { items[i] = 0.0; /* initialize each (or memset VLA) */ for (;;) { /* loop continually until valid item price entered */ int rtn; printf (" price of item[%2d]: ", i + 1); /* prompt for price */ rtn = scanf ("%f", &items[i]); if (rtn == EOF) { /* handle EOF */ fprintf (stderr, "(user canceled input)\n"); return 1; } else if (rtn == 1 && items[i] > 0) { /* valid price received */ empty_stdin(); break; } /* otherwise, handle error */ fprintf (stderr, "error: invalid input.\n\n"); empty_stdin (); /* remove any chars from stdin up to '\n' */ } total += items[i]; } printf ("\ntotal (%d items): $%.2f\n", size, total); } 

示例使用/输出

(显示入口中的故意错误)

 $ ./bin/checkout How many items are you checking out today?: what? error: invalid input. How many items are you checking out today?: 4 price of item[ 1]: free? error: invalid input. price of item[ 1]: 1.25 price of item[ 2]: 3.50 price of item[ 3]: discount? error: invalid input. price of item[ 3]: 2.25 price of item[ 4]: 3 total (4 items): $10.00 

仔细看看,如果您有其他问题,请告诉我。

在使用方面,arrays的使用没有区别。 但是代码中几乎不需要进行任何更改。

 #define MAX_SIZE (10) int size=0, i=0; //It is always better to initialize the variables. float items[MAX_SIZE] = {0.0f}; //Automatically the entire array will be initialized to zero. printf("How many items are you checking out today?"); scanf("%d", &size); if(size > MAX_SIZE) size = MAX_SIZE; for(i=0;i 

还有其他方法可以实现代码来处理数组大小。 这是其中一种方式。