关于#c语言#的问题:请问为什么第一个for循环中int_8t 换成 int 即可成功运行,而使用int_8t会让循环一直进行下去


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#define N 7

int main()
{
   int32_t array[N]={0};
   for(int8_t i=0;i<=N;i++)
   {
       printf("Enter the number:");
       scanf("%d",&array[i]);
       
   }
   for(int8_t i=N;i>=0;i--)
   {
       printf("%d",array[i]);
   }
    return 0;
}

请问为什么第一个for循环中int_8t 换成 int 即可成功运行,而使用int_8t会让循环一直进行下去

先指出你的代码逻辑问题可能引发栈溢出:

for(int8_t i=N;i>=0;i--)
   {
       printf("%d",array[i]);
   }

数组array的长度是N,所以最大索引应该是N-1,所以你这里可以这样来写

for(int8_t i=N-1;i>=0;i--)
   {
       printf("%d",array[i]);
   }

另外你第一个循环不管是int8_t还是int都不会无限循环,因为int8_t累计也不会超过N(7)的

int8_t是指8位有符号整数,它的范围是-128到127。使用int8_t作为i的数据类型,i的值将从0到7进行循环,且进行八次迭代。但数组的大小为N,即7个元素,因此通过使用int8_t作为循环变量的类型,该程序在第八次循环时会尝试访问数组的未定义元素,并导致未定义的行为。

你的程序运行会报错,越界了写会导致不可预知的后果,正确写法如下,不论用什么数据类型运行结果都是一致的:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#define N 7

int main()
{
    int32_t array[N] = { 0 };
    for (int8_t i = 0; i < N; i++)
    {
        printf("Enter the number:");
        scanf("%d", &array[i]);

    }
    for (int8_t i = N-1; i >= 0; i--)
    {
        printf("%d", array[i]);
    }
    system("pause");

    return 0;
}

int8_t是指8位有符号整数,它的范围是-128到127。使用int8_t作为i的数据类型,i的值将从0到7进行循环,且进行八次迭代。但数组的大小为N,即7个元素,因此通过使用int8_t作为循环变量的类型,该程序在第八次循环时会尝试访问数组的未定义元素,并导致未定义的行为。

该回答引用ChatGPT
int8_t是有符号的8位整型,取值范围为-128~127,在for循环中,当i为127时,i++操作就会将i变成-128,由于i的取值范围已经超出了int8_t的取值范围,导致循环一直进行下去。换成int类型,i的取值范围为-2147483648~2147483647,远远大于数组长度N,不会出现这种问题。

因此,修改代码如下,即可正常运行:

c
int array[N]={0};
for(int i=0;i<N;i++)
{
printf("Enter the number:");
scanf("%d",&array[i]);
}

问题出现在第一个 for 循环中的循环条件部分。循环条件 i <= N 是错误的,导致循环一直进行下去。

在 int8_t 的情况下,变量 i 的类型是有符号的8位整数。范围是 -128 到 127。当 i 的值增加到 N=7 时,条件 i <= N 不再成立,因为 i 已经超过了 N 的值。然而,由于 i 是有符号整数,当它增加到最大值 127 后,下一次增加会导致溢出,变为 -128,从而使循环条件仍然成立,循环继续进行下去,造成了无限循环。

将 int8_t 改为 int 后,循环条件 i <= N 中的 i 变量被声明为有符号整数类型,具有足够的位数来容纳 N 的值。因此,循环条件可以正确判断,循环会在 i 的值超过 N 后终止,避免了无限循环的情况。

要解决这个问题,你可以将循环条件修改为 i < N,这样循环将在 i 的值达到 N 时终止,而不是继续执行一次。修改后的代码如下所示:


```bash
int32_t array[N] = {0};
for (int8_t i = 0; i < N; i++)
{
   printf("Enter the number:");
   scanf("%d", &array[i]);
}

for (int8_t i = N - 1; i >= 0; i--)
{
   printf("%d", array[i]);
}

return 0;


```
这样修改后,循环将按预期执行,并正确地打印数组的逆序。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在这个代码中,数组的长度为7,所以数组下标应该在0-6之间。而在第一个for循环中,使用int8_t定义的变量i的取值范围是-128到127,其中-1的补码是0xff,而在运算过程中会转换成unsigned int类型的0xffffffff,也就是一个很大的值,所以当i等于7时,数组会访问一个超出其长度范围的位置,这就是数组越界的问题,会导致程序出现未定义行为。

而如果将int8_t替换为int,则i的取值范围就是-2147483648到2147483647,范围更广,能够包括所有合法的数组下标。因此程序就可以正确地运行了。

修正后代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#define N 7

int main()
{
   int32_t array[N]={0};
   for(int i=0;i<N;i++)
   {
       printf("Enter the number:");
       scanf("%d",&array[i]);
   }
   for(int i=N-1;i>=0;i--)
   {
       printf("%d",array[i]);
   }
    return 0;
}

在第一个循环中,我们使用了0-6的数组下标。在第二个循环中,我们以相反的顺序逆序遍历数组,这里需要注意要以i=N-1为起点,因为数组下标是从0开始计数的。
如果我的回答解决了您的问题,请采纳!