“返回”数组时的静态或指针

时间:2018-05-22 19:56:02

标签: c arrays pointers static

我正在尝试使用随机值加载大小为n的数组(用户输入)。我已经读过你不能在C中返回一个数组,你必须使用一个指针(这很令人困惑)。但是,我已经读过如果你将该数组存储到返回函数中的局部变量,则指针将不起作用并且可以使用静态数组(可以在函数中返回吗?)。另外,我已经读过你应该在使用数组后调用free打开空间备份了吗?我必须使用它是错误的,因为它崩溃了。所以我现在评论它。一些澄清会很棒。

这是我到目前为止所拥有的。打印时,它只是打印我假设的只是垃圾。

int* prefixAverages1(int);

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main() {

    int choice;
    int input;

    printf("What is the size of the array?:");
    scanf("%d", &input);
    printf("Do you want to run prefixAverages 1 or 2?");
    scanf("%d", &choice);

    switch(choice) {
        case 1:
            printf("Beginning prefixAverages1\n");
            int *a = prefixAverages1(input);
            for (int i=0; i < input; i++) {
                printf("%d", &i);
                printf("%d \n", a[i]);
            }
            //free(a);
            break;
    }
}

int* prefixAverages1(int input) {
    int x[input];
    int *a = (int*)malloc(input);
    srand(time(NULL));  

    for(int i = 0; i < input; i++) {
        int s = 0;
        for(int j = 0; j < i; j++) {
            int r = rand() % 100;
            x[j] = r;
            s = s + x[j];
        }
        a[i] = s / (i+1);
        printf("%d \n", a[i]);
    }
    return a;
}

我知道我的语法可能不太好。我多年没有触及C,所以如果我的错误是语法上的,请告诉我。

编辑:值在函数中按预期打印。在clairity的代码中添加了print语句

3 个答案:

答案 0 :(得分:0)

首先,$ cygcheck-dep -r xwinclip # /usr/bin/cygcheck-dep: xwinclip: requires ( cygwin libX11_6 libXfixes3 ) 采用的是字节数,而不是绝对数组大小 - 所以改变这一行: -

malloc

int *a = (int*)malloc(input);

其次,要调试正在打印的错误值,请在函数int *a = malloc(input*sizeof(int)); 中添加打印: -

prefixAverages1

在主要打印中,摆脱第一个打印..这可能会让你觉得打印错误值。本地循环计数器变量的地址看起来像垃圾

...
...
a[i] = s / (i+1);
printf("%d \n", a[i]);
...

如果您想跟踪数组元素的索引,也可以将其修改为: -

printf("%d", &i);

您必须重新引入printf("%d", i); 以避免泄漏内存

你应该遵循@ AustinStephens的建议并避免使用第二个功能

答案 1 :(得分:0)

只要有一个用随机值加载数组的函数就可以了:

void randomValues(int arr[], int size);

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main() {
    int i;
    int input;
    int *array;

    printf("What is the size of the array?: ");
    scanf("%d", &input);

    array = malloc(sizeof(int) * input);

    randomValues(array, input);

    for(i = 0; i < input; ++i)
        printf("array[%d] = %d\n", i, array[i]);

    free(array);

    return 0;
}

void randomValues(int arr[], int size) {
    int i;
    int r;

    srand((int) time(0));

    for(i = 0; i < size; ++i) {
        r = rand() % 100;
        arr[i] = r;
    }
}

答案 2 :(得分:0)

  

我试图随机加载大小为n的数组(用户输入)   值。我已经读过你不能在C中返回数组,你必须使用   指针(这很令人困惑)。

是的,指针和数组之间的关系以及数组本身无法做到的令人惊讶的广泛范围是常见的混淆点。在某种程度上,它是一种迂腐的区别。几乎所有C都允许你使用数组,它会让你通过一个指针来完成,但它会自动数组类型的值转换为适当的指针,这样这些细节就会被隐藏起来。

但在某些地方它会戳出来。例如,没有有效的语法允许您甚至尝试声明一个返回数组的函数。

在其他地方,它会产生误导。例如,您可以声明一个出现的函数来接受一个数组作为参数,但标准明确指定该参数实际上是一个相应的指针(并且当这个指针自然失效时)无论如何你都称这样的功能)。具体做法是:

int foo(int x[3]);

100%相当于

int foo(int *x);
  

但是,如果你,我已经读过了   将该数组存储到返回函数中的局部变量,   指针不起作用

这不是特别关注数组,而是一般的自动变量。当它们超出范围时 - 逻辑上不再存在 - 在声明它们的最内层块的末尾 - 因此一旦函数返回,指向或进入这些对象的指针就不再有效。获得这种指针值的一种方法是使函数返回它。这本身就没问题,但你不能安全地取消引用这样的指针值。

  

可以使用静态数组(可以   在函数中返回?)。

任何类型的静态变量的生命周期都是程序的整个执行。因此,将指针(in)返回到函数的静态变量是安全的并且是有意义的。但是虽然它可以从函数返回指向静态数组的指针,但你仍然无法返回这样的数组。

  

另外,我读过你应该这么做的   使用数组后自由调用打开空间备份?

您应释放已使用其中一个内存分配函数(malloc()等)分配的内存,而不释放其他内存。但是当你在函数内部分配内存时,除了其他方式之外,你可以通过返回指向它的指针来让调用者负责释放内存。

事实上,您在示例代码中演示的大多数内容在这些方面都很好。但是,您确实发生了破坏程序的关键错误。这里:

    int *a = (int*)malloc(input);

您分配input 字节并将指针存储在a中,但对inputint对象的存储空间不足}。 int的大小因实现而异,但标准允许的最小大小为两个字节,最常见的大小为四个字节。要为input类型的int对象分配空间,基本习惯用语是

int *a = malloc(input * sizeof(int));

就个人而言,我更喜欢

int *a = malloc(input * sizeof(*a));

因为无论指针的引用类型是什么类型,我都会得到正确的大小,即使我稍后更改它。

您将分配的空间视为比实际大的空间这一事实很可能解释了您的程序的不当行为,包括当您尝试释放已分配的内存时崩溃。