我检查过了,没有语法错误。我使用Code:: block在C中编码,这是我第一次遇到类似的错误。当我运行代码时,控制台启动并在一秒钟后关闭。它甚至不打印printf
里面的内容。
#include <stdio.h>
int main(void)
{
int n;
int vet[n];
int t;
int i;
int lim;
int lastswap;
int swap;
printf("Array lenght:");
scanf("%dn", &n);
for (i = 0; i < n; i++)
{
scanf("%dn", &vet[i]);
}
lim = 0;
do
{
swap = 0;
for (i = n - 1; i > lim; i--)
{
if (vet[i] < vet[i - 1])
{
t = vet[i];
vet[i] = vet[i - 1];
vet[i - 1] = t;
swap = 1;
lastswap = i;
}
lim = lastswap;
}
} while (swap != 0);
for (i = 0; i < n; i++)
{
printf("%dn", vet[i]);
}
}
主要问题
n
的值为undefined当它用于指定数组的大小时vet
。[1][2]
动态数组(在堆上)
创建在运行时确定大小的数组的首选方法是在堆上分配内存。[2]为此,应按正确顺序执行以下步骤:
- 声明
n
- 输入
n
(也验证输入:检查scanf
的结果,也如果输入有一个合理的大小) - 分配
vet
(通过malloc
作为int
指针)
…在写入数组之前。顺便说一句:不要忘记在使用内存后将其free
。
像这样的东西可以是你的基本框架(根据需要更改UPPER_LIMIT
):
#define UPPER_LIMIT 1024 /* or enum { UPPER_LIMIT=1024 }; */
int n;
if (scanf("%d", &n) == 1) {
if (0 < n && n < UPPER_LIMIT) {
int* vet = malloc(n*sizeof *vet);
if (vet) {
/* work on vet */
}
free(vet);
}
}
固定大小的数组另一个选择是使用固定维度的数组,然后你必须检查输入的n
是否在固定数组的范围内:
#define UPPER_LIMIT 1024 /* or enum { UPPER_LIMIT=1024 }; */
int n;
int vet[UPPER_LIMIT];
if (scanf("%d", &n) == 1) {
if (0 < n && n < UPPER_LIMIT) {
/* work on vet */
}
}
二次问题在scanf
的格式字符串中使用换行符会导致中讨论的问题,当换行符在格式字符串中时,scanf的行为。所以最好切换到scanf("%d", &n);
和scanf("%d", &vet[i]);
。BTW:不要忘记检查scanf
的返回值和输入。
脚注
[1]目前尚不清楚为什么GDB在线调试器接受此为有效代码,但这可能是另一个问题的主题。
[2]C99支持可变长度数组(VLA),这是一种在运行时确定大小的数组声明方式。为此,必须在数组声明之前定义size变量,其值大于零。(详见数组声明小节可变长度数组)。C11将可变大小数组作为实现定义的特性——这意味着符合标准的C99代码可能无法移植。对于vla的实际好处也没有达成一致意见,例如在C
中理解变长数组的困难可变大小数组C99(+):
#define UPPER_LIMIT 1024 /* or enum { UPPER_LIMIT=1024 }; */
int n;
if (scanf("%d", &n) == 1) {
if (0 < n && n < UPPER_LIMIT) {
int vet[n];
/* work on vet */
}
}
我有点明白了。我将n
声明为常量,删除了scanf
,它工作了。