【问题标题】:initializing an array using a function in C使用 C 中的函数初始化数组
【发布时间】:2013-11-18 20:43:54
【问题描述】:

我正在做课堂作业,我想我会用一个问题来打扰你们:

所以程序的目的是让用户输入数组的大小,然后用一些数据对其进行初始化。最大大小为 20。我的问题是当设置大小超过 14 并尝试对其进行初始化时,数组会崩溃。例如,如果它将大小设置为 20,它会接受它,但是当我尝试初始化它时,它会崩溃。我不知道我在做什么。非常感谢您的帮助。

非常感谢,

埃西

int main ()
{

     int sizeOfArray = 0; //size Of Array
     float myArray[sizeOfArray];

     //I have a piece a line or two of code that asks the user for the size of the    
       array

     printf("Let's Initialize an array of size %d!!\n", sizeOfArray);
     do
     {
           printf("Enter array element %d : ", initCounter+1);
           myArray[initCounter] = userInitArray();
           initCounter++;
      }while (initCounter < sizeOfArray);
}

float userInitArray()
{
      float num;
      scanf("%f", &num);
      return num;
}

【问题讨论】:

  • initCounter 在哪里初始化?
  • 如果这是C代码,为什么还要标记[c++]
  • 你也可以在main() 的第二行之后停下来。从字面上看,没有什么好的可以跟随。
  • @Raxvan,希望在某个地方的静态存储持续时间,否则 OP 将陷入痛苦的世界:-)

标签: c arrays function function-pointers


【解决方案1】:

这两行

 int sizeOfArray = 0; //size Of Array
 float myArray[sizeOfArray];

创建一个空数组。因此,您以后尝试存储在此数组中的任何内容都是越界访问 并调用未定义行为。您的程序在第 14 次调用时崩溃的事实只是运气。它也可能在第一个上崩溃。

【讨论】:

    【解决方案2】:
    int sizeOfArray = 0; //size Of Array
    float myArray[sizeOfArray];
    

    您的数组在此处创建,大小为零。当您稍后增加sizeOfArray 时,它不会神奇地扩展。您需要首先设置 size 变量(从您的“一两行代码”用户输入)然后基于此创建数组。

    您可能还想对数组大小施加一些合理的上限,这样您就不会在尝试创建一个包含十亿个条目的数组时炸毁堆栈:-)

    【讨论】:

      【解决方案3】:

      您有一个大小为零的(variable-length) array。您需要先询问大小,然后分配数组。否则任何分配给数组元素的尝试都会导致undefined behaviour

      【讨论】:

        【解决方案4】:

        你可以这样做:

        int sizeOfArray; //size Of Array
        printf("tell me the size of the array");
        scanf("%d",&sizeOfArray);
        float myArray[sizeOfArray]; // not a good practice 
        

        正确的做法是:

        int sizeOfArray; //size Of Array
        float *myArray;
        printf("tell me the size of the array");
        scanf("%d",&sizeOfArray);
        myArray=malloc(sizeof(float)*sizeOfArray); 
        

        这时你可以把指针当作一个普通的数组来使用。 并像这样调用:myArray[3] = doSomething();

        编辑请注意,由于您已经知道最大大小,您可以避免执行上面列出的动态分配:

        #Define MAXSIZE 20
        int main ()
        {
        
             int sizeOfArray; //size Of Array
             float myArray[MAXSIZE];
        
             printf("tell me the size of the array\n");
             scanf("%d",&sizeOfArray);
        
             printf("\nLet's Initialize an array of size %d!!\n", sizeOfArray);
             do
             {
                   printf("Enter the element at myArray[%d] : ", initCounter+1);
                   myArray[initCounter] = userInitArray();
                   initCounter++;
              }while (initCounter < sizeOfArray);
        }
        
        float userInitArray()
        {
              float num;
              scanf("%f", &num);
              return num;
        }
        

        这最后一个选项可能正是您的老师真正想要的。

        【讨论】:

        • 感谢您的帮助和意见!工作!非常感谢!
        【解决方案5】:

        您需要在动态分配 myArray 之前读取 sizeOfArray,如下所示:

        float * myArray = malloc(sizeOfArray * sizeof(float));

        这是在堆上分配 sizeof(float) * sizeOfArray 字节的内存并将分配的内存地址分配给 myArray。

        这可能很难理解 C 中的数组,它们实际上只是指向内存的指针 - 在您的程序中,数组 myArray 静态分配在堆栈上,大小为 0。您不能向其中添加任何元素或分配给任何索引,它不会增长,它的前 0 个浮点元素很长。在这种情况下,您的程序可能发生的最好的事情是它会崩溃。最坏的情况,它不会崩溃并且会发生奇怪的事情;

        您真的应该阅读一些有关 C 中的内存分配/管理的内容。

        【讨论】:

        • 感谢您的帮助和意见!非常感谢!
        • 这里不需要动态内存分配,C 已经有 VLA 多年了。即使您确实采用malloc 方式,强制转换返回值也是一种不好的形式。而且数组不是指针。它们经常衰减成指向第一个元素的指针,但是有非常明显的区别。
        • 谢谢@paxdiablo,你说得对。我确实忘记了 VLA,在过去 20 年里做了更多的 C++ :) 我是正确的。你说得对,数组不是指针,但相信我,我理解其中的区别,但最后,例如将它作为函数参数传递时,它只是指针。
        【解决方案6】:

        我认为您忘记在程序开头添加函数原型(main 之前)。
        还有

         int sizeOfArray = 0; //size Of Array
         float myArray[sizeOfArray];   
        

        错了。
        当您使用可变长度数组(在 C99 中有效)时,您可以这样做

         int sizeOfArray; //size Of Array
         printf("Let's Initialize an array of size %d!!\n", sizeOfArray);
         float myArray[sizeOfArray];
        

        【讨论】:

        • 这在 C 语言中是非法的。对不起 :)
        • @egur;这在 C 中是合法的(C99 允许这样做):)
        • 它并不真正合法,但 gcc 确实“理解”这些事情并很好地处理它们。
        【解决方案7】:

        C 或 C++ 不支持动态数组。 将您的数组更改为:

        float* myAraray;
        //later when you have the size , allocate it:
        myArray = (float*)malloc(arrSize * sizeof(float));
        

        【讨论】:

        • C99 支持动态数组。
        猜你喜欢
        • 2021-09-13
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-19
        • 1970-01-01
        相关资源
        最近更新 更多