尝试将浮点数读入数组时,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); }
请注意,这包括输出结尾处的换行符,以及输入时出现问题(例如无数据或无效数据)时的诊断。
我以为数组只是指向数组第一个元素的指针? 为什么我必须使用&符号?
- 数组不仅仅是指向数组第一个元素的指针,但是当一个数组名在表达式中使用而不是作为
sizeof()
的参数时,它会更改为指向数组第一个元素的指针。 - 您必须使用&符号,因为
values[0]
是数组的第一个元素的值,而不是数组的第一个元素的地址,而scanf()
需要地址,而不是值。 记住:a[i] == *(a + i)
表示数组名称或指针a
和索引i
,并注意*
取消引用指针。 如果您编写了scanf("%lf", values)
或scanf("%lf", values + 0)
,则表示您正在传递指针。 请注意,传递scanf("%lf", &values)
将是一种类型不匹配(尽管作为地址传递的值是相同的 – 所以它巧合’工作’)。 传递的类型是’指向8个数组的指针’,这与’指向double
的指针’不同。