m0_66394588 2022-02-05 01:14 采纳率: 91.5%
浏览 52
已结题

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

#include <stdio.h>

int main()
{
signed char i = 0;

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

    return 0;

}

  • 写回答

4条回答 默认 最新

  • _GX_ 2022-02-05 08:17
    关注
    #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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月14日
  • 已采纳回答 2月6日
  • 修改了问题 2月5日
  • 创建了问题 2月5日

悬赏问题

  • ¥30 自适应 LMS 算法实现 FIR 最佳维纳滤波器matlab方案
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥15 Python3.5 相关代码写作
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像