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日

悬赏问题

  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 51单片机中C语言怎么做到下面类似的功能的函数(相关搜索:c语言)
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起