首页 > 解决方案 > 为什么我不能用 i = -1 初始化循环?

问题描述

当我偶然发现这个我不明白的东西时,我正在学习循环。

在这段代码中,如果我进入 for 循环,i = 0它会按预期工作,如果我写“狗”,我会得到 3 个 a,但如果我写i = -1,我根本不会得到输入,不应该给我额外的?

我不能在i任何我想要的地方开始价值吗?

#include <string.h>

int main (int argc, char **argv) {
        char string[10];

        scanf("%s", string);

        void changestring (char *newstring) {
                for (int i=0; i < strlen(newstring); i++) {
                        printf("a");
                }
        }
        changestring(string);
}

标签: c

解决方案


首先,为了消除一些混乱,让我们稍微重写一下您的代码(因为对于外行来说,这里发生的事情很少,可能看起来相似,但实际上并非如此)。

#include <string.h>

void print_as_according_to_strlen(char *n) {
    for (int i=0; i < strlen(newstring); i++) {
        printf("a");
    }
}

在那里,这是相关的部分。如果你看一下strlen你会看到的定义,它返回一个类型的值size_t

size_t strlen(const char *s);

返回字符串 s 的长度。

size_t无符号类型。C 和 C++ 具有某些规则,当在操作中一起使用时,整数值被隐式转换为“通用”类型。这些就是所谓的“整数提升规则” ——知道这些很重要,你绝对必须学习它们。

这些规则之一是,如果您使有符号整数与无符号整数“交互” ,则提升的类型也将是无符号的。当然,如果您尝试将负值提升为无符号类型,结果会有所不同。

现在有了 C,事情在这里变得很棘手,因为有一些(实际上是大多数情况)试图这样做会调用未定义的行为,即任何事情都可能发生。然而,有一些例外情况,它实际上表现良好(例如,如果您有两个无符号变量unsigned a = 3,并且unsigned b = 5操作的结果a-b实际上是一个定义明确的值,因为无符号溢出是明确定义的,结果是UINT_MAX - (b-a))。

您的底线是:您必须重写代码,以便比较升级为有符号比较,或者不是从开始,而是-1转到strlen(…)+1int我建议您不要使用 a ,ptrdiff_t而是使用 a ,因为 int 的大小可能足以或可能不足以容纳strlen. 并且碰巧(不是 C,而是现代操作系统如何管理内存)strlen永远不会返回可能溢出的值ptrdiff_t

ptrdiff_t len = strlen(newstring);
for(ptrdiff_t i=-1; i < len ; i++){

推荐阅读