关于C中数组的各种问题

时间:2015-01-20 16:03:19

标签: c arrays scanf

所以我现在正在努力学习C,并且我正在编写基本脚本以确保我有基础,但我很难通过以下代码来理解这个问题:

#include <stdio.h> //Linking external libraries.
#include <math.h>

int main(void) {
    /* First I will set my variables.
    */
    double std; //Standard Deviation
    double sqdif;
    double avg;
    int N=10; //number of elements
    double X[10]; //Not sure why I cannot use N here.
    int i;


    /* Now I will prompt for input and listen for values,
    then assign those values respectively.*/

    for (i = 1; i < 11; i++) {
        printf("Please enter X[ %d ", i);
        printf("]: ");
        scanf("%d", &X[i-1]);
    }

    for (i = 0; i < N; i++) {
        avg = avg + X[i];
        printf("\n %d", X[i]);
    }
    avg = avg / N;
    printf("\nThe average is: %d", avg);


    return 0;
}

我的两个主要问题是:

  1. 为什么我不能用N来定义我的数组X?
  2. 为什么我的剧本会回归:
  3.   

    1        4196197        4196197        4196197        4196197        4196197        4196197        4196197        4196197        4196197       平均值是:4196197

    我的结果?如果您在代码中看到错误,请告诉我们!

    谢谢,

    聚苯乙烯。这显然是一个不完整的剧本。

4 个答案:

答案 0 :(得分:1)

printf("\n %d", X[i]);

应该是

printf("\n %f", X[i]);

因为X[i]的类型为double

即使没有错,请考虑重写for循环以获得更好的可读性,当然会再次将%d更改为%f

 for (i =0; i < 10; i++) {
        printf("Please enter X[ %d ]:", i);
        scanf("%f", &X[i]);
    }

答案 1 :(得分:1)

  

为什么我不能用N来定义我的数组X?

你可以。您正在使用可变长度数组。可变长度数组在C99中引入。您需要在C99模式下编译代码(使用-std=c99选项)。

  

为什么我的剧本会回归:
  1 4196197 4196197 4196197 4196197 4196197 4196197 4196197 4196197 4196197平均为:4196197

avg未初始化。在使用in语句之前用0初始化它:

avg = avg + X[i];  

否则程序会因未定义的行为而出现错误。另请注意,分别需要%lf%f来扫描和打印double数据类型。

double avg = 0; /* Initialize it with 0 */
int N=10; 
double X[N]; /* Variable length array. C99 mode needed to compile the code */

答案 2 :(得分:1)

  

为什么我不能用N来定义我的数组X?

在1999标准之前,必须使用常量表达式指定数组大小,其值可以在编译时计算;这意味着数字文字,例如10预处理器宏将扩展为数字文字,例如#define N 10,或算术表达式,涉及文字或宏,扩展到文字:

#define X 10
...
int arr1[X];     
int arr2[2 * X];
int arr3[10];
int arr4[2 * 4 + 2];

所有X2 * X102 * 4 + 2都是常量表达式,可以在编译时进行评估。

在您的代码中,N不是常量表达式;它只是一个常规变量,其值在运行时才建立。

C99引入了可变长度数组的概念,其大小可以在运行时确定。如果您使用过C99编译器(例如,带有-std=c99选项的gcc),那么您的代码将被编译。 Visual Studio对C99的支持是最小的,我认为当前版本根本不支持VLA。

VLA有许多限制;你不能在它们中使用初始化程序,也不能在文件范围内声明它们(在任何函数之外)。您需要小心它们,因为它们的内存是从堆栈中分配的,就像任何其他本地(auto)变量一样。

2011 C标准使VLA成为可选项(我的理解是它们是正确实施的一个主要难题),因此它们可能不会得到很好的支持。

  

为什么我的脚本会返回:   1 4196197 4196197 4196197 4196197 4196197 4196197 4196197 4196197 4196197平均为:4196197

正如其他人所指出的那样,您在printfscanf来电中使用了错误的转化说明符。 %d期望相应的参数具有类型int(适用于printf)和int *(适用于scanf)。您需要改为使用%f%lf

scanf("%lf", &X[i-1]);  // %lf expects pointer to double
...
printf("%f", X[i-1]);  // %f expects double

请注意printfscanf中的转换说明符不对称,这是重要的一种情况。要阅读double,您必须使用%lf;常规%f期望相应的参数是指向float的指针。但是,您可以使用%f打印double或float。

检查两个功能的方便的C参考手册。

您还需要初始化avg

double avg = 0.0;

答案 3 :(得分:0)

avg = avg + X[i];

avg永远不会被初始化,avg的值不确定,因此您会看到未定义的行为。

你有另一个UB

printf("\n %d", X[i]);

printf()中使用错误的格式说明符将是UB。

printf("\n %lf", X[i]);

您扫描0-9的值并打印0-10的值,此处您再次使用未初始化的a[10]元素。

汇总变化应该像:

 avg = 0;

    for (i = 0; i < N; i++) {
        printf("Please enter X[ %d ", i);
        printf("]: ");
        scanf("%lf", &X[i]);
    }

    for (i = 0; i < N; i++) {
        avg = avg + X[i];
        printf("\n %lf", X[i]);
    }
    avg = avg / N;
    printf("\nThe average is: %lf", avg);

C99支持VLA(可变长度数组),您可以使用它们

int N = 10;
double X[N]; /* Valid */