gpt4 book ai didi

Write a function which accepts as input a 2D integer array and returns the summation of all elements in it(编写一个函数,它接受一个2D整数数组作为输入,并返回其中所有元素的总和)

转载 作者:bug小助手 更新时间:2023-10-22 16:38:49 33 4
gpt4 key购买 nike



I want to write a function that accepts as input a 2D integer array (denoted by double asterisks) and the size of that array as n (number of arrays) and m (size of each array).
As output, the function should return the summation of all elements in the array. Remember, arrays in C are 0-indexed!

我想写一个函数,它接受一个2D整数数组(用双星号表示)作为输入,该数组的大小为n(数组数量)和m(每个数组的大小)。作为输出,函数应该返回数组中所有元素的总和。记住,C中的数组是0索引的!


My code is as follows, but it always output incorrect results.

我的代码如下,但它总是输出不正确的结果。


int two_d_sum(int ** arr, int n, int m) {
int sum = 0, t;

int* p = &(**arr);
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
t = *(p + i*m + j);
sum += t;
}
}
return sum;
} /* two_d_sum() */

This function is called as follows:

此函数的调用方式如下:


int main() {
printf("Enter the number of arrays in the array (n): ");
int size_n;
scanf("%d%*c", &size_n);

printf("Enter the number of elements in the array in the array (m):");
int size_m;
scanf("%d%*c", &size_m);

int **arr = (int **)malloc(size_n * sizeof(int *));
for (int i = 0; i < size_n; i++) {
arr[i] = (int *)malloc(size_m * sizeof(int));
for (int j = 0; j < size_m; j++) {
int num;
printf("Enter a number: ");
scanf("%d%*c", &num);
arr[i][j] = num;
}
}

// ...
int sum = two_d_sum(arr, size_n, size_m);
return 0;
}

更多回答

What do you pass for arr ? Show more code.

你认为arr是什么?显示更多代码。

"arrays in C are 0-indexed!": not sure that this reminder is really necessary :-)

“C中的数组是0索引的!”:不确定此提醒是否真的有必要:-)

arr is a 2D-integer array, such as int arr[5][9].

arr是一个2D整数数组,例如int arr[5][9]。

Please try to create a minimal reproducible example to show us.

请尝试创建一个最小的可复制示例来向我们展示。

An array of arrays is not the same thing as a pointer to a pointer. An array of arrays decays to a pointer to arrays. For example an array like int arr[5][9] will decay to the type int (*)[9]. Your compiler should have been complaining about you passing the wrong argument type.

数组数组与指向指针的指针不是一回事。数组的数组衰减为指向数组的指针。例如,像int arr[5][9]这样的数组将衰减为int(*)[9]类型。您的编译器应该一直在抱怨您传递了错误的参数类型。

优秀答案推荐

As coded, you assume the array is a flat 2D array (an array of arrays of int) but given the prototype for the function provided to you, arr is a pointer to an array of pointers to int, which may be implemented with independently allocated arrays (EDIT: and indeed that is how you allocate this indirect 2D array in the main() function).

根据编码,您假设数组是一个平面2D数组(int数组的数组),但给定提供给您的函数的原型,arr是指向int指针数组的指针,可以用独立分配的数组来实现(EDIT:实际上,这就是您在main()函数中分配这个间接2D数组的方式)。


You should just use the pointers, which is very simple: all you need to do is iterate with nested for loops:

您应该只使用指针,这非常简单:您所需要做的就是使用嵌套的for循环进行迭代:


int two_d_sum(int **arr, int n, int m) {
int sum = 0;

for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
sum += arr[i][j];
}
}
return sum;
}

Note that you can use a flat 2D array, either defined in the scope of main() as int arr[size_n][size_m] or allocated from the heap as int (*arr)[size_m] = calloc(sizeof *arr, size_n) and pass the dimensions first to the function two_d_sum:

请注意,您可以使用平面2D数组,该数组在main()的作用域中定义为int arr[size_n][size_m],或者从堆中分配为int(*arr)[size_m]=calloc(sizeof*arr,size_n),并首先将维度传递给函数two_d_sum:


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

int two_d_sum(size_t n, size_t m, int arr[n][m]) {
int sum = 0;

for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
sum += arr[i][j];
}
}
return sum;
}

int main(void) {
printf("Enter the number of arrays in the array (n): ");
int size_n;
if (scanf("%d%*c", &size_n) != 1)
return 1;

printf("Enter the number of elements in the array in the array (m):");
int size_m;
if (scanf("%d%*c", &size_m) != 1)
return 1;

// allocate the flat 2D array from the heap
int (*arr)[size_m] = malloc(sizeof(*arr) * size_n);
// alternately: int (*arr)[size_m] = malloc(sizeof(**arr) * size_n * size_m);
// or: int (*arr)[size_m] = malloc(sizeof int[size_n][size_m]);

if (arr == NULL) {
fprintf(stderr, "cannot allocate memory\n");
return 1;
}
for (int i = 0; i < size_n; i++) {
for (int j = 0; j < size_m; j++) {
int num = 0;
printf("Enter a number: ");
if (scanf("%d%*c", &num) != 1)
return 1;
arr[i][j] = num;
}
}

// ...
int sum = two_d_sum(size_n, size_m, arr);
printf("sum is %d\n", sum);
free(arr);
return 0;
}


This is not a 2D array but an array of pointers forming a look-up table of sorts. Unlike in a 2D array, these pointer tables do not allocate memory in a contiguous chunk. Each time you call malloc, a new chunk gets allocated and you can't know where in the heap memory it ends up. See Correctly allocating multi-dimensional arrays for details.

这不是2D阵列,而是形成各种查找表的指针阵列。与2D数组不同,这些指针表不在连续块中分配内存。每次调用malloc时,都会分配一个新的块,并且您不知道它在堆内存中的位置。有关详细信息,请参阅正确分配多维数组。


Your caller code should be replaced with a proper 2D array:

您的调用方代码应替换为正确的2D数组:


int (*arr) [size_m] = malloc( sizeof(int[size_n][size_m]) );
...
free(arr);

You must rewrite the function to use 2D arrays too:

您必须重写函数才能使用2D数组:


int two_d_sum(int n, int m, int arr[n][m])

And now it can be called as two_d_sum(size_n, size_m, arr);.

现在它可以被称为two_d_sum(size_n,size_m,arr);。


And if you like, you can now probably do pointer aliasing inside the function like int* p = (int*)arr;, although that is still questionable code and strictly speaking still not well-defined still. Because pointer arithmetic going out of bounds on each of the sub arrays in this array-of-arrays is still not well-defined.

如果你愿意的话,你现在可能可以在函数内部进行指针混叠,比如int*p=(int*)arr;,尽管这仍然是有问题的代码,严格来说仍然没有定义好。因为在这个数组数组中的每个子数组上超出界限的指针算术仍然没有定义好。


I don't see the reason why you can't just access the array as arr[i][j] inside the function.

我看不出为什么不能在函数内以arr[I][j]的形式访问数组。


更多回答

@Gerhardh: the main functions implements the task described as a 2D integer array (denoted by double asterisks). Using a 2D VLA or an allocated 2D array seems beyond the OP's skill level at this point, and VLAs might not be available on their programming environment.

@Gerhardh:主要函数实现了描述为2D整数数组(用双星号表示)的任务。在这一点上,使用2D VLA或分配的2D阵列似乎超出了OP的技能水平,并且VLA可能在其编程环境中不可用。

The int** arrays are arguably much harder to work with than pointer-to-VLA, since the former tends to be far more error-prone and leaky. The problematic format of them is the very reason why the OP is asking this question in the first place. The only disadvantage with pointer-to-VLA is that the array pointer declarations look a bit exotic until you get the hang of them.

可以说,int**数组比指向VLA的指针更难处理,因为前者往往更容易出错和泄漏。他们有问题的格式正是OP提出这个问题的原因。指针指向VLA的唯一缺点是数组指针声明看起来有点奇怪,直到你掌握了它们的窍门。

@Gerhardh: I posted an alternate implementation

@Gerhardh:我发布了一个替代实现

@Lundin: I agree and posted an alternate implementation, but VLAs are alas still optional in C23.

@Lundin:我同意,并发布了一个替代实现,但VLA在C23中仍然是可选的。

VLA parameters to functions is not optional in C23. From the C23 draft's definition of __STDC_NO_VLA__: "The integer constant 1, intended to indicate that the implementation does not support variable length arrays with automatic storage duration. Parameters declared with variable length array types are adjusted and then define objects of automatic storage duration with pointer types. Thus, support for such declarations is mandatory."

函数的VLA参数在C23中不是可选的。根据C23草案对__STDC_NO_VLA_的定义:“整数常量1,旨在表明该实现不支持具有自动存储持续时间的可变长度数组。使用可变长度数组类型声明的参数会被调整,然后使用指针类型定义具有自动存储持续时间的对象。因此,必须支持此类声明。”

I find int* arr = malloc(n*m*sizeof(int)); more intuitive. For accessing an element at the (i,j) cell one could define an access method returning arr[i*m + j]. Do you think this method could have some potential drawbacks compared to the one you showcased?

@MehdiCharife arr[i*m + j] is harder to read and therefore easier to get wrong. There may also be various non-obvious performance stuff here, such as what counters this boils down to in the machine code and if that resulting code is suitable for data caching or not. But the main argument is readability, we expect to access a 2D array as arr[i][j] and nothing else.

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