gpt4 book ai didi

c - C 中的可变大小数组和数组指针

转载 作者:行者123 更新时间:2023-11-30 16:19:01 24 4
gpt4 key购买 nike

我正在 HackerRank 中进行编码练习。在 C++ 的可变大小数组练习中,我尝试用 C 来做,但没能做对。

我的代码有时会通过简单的测试用例 0,但有时不会。代码完全相同,但得到不同的答案。

int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */

int n, q;
scanf("%d%d", &n, &q);

int *p_arr[n];

if (n > 0) {
for (int i = 0; i < n; i++) {
int tmp;
scanf("%d", &tmp);

int tmp_arr[tmp];
p_arr[i] = tmp_arr;
for (int j = 0; j < tmp; j++) {
int value;
scanf("%d", &value);
p_arr[i][j] = value;
printf("%d ", p_arr[i][j]);
}
printf("\n");
}
}

if (q > 0) {
for (int i = 0; i < q; i++) {
int row, col;
scanf("%d%d", &row, &col);
printf ("%d %d\n", row, col);
int answer = p_arr[row][col];
printf("%d\n", answer);

}
}
return 0;

}

这是我得到的错误答案

1 5 4 

1 2 8 9 3

0 1

21973

1 3

32764

我不知道2197332764来自哪里。

这就是我所期望的答案

1 5 4 

1 2 8 9 3

0 1

5

1 3

9

有时我得到了错误的答案,有时我得到了正确的答案。为什么会这样?非常感谢!

最佳答案

继续评论,如果练习涉及可变长度数组,那么它应该用 C 编写,因为 C++ 标准不提供 VLA(并且在 C99 添加后,从 C11 开始它们已成为可选)

代码的主要问题(除了分配输入完全失败之外)是它调用未定义的行为,因为int tmp_arr[tmp]超出了范围在 for 循环的末尾。使用 p_arr[i] = tmp_arr; 分配的内容不再存在于循环之外,因为 tmp_arr 不再存在。任何在值超出范围后访问该值的尝试都会调用未定义的行为,请参阅 Undefined, unspecified and implementation-defined behavior

每次处理输入时,都必须验证输入成功并且获取的值在有效范围内。例如,nq 都必须是正值。使用 scanf 你可以(至少)做到

    if (scanf("%d%d", &n, &q) != 2 || n <= 0 || q <= 0) {
fputs ("error: invalid format or value.\n", stderr);
return 1;
}

以上内容验证了已收到 2 个输入并且均为正值。

为了保留使用 p_arr[i] = tmp_arr; 分配的指针,tmp_arr 必须是分配的类型以处理未知的 tmp 元素的数量,或者必须在循环外部声明它(并且足够大以处理所有预期值 - 考虑到 tmp 被读取为输入 - 似乎不是预期的方法) 。您也不能将 tmp_arr 声明为静态,因为只有一个实例,并且将其重复分配给 p_arr[i] 会保留 p_arr[i] 的所有元素code> 指向同一个地方。

简单地分配tmp_arr,然后对p_arr[i]的分配将在程序的生命周期内保留或直到它被释放,例如

        int *tmp_arr = calloc (tmp, sizeof *tmp_arr);   /* allocate */
if (!tmp_arr) { /* validate every allocation */
perror ("calloc-tmp_arr");
return 1;
}
p_arr[i] = tmp_arr;

(注意: calloc 上面用于将分配的新内存归零。您可以使用 malloc 代替,因为代码分配给每个元素)

将其放在一起并添加(最小)验证,您可以执行类似于以下操作的操作:

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

int main (void) {

int n, q; /* validate EVERY input */
if (scanf("%d%d", &n, &q) != 2 || n <= 0 || q <= 0) {
fputs ("error: invalid format or value.\n", stderr);
return 1;
}

int *p_arr[n]; /* array of n-pointers to int */

for (int i = 0; i < n; i++) {
int tmp;
if (scanf("%d", &tmp) != 1 || tmp <= 0) { /* validate! */
fputs ("error: invalid input - tmp.\n", stderr);
return 1;
}

int *tmp_arr = calloc (tmp, sizeof *tmp_arr); /* allocate */
if (!tmp_arr) { /* validate every allocation */
perror ("calloc-tmp_arr");
return 1;
}
p_arr[i] = tmp_arr;
for (int j = 0; j < tmp; j++) {
int value;
if (scanf("%d", &value) != 1) { /* validate! */
fputs ("error: invalid input - value.\n", stderr);
return 1;
}
p_arr[i][j] = value;
printf ("%d ", p_arr[i][j]);
}
putchar ('\n'); /* no need to printf a single-character */
}

for (int i = 0; i < q; i++) {
int row, col; /* validate! */
if (scanf ("%d%d", &row, &col) != 2 || row < 0 || col < 0) {
fputs ("error: invalid input, row or col.\n", stderr);
return 1;
}
printf ("%d %d\n%d\n", row, col, p_arr[row][col]);
}

for (int i = 0; i < n; i++)
free (p_arr[i]);

return 0;
}

(注意:未经测试,因为未提供 hackerrank 输入)

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

关于c - C 中的可变大小数组和数组指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55740524/

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