Ceceliaaa 2023-04-08 16:08 采纳率: 66.7%
浏览 25

关于 回文数 和进制数 的问题

我不懂了啊大家,这代码怎么越改越怪呢

img


img

#include<stdio.h>
#include<ctype.h>
#include<string.h>
int ishuiwenshu(char*ch);
int main(void)
{//M[]即是我们读入的数组,第一次输入最大的位数是100,每次加法后最多往前进一位,最多30次,为了防止溢出,就把数组的大小放大了一点 
    char M[135];
    //M[]则用于存储每次加法后得到的新数字字符串 
    char subM[135],ssubM[135];
    int N,i,j,k,n;
    
    scanf("%d",&N);
    scanf("%s",M);
    
    n=strlen(M);
    //输入的数字可能是16进制的,所以输入的可能会有字母,当遍历数组时,其ASCII码大于‘9’的时候,就是字母,为了方便,用tolower()都变成小写 
    if(ishuiwenshu(M))
      printf("STEP=0");
    if(!ishuiwenshu(M))
    {
        for(i=0;i<n;i++)
    {
        if(N==16&&M[i]>'9')
            {
                //处理输入的字母,转换成数字 
                M[i]=tolower(M[i]);
                M[i]=M[i]-'a'+10;
            }
    }
    //开始3最多的0次判断与加法 
    for(k=1;k<=30;k++)
    { 
        //第一次进入该循环时,并不用subM[]数组来处理,但在加法过一次之后,为了要把上一次得到的subM[]的值赋给M[],然后再继续下面的加法 
        if(k>1)
        {   
            n=strlen(subM);
            for(i=0;i<n;i++)
            {
                M[i]=ssubM[i];
                ssubM[i]=0;
                subM[i]=0;//将subM[]同时初始化为0,防止上一次的数值产生误差 
            }
        } 
        
        for(i=0;i<n;i++)
        {    
            //用subM[]来存储得到的新数字字符串 
            subM[i]=M[i]+M[n-1-i];
            ssubM[n-1-i]=subM[i];
        }
        for(j==0;j<n;j++)
        {
            //处理进位问题 
            if(ssubM[j]>=N)
            {    //需要逆位存储,不然反过来会类似于从十位开始往前近 
                ssubM[j]=subM[j]%N;
                ssubM[j]=subM[j]/N;
                
            }
        }
        n=strlen(ssubM);
        for(i=0;i<n;i++)
        {    
            //用subM[]来存储得到的新数字字符串 
            subM[n-1-i]=ssubM[i];
        }
            //在每一次开始加法后,先判断是否是回文数,如果是,跳出循环,然后printf();
            if(ishuiwenshu(subM))
            break;
    
    }
    //因为当k=31时,也会跳出循环,所以需要判断是否是要输出STEP 
    if(k>30)
    printf("Impossible!");
    else
    printf("STEP=%d",k);
    }
    
    return 0;
    
}
//回文数判断的函数 
int ishuiwenshu(char*ch)
{
    int i,j;
    i=0;
    j=strlen(ch);
    for(i=0;i<=(j/2);i++)
    {
        if(ch[i]!=ch[j-1-i])
        return 0;
    }
    return 1;
}

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-04-08 18:17
    关注
    • 你可以看下这个问题的回答https://ask.csdn.net/questions/7582983
    • 你也可以参考下这篇文章:算法与数据结构之带头结点和不带头结点单链表存在的问题
    • 除此之外, 这篇博客: 操作系统之寄存器中的 为了跟上我们汇编大佬的脚步,当然需要了解一些寄存器 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
      • 首当其冲的就是通用寄存器

        • 这类寄存器是执行代码中最常用,也是最最基础的寄存器。
        • 程序在执行过程中,绝大部分时间都是操作这类寄存器来执行指令的,实现指令的功能的
        • 通用寄存器的长度取决于机器的字长
        • 16位cpu通用寄存器共有 8 个:
          • AX:累加器,可用于乘、除、输入/输出以及中间结果的缓存等操作,
          • BX:基址寄存器,用于存储器指针
          • CX:计数器,用于串操作、循环控制的计数器
          • DX
          • BP:基址寄存器/基指针
          • SP:堆栈指针
          • SI:变址寄存器
          • DI:变址寄存器
        • 32位cpu通用寄存器共有 8 个: EAX,EBX,ECX,EDX,EBP,ESP,ESI,EDI功能和上面差不多
          • EAX: 通常用来执行加法,函数调用的返回值一般也放在这里面
          • EBX: 数据存取
          • ECX: 通常用来作为计数器,比如for循环
          • EDX: 读写I/O端口时,EDX用来存放端口号
          • ESP: 栈顶指针,指向栈的顶部
          • EBP: 栈底指针,指向栈的底部,通常用EDP+偏移量的形式来定位函数存放在栈中的局部变量
          • ESI:字符串操作时,用于存放数据源的地址
          • EDI: 字符串操作时,用于存放目的地址的,和ESI两个经常搭配一起使用,执行字符串的复制等操作
      • 然后就是标志寄存器(难哭,都是一些关于计算的问题)

        • “人如其名”,既然名字叫做标志寄存器,当然里面会有众多的标志位,这些标志位记录了CPU执行指令过程中的一系列状态
          在这里插入图片描述

        • 6个状态标志位

          • CF—进位标志,加法时的最高位(第7位或第15位)产生进位或减法时最高位出现借位,则CF=1,否则CF=0;

          • AF—辅助进位标志,供BCD码使用。当(第3位)出现进位或借位时AF=1,否则AF=0;

          • OF—溢出标志,带符号数进行算术运算时,其结果超出了8位或16位的表示范围,产生溢出,则OF=1,否则OF=0;

          • ZF—零标志,运算结果各位都为零,则ZF=1,否则ZF=0;

          • SF—符号标志,运算结果为负数时,即运算结果的最高位为1,则SF=1,否则SF=0;

          • PF—奇偶标志,反映操作结果中“1”的个数的情况,若有偶数个“1”,则PF=1,否则PF=0。

        • 3个控制标志位

          • DF—方向标志,用来控制数据串操作指令的步进方向;当设置DF=1时,将以递减顺序对数据串中的数据进行处理。当设置DF=0时,递增。
          • IF—中断允许标志,当设置IF=1,开中断,CPU可响应可屏蔽中断请求;当设置IF=0时,关中断,CPU不响应可屏蔽中断请求。
          • TF—陷阱标志,为程序调试而设的。当设置TF=1,CPU处于单步执行指令的方式;当设置TF=0时,CPU正常执行程序。
        • (这是别人写的一篇非常好的关于标志寄存器的文章(http://blog.csdn.net/wangkehuai/article/details/7337328) ,很惭愧本人学的不精)

      • 第三个指令寄存器

        • 又是一个“长得像名字一样的”,所以,指令寄存器,就是用于暂存当前正在执行的指令。
        • 根据指令在存贮器中的地址(由指令地址计数器给出),把指令从存贮器中取出来之后,放在专门用于存放指令的地方–指令寄存器,对指令进行分析和执行,同时指令寄存器继续指向下面一条指令,如此不断重复。
      • 第四个段寄存器

        • 16位的寄存器能寻址的范围是64KB,通过引入段的概念,将内存空间划分为不同的区域:分段,通过段基址+段内偏移段方式来寻址。
        • 段寄存器有6个
          • CS: 代码段寄存器。存放当前正在运行的程序代码所在段的段基址,表示当前使用的指令代码可以从该段寄存器指定的存储器段中取得,相应的偏移量则由IP提供。
          • DS: 数据段寄存器。指出当前程序使用的数据所存放段的最低地址,即存放数据段的段基址。
          • SS: 栈段寄存器。指出当前堆栈的底部地址,即存放堆栈段的段基址。
          • ES: 扩展段寄存器。指出当前程序使用附加数据段的段基址,该段是串操作指令中目的串所在的段。
          • FS: 数据段寄存器
          • GS: 数据段寄存器

    以上就是全部要介绍的寄存器了,需要说明一下的是,这并不是x86CPU全部所有的寄存器,除了这些,还存在调试寄存器、描述符寄存器、任务寄存器、模型特定寄存器等。

    评论

报告相同问题?

问题事件

  • 修改了问题 4月8日
  • 修改了问题 4月8日
  • 创建了问题 4月8日

悬赏问题

  • ¥30 不会,学习,有偿解答
  • ¥15 SQL查询语句报错(检查)
  • ¥15 此表中公式应该怎么写
  • ¥15 求HI-TECH PICC 9.50 PL3安装包
  • ¥15 在Windows中运行ollama出现运行缓慢的情况
  • ¥15 下载ctorch报错,求解
  • ¥15 如何将这段css代码应用于wordpress的elementor的单个小部件中显示,而不是整个网站全局显示。
  • ¥15 如何入门学习c语言,单片机
  • ¥15 idea 编辑语言的选择
  • ¥15 Windows下部署Asmjit