请问怎么理解这串代码呢,希望能帮我逐行做一个注释

#include <stdio.h>

int main()
{
signed char i = 0;

    while (i <= 0)
    {
            printf("%d", i);
            i = i - 1;
    }

    return 0;

}

#include <stdio.h>

int main()
{
    signed char i = 0;    // 定义类型为signed char的局部变量i并初始化为0
    while (i <= 0) {      // 把i的值整型提升为int,然后再与0比较,如果小于等于0,继续循环,否则退出循环
        printf("%d", i);  // 把i的值整型提升为int,再传入printf函数 
        i = i - 1;        // 把i的值整型提升为int,然后减1,最后把结果转换为signed char类型赋值给i
                          // 当i-1的结果是-129时,这个值已经超出signed char类型可表示的值范围[-128, 127],
                          // C/C++标准规定对于有符号类型,这种情况其行为是implementation defined。
                          // 大多数编译器对这种情况是按截断处理来实现的,截取-129的低8位得到的结果是127,因此i的值变成127,然后再与0比较时退出循环
                          // https://en.cppreference.com/w/c/language/conversion#Integer_conversions
    }
    return 0;
}

// 下面是clang编译器生成的汇编码
/*

main:                                   # @main
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     dword ptr [rbp - 4], 0
        mov     byte ptr [rbp - 5], 0        # rbp-5是局部变量i的地址,这里是初始化i为0
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
        movsx   eax, byte ptr [rbp - 5]      # movsx指令是按符号扩展拷贝,这里是整型提升i的值为int类型
        cmp     eax, 0                       # 与0比较
        jg      .LBB0_3                      # 如果大于0,跳出循环
        movsx   esi, byte ptr [rbp - 5]      # 整型提升i的值为int类型,拷贝至esi寄存器,即printf的第二个参数
        movabs  rdi, offset .L.str           # 把输出格式字符串地址拷贝至rdi,即printf的第一个参数
        mov     al, 0                        # 返回值清零
        call    printf                       # 调用printf函数输出i的值
        movsx   eax, byte ptr [rbp - 5]      # 整型提升i的值为int类型
        sub     eax, 1                       # 整型提升的值减1
        mov     byte ptr [rbp - 5], al       # 将计算结果转换为char类型赋给i
        jmp     .LBB0_1
.LBB0_3:
        xor     eax, eax
        add     rsp, 16
        pop     rbp
        ret
.L.str:
        .asciz  "%d"

*/

参考
https://en.cppreference.com/w/c/language/conversion#Usual_arithmetic_conversions
https://en.cppreference.com/w/c/language/operator_arithmetic

就是i从0开始一直减1,直到i 的值小于signed char类型的范围, 数值溢出变成正数就结束循环了.
signed char 类型取值范围是 -128 到 127, 当 i 的值是 -128 时再减1就数值溢出变成 127了,而不是 -129.
127不满足 while (i <= 0)循环条件,就结束循环了

#include <stdio.h>
int main()
{
    signed char i = 0; //定义i为signed char 类型取值范围是 -128 到 127,  i 的初始值为0

    while (i <= 0)  //如果i<=0则继续循环
    {
        printf("%d ", i); //输出当前i的值
        i = i - 1;   //i的值减1, 当 i 的值是 -128 时再减1就数值溢出变成 127了,而不是 -129
    }
    printf("\n结束循环后 i 的值是%d", i);
    return 0;
}

img

如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!

img

首先是头文件,里面包含循环语句的使用,然后是运行主函数main,接下来调用main函数内容。定义有符号字符i。char类型占用一个字节大小,一个字节为8B,即可储存2^8个数据。有正负之分,即-128*127,(unsigned 为无符号,单位0~255),while为循环语句的标识符。形式为while(条件){},条件成立,返回结果为1,运行{}里的内容。条件不成立,退出while循环,继续运行。当i为-128(二进制语言 1111 1111,第一位为1,表示负数,为0表示正数。)时,再减1,数值溢出。结果为127(二进制语言 0111 1111)。
转换方式:1111 1111(-128)-1,不计算第一位数字,即当成绝对值看待。为111 1111+1,结果为000 0000,再取相反数,即1000 0000的相反数0111 1111(127)。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632