为什么超过44个字符时会打印随机符号

Tac*_*Cat 4 c arrays

我正在从C编程:现代方法中学习C语言.现在我要进行有关数组的练习.其中一个练习是编写一个以不同方式打印输入消息的过滤器.

我到目前为止(见下面的代码),一切正常,直到字符数超过44,然后它打印随机符号.如果字符数低于44,一切正常.我完全不知道为什么会这样做.问题出在哪里,解决方案可能是什么?

int i = 0, k = 0;
char message[k],ch;

printf("Enter a message: ");
while(toupper(ch = getchar()) != '\n')
{
    message[k] = ch;
    k++;
}
printf("In B1FF-speak: ");
for (i = 0; i <= k - 1; i++)
{
    switch(toupper(message[i]))
    {
        case 'A':
            printf("4");
            break;
        case 'B':
            printf("8");
            break;
        case 'E':
            printf("3");
            break;
        case 'I':
            printf("1");
            break;
        case 'O':
            printf("0");
            break;
        case 'S':
            printf("5");
            break;
        default:
            printf("%c", toupper(message[i]));
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 9

int i = 0, k = 0;
char message[k],ch;
Run Code Online (Sandbox Code Playgroud)

您已将其定义message可变长度数组(VLA).(这是1990版C中不存在的一个特征;它是1999年标准添加的,并且是2011年标准的可选项.)

由于值k0,长度message0.C不支持零长度数组.定义具有恒定长度零的数组是非法的(违反约束,需要诊断).定义长度为零的可变长度数组具有未定义的行为.

VLA的长度在定义时是固定的.更改以后的值k不会更改数组的长度.你的代码似乎认为它会.

你的程序似乎适用于长达44的长度.这是未定义行为的本质.可能发生的最糟糕的事情是你的程序似乎"正确"工作; 这只意味着你有一个难以察觉的错误.

如果你想在数组中存储任意多个元素,你可以用一个足够大的大小来定义它(可能很难或不可能确定它有多大),或者你可以realloc()用来分配它动态数组并根据需要扩展它.(realloc()实际上并不扩展数组;它创建一个具有更大大小的新数组,并将旧数组的内容复制到新数组中.如果没有足够的可用内存,它可能会失败;总是检查它返回的值确定它是成功还是失败.)