这是我的代码:
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 <stdio.h>
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] = %gn", values[0]);
return(0);
}
请注意,这包括输出末尾的换行符,并且还会诊断输入上何时出现问题(例如没有数据或无效数据(。
我以为数组只是指向数组第一个元素的指针?为什么我必须使用与号?
- 数组
- 不仅仅是指向数组第一个元素的指针,但是当数组名称在表达式中用作
sizeof()
参数以外的参数时,它会更改为指向数组第一个元素的指针。 - 您必须使用与号,因为
values[0]
是数组第一个元素的值,而不是数组第一个元素的地址,并且scanf()
需要地址,而不是值。 请记住:a[i] == *(a + i)
数组名称或指针a
和索引i
,并注意取消引用指针*
。 如果你写了scanf("%lf", values)
或scanf("%lf", values + 0)
,你正在传递一个指针。 请注意,传递scanf("%lf", &values)
将是类型不匹配(尽管作为地址传递的值是相同的 - 所以它恰好"有效"(。 传递的类型将是"指向 8double
数组的指针",这与"指向double
的指针"不同。