刚接触编程,我正在解决一个问题,我应该打印一个递减数字的正方形图案,使得5
将给予:
5 5 5 5 5 5 5 5 5
5 4 4 4 4 4 4 4 5
5 4 3 3 3 3 3 4 5
5 4 3 2 2 2 3 4 5
5 4 3 2 1 2 3 4 5
5 4 3 2 2 2 3 4 5
5 4 3 3 3 3 3 4 5
5 4 4 4 4 4 4 4 5
5 5 5 5 5 5 5 5 5
字符串
我想到了用数组,反复从数组中减去并打印出来来解决这个问题;
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
// Complete the code to print the pattern.
int *arr;
int k = 1;
arr = calloc(2 * n - 1, sizeof(char));
for (int i = 0; i < 2 * n - 1; i++) {
*(arr + i) = n;
}
do {
for (int i = 0; i < 2 * n - 1; i++) {
printf("%d ", arr[i]);
}
printf("\n");
for (int i = k; i < 2 * n - 1 - k; i++) {
arr[i] = arr[i] - 1;
}
k++;
} while (k <= n);
k = n - 1;
for (int j = 1; j < n; j++) {
for (int i = k; i < 2 * n - 1 - k; i++) {
arr[i]++;
}
k--;
for (int i = 0; i < 2 * n - 1; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
return 0;
}
型
这在Visual Studio代码中可以工作,但在网站上的编译器上不行,在我测试的另一个在线编译器上也不行。我假设我在calloc
部分搞砸了。有什么问题吗?
4条答案
按热度按时间mlmc2os51#
sizeof(int)
,而不是sizeof(char)
。w8f9ii692#
您使用动态分配的阵列的方法是1)不安全和2)低效的。
首先,您需要检查用户在scanf调用中是否输入了有效的正数
字符串
您还需要检查是否已成功分配内存。你必须正确地指定分配数组的元素的大小。也就是说,您需要使用表达式
sizeof( int )
而不是sizeof( char )
型
第三,你需要知道最大输出值的宽度。否则,具有图案的table将不会正确对齐。例如,尝试在
n
等于10
时运行程序。你的程序也有太多的循环。
最后你需要释放分配的内存。
为了输出模式,不需要动态分配内存。只需使用一对嵌套的for循环和函数
printf
就足够了。这是一个演示程序。这个程序的诀窍就是用这两个表达式
型
调查他们。
型
程序输出可能如下所示
型
kfgdxczn3#
内存分配在C中是如何工作的?//我的代码有什么问题?
您的分配语句确实存在一个主要问题,导致了未定义的行为,与您的观察结果一致:代码可以如预期的那样在一些目标上工作而在其他目标上不工作。
在
arr
中为2 * n - 1
条目分配内存,使用arr = calloc(2 * n - 1, sizeof(char));
问题是arr
是int
的数组,因此元素大小应为sizeof(int)
。通过分配2 * n - 1
字节,当代码写入超出所分配块的末尾时,会导致未定义的行为。这里有一个更安全的方法:始终使用目标条目类型的大小:
字符串
还要注意,您应该检查
scanf
和calloc
故障,并在不再需要内存时释放内存。以下是修改后的版本:
型
然而,请注意,代码可以进一步简化,而无需内存分配,通过从简单的数学公式计算动态打印值:
型
zte4gxcn4#
为什么不干脆:
字符串
?