尝试将浮点数读入数组时,scanf崩溃

这是我的代码:

double values[8], cumulative[8]; printf("Enter first decimal number: "); scanf("%f", values[0]); printf("values[0] = %g", values[0]); 

我的问题是scanf语句崩溃程序,第二个printf永远不会执行。 我最初的尝试是用双精度填充数组的每个插槽,但由于这不起作用,我将程序简化为此,但这也不起作用。

我是一个初学者学习C,所以我可能犯了一个我看不见的愚蠢错误。 任何帮助将不胜感激,谢谢!

编辑:

好的,显然我需要在scanf语句中添加一个&符号。 但我认为数组只是指向数组第一个元素的指针? 为什么我必须使用&符号?

scanf("%f", values[0]); – 此处应将第一个元素的地址传递给scanf。 您正在传递第一个元素的值,它是一个垃圾值,因此它崩溃了。

values[0]*(values + 0) ,所以这将给出第一个元素的值而不是第一个元素的地址。

执行scanf("%lf", &values[0]);scanf("%lf", (values + 0));scanf("%lf", values);

因为它是double使用%lf而不是%f

程序中的另一个问题是未实现的变量。 在声明时尝试将变量初始化为零。

 double values[8] = {0}; double cumulative[8] = {0}; 

在代码的某个位置访问一些错误的指针将导致100%崩溃,如果它初始化为零。 否则它将尝试访问一些垃圾值指针,这将导致内存损坏,这有时不会崩溃反而会给出意外的输出。 但是这也有50%的机会让你崩溃,现在你正在获得。

 scanf("%f", values[0]); 

您需要将要存储的位置的地址传递给scanf() 。 它需要是:

 scanf("%f", &values[0]); 

否则,你只是告诉scanf()将输入值存储到values[0]的初始化值的整数表示指向的任何内存位置 – 这绝对不是你想要的。

扫描double的格式是%lf ; %f适用于float 。 这与printf()不同,后者让人感到困惑 – 我也是。 您还需要传递指向变量的指针。

如果您使用GCC,它应该警告您格式不匹配。 如果没有,你没有启用足够的警告选项进行编译( -Wall是一个很好的起点;如果可以的话,添加-Wextra-Werror )。 检查printf()scanf()格式的显式选项是-Wformat ,但它包含在-Wall

 #include  int main(void) { double values[8]; printf("Enter first decimal number: "); if (scanf("%lf", &values[0]) != 1) printf("Scan failed!\n"); else printf("values[0] = %g\n", values[0]); return(0); } 

请注意,这包括输出结尾处的换行符,以及输入时出现问题(例如无数据或无效数据)时的诊断。

我以为数组只是指向数组第一个元素的指针? 为什么我必须使用&符号?

  1. 数组不仅仅是指向数组第一个元素的指针,但是当一个数组名在表达式中使用而不是作为sizeof()的参数时,它会更改为指向数组第一个元素的指针。
  2. 您必须使用&符号,因为values[0]是数组的第一个元素的值,而不是数组的第一个元素的地址,而scanf()需要地址,而不是值。 记住: a[i] == *(a + i)表示数组名称或指针a和索引i ,并注意*取消引用指针。 如果您编写了scanf("%lf", values)scanf("%lf", values + 0) ,则表示您正在传递指针。 请注意,传递scanf("%lf", &values)将是一种类型不匹配(尽管作为地址传递的值是相同的 – 所以它巧合’工作’)。 传递的类型是’指向8个数组的指针’,这与’指向double的指针’不同。