gpt4 book ai didi

c - 我应该如何传递一个大小由用户输入确定的数组,并在函数中传递该数组?

转载 作者:行者123 更新时间:2023-11-30 14:35:03 26 4
gpt4 key购买 nike

(C 编程)我想知道如何通过一个直到编译时才知道其大小的函数传递数组?主要是,我的程序从用户接收数字( double ),并使用 scanf() 将所有数字存储到数组中,除了 0 之外。每当输入 0 时,都应该将其丢弃(不以任何方式存储)并且用户应该可以继续。用户输入的数量未知,但输入数量不会超过 100 万(10^6),或者直到用户输入 EOF(ctrl d)。 (不要求用户输入数组的大小,只要求输入值)。然后,我必须将数组传递给一个单独的函数,该函数将确定数组的总和。我有一个函数 count() 来计算数组中的数字,这似乎可以工作,但我的函数 sums() 似乎没有访问数组的元素,因为它每次都返回 0。我知道我可能需要一个指针,但我不确定如何去做。到目前为止我的程序如下。

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

#define MAX_SIZE 10*10*10*10*10*10

int main();
int counts(double array[]);
double sums(double array[]);
double maxFind(double array[]);


int main()
{
double arr[MAX_SIZE];
int countNums, i;
double sum, max;

printf("Please enter values\n");

while(scanf("%f", &arr[i]) != EOF && i < MAX_SIZE)
{
if(arr[i] == 0){
continue;
}
i++;
}




countNums = counts(arr);
printf("The count of numbers read from the input is %9d\n", countNums);

sum = sums(arr);
printf("The sum of these numbers is %20.10f\n", sum);

max = maxFind(arr);
printf("The max number is %20.10f\n", max);
}




int counts(double array[])
{
int countNum = 0;
for(int i = 0; i < sizeof(array) ; i++)
{
if(array[i] == 0){
continue;
}
countNum++;
}
return countNum;
}



double sums(double array[])
{
int i;
double sumNum = 0;
for(i = 0; i < sizeof(array); i++){
sumNum = sumNum + array[i];
}
return sumNum;
}



double maxFind(double array[])
{
double maxNum = array[0];
for(int i = 1; i < sizeof(array); i++){
if(array[i] > array[i-1]){
maxNum = array[i];
}
}
return maxNum;
}

最佳答案

你面临着“如何读取未知数X?”的经典案例。答案是简单地用 malloc (或 callocrealloc )分配一些初始元素数,并跟踪你拥有的 allocated 和元素数 used (填充)。当 used == allocated 时,您对数组进行 realloc 并将可用元素数量增加一定量,可以是每次固定的数量,也可以是当前的某个倍数。将元素数量加倍可以很好地平衡分配增长和所需的重新分配数量。

一个简单的示例,使用 scanf 读取未知数量的 double ,然后输出读取的数字和总和:

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

int main (void) {

size_t used = 0, allocated = 2; /* used doubles/allocated doubles */
double *arr, sum = 0.0; /* array & sum of elements */

/* allocate initial 'allocated' number of doubles */
if (!(arr = malloc (allocated * sizeof *arr))) {
perror ("malloc-arr");
return 1;
}

while (scanf ("%lf", &arr[used]) == 1) { /* read doubles until EOF */
sum += arr[used++]; /* add to sum, increment used */
if (used == allocated) { /* if used == allocated */
/* reallocate more doubles using a temporary pointer */
void *tmp = realloc (arr, 2 * allocated * sizeof *arr);
if (!tmp) { /* validate reallocation */
perror ("realloc-tmp");
break; /* don't exit, original arr still good, break */
}
arr = tmp; /* assign reallocated block to arr */
allocated *= 2; /* update number allocated */
}
}
printf ("%zu doubles entered with sum: %.2f\n", used, sum);

free (arr); /* free the memory you have allocated */
}

(注意:您始终将 realloc 指向临时指针,因为如果 realloc 失败,它将返回 NULL 覆盖您的原始指针地址,从而阻止您访问,或者 free() the original block resulting in a *memory leak*. If realloc` 确实失败,通过使用临时指针,您现有的数据将通过原始指针保留)

您现在可以将 arr 及其保存的元素数量 (used) 传递给任何需要该信息的函数。

示例使用/输出

$ ./bin/sumdoubles
1.1
2.2
3.3
4.4
5.5
6.6
7.7
8.8
9.9
9 doubles entered with sum: 49.50

或从文件重定向 10,000 个浮点值:

$ ./bin/sumdoubles < ../dat/10000float.txt
10000 doubles entered with sum: 117991733.64

内存使用/错误检查

在您编写的动态分配内存的任何代码中,对于分配的任何内存块,您都有两个责任:(1) 始终保留指向起始地址的指针内存块,因此,(2) 当不再需要它时可以释放

您必须使用内存错误检查程序来确保您不会尝试访问内存或在分配的 block 的范围之外进行写入,尝试读取或基于未初始化的值进行条件跳转,最后,以确认您释放了已分配的所有内存。

对于 Linux,valgrind 是正常选择。每个平台都有类似的内存检查器。它们使用起来都很简单,只需通过它运行您的程序即可。

$ valgrind ./bin/sumdoubles
==6316== Memcheck, a memory error detector
==6316== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6316== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6316== Command: ./bin/sumdoubles
==6316==
1.1
2.2
3.3
4.4
5.5
6.6
7.7
8.8
9.9
9 doubles entered with sum: 49.50
==6316==
==6316== HEAP SUMMARY:
==6316== in use at exit: 0 bytes in 0 blocks
==6316== total heap usage: 6 allocs, 6 frees, 2,288 bytes allocated
==6316==
==6316== All heap blocks were freed -- no leaks are possible
==6316==
==6316== For counts of detected and suppressed errors, rerun with: -v
==6316== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放分配的所有内存并且不存在内存错误。

编辑 - 函数中的其他问题

for(i = 0; i < sizeof(array); i++)

sizeof(array) 就是 sizeof(a_pointer) 。数组在访问时会转换为指针。请参阅:C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)。您可能想要传递指针和元素数量,例如

double sums(double *array, size_t n)
{
size_t i;
double sumNum = 0;

for(i = 0; i < n; i++){
sumNum = sumNum + array[i];
}

return sumNum;
}

您将在 sums 中调用 main() 作为

size_t sum = sums (arr, used);

使用 sums 函数的示例(稍作修改以适应口味):

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

double sums (double *array, size_t n)
{
double sumNum = 0;

for (size_t i = 0; i < n; i++)
sumNum = sumNum + array[i];

return sumNum;
}

int main (void) {

size_t used = 0, allocated = 2; /* used doubles/allocated doubles */
double *arr, sum = 0.0; /* array & sum of elements */

/* allocate initial 'allocated' number of doubles */
if (!(arr = malloc (allocated * sizeof *arr))) {
perror ("malloc-arr");
return 1;
}

while (scanf ("%lf", &arr[used]) == 1) { /* read doubles until EOF */
if (++used == allocated) { /* if used == allocated */
/* reallocate more doubles using a temporary pointer */
void *tmp = realloc (arr, 2 * allocated * sizeof *arr);
if (!tmp) { /* validate reallocation */
perror ("realloc-tmp");
break; /* don't exit, original arr still good, break */
}
arr = tmp; /* assign reallocated block to arr */
allocated *= 2; /* update number allocated */
}
}
sum = sums (arr, used); /* call functions here */

printf ("%zu doubles entered with sum: %.2f\n", used, sum);

free (arr); /* free the memory you have allocated */
}

(输出是相同的)

仔细检查一下,如果您还有任何其他问题,请告诉我。

关于c - 我应该如何传递一个大小由用户输入确定的数组,并在函数中传递该数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58703952/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com