C程序设计语言第二版习题3-4

简介: 在数的反码表示中,上述的 itoa 函数不能处理最大的负数,即 n 等于-2^(字长-1) 的情况。请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。

问题描述

在数的反码表示中,上述的 itoa 函数不能处理最大的负数,即 n 等于-2^(字长-1) 的情况。请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。

问题分解

  • 主函数main
  • 核心函数 itoa(n, s)。先来看原文的函数实现:
void itoa(int n, char s[])
{
        int i, sign;
        if((sign = n) < 0){
                n = -n;
        }
        i = 0;
        do{
                s[i++] = n % 10 + '0';
        }while((n /= 10) > 0);
​
        if(sign < 0){
                s[i++] = '-';
        }
        s[i] = '\0';
        reverse(s);
}

先来分析itoa函数为什么不能处理最大的负数,我们假设在int数据取值范围位-128 ~ 127 的机器上,当n = -128时,-n = 128 > 127,此时灾难发生了——得到的结果并不是我们想要的字符串。因此,问题处在 if((sign = n) < 0) 这句,那么我们只要将其改造一下即可。

代码实现

#include<stdio.h>
​
void itoa(int n, char s[]);
void itoa2(int n, char s[]);
void reverse(char s[]);
​
int main()
{
        int n = (~0U >> 1) + 1;
        char s[100], s1[100], s2[100];
        printf("The input number is: %d\n", n);
        itoa(n, s);
        printf("The output string of itoa is: %s\n", s);
​
        itoa2(n, s1);
        printf("The output string of itoa2 is: %s\n", s1);
        return 0;
}
​
void itoa2(int n, char s[])
{
    int sign, i;
    sign = n;
    i = 0;
    do {
        s[i++] = ((sign < 0) ?-(n % 10) : n % 10) + '0'; //负数对10求余仍然是负数
    } while ((n /= 10) != 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}
​
void itoa(int n, char s[])
{
        int i, sign;
        if((sign = n) < 0){
                n = -n;
        }
        i = 0;
        do{
                s[i++] = n % 10 + '0';
        }while((n /= 10) > 0);
​
        if(sign < 0){
                s[i++] = '-';
        }
        s[i] = '\0';
        reverse(s);
}
void reverse(char s[])
{
    int i, j, c;
    for (j = 0; s[j] != '\0'; j++)
        ;
    for (i = 0, j--; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

编译运行

image

由运行结果可看出,原方法得到的结果不是预期的,改造后的得到了正确的结果。

目录
相关文章
|
6月前
|
程序员 编译器 C语言
【C语言程序设计】编写简单的C程序
【C语言程序设计】编写简单的C程序
132 0
|
存储 自然语言处理 算法
C语言总结(第2章算法——程序的灵魂 第3章最简单的C程序设计——顺序程序设计 第4章选择结构程序设计)
算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 6是解决做什么和怎么做的问题。简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵魂。
1079 0
|
C语言
明解C语言第七章习题
明解C语言第七章习题
|
数据安全/隐私保护 C语言
C语言第四章 分支结构程序设计习题2【修改版,看水印】
C语言第四章 分支结构程序设计习题2【修改版,看水印】
159 0
C语言第四章 分支结构程序设计习题2【修改版,看水印】
|
算法
C程序设计语言第二版习题2-9
在求反码时,表达式 x &= (x - 1) 用于把x最右边的值为1的位删除掉。请解释一下这样做的道理。用这一方法重写bitcount函数 ,使之执行得更快一点
828 0
C程序设计语言第二版习题4-1
编写一个函数strrindex(s, t),用于返回字符串t在s中最右出现的位置,如果 s中不 包含t,那么返回-1。
3684 0
|
机器学习/深度学习 算法 JavaScript
C程序设计语言第二版习题3-6
修改itoa函数,使得该函数可以接收三个参数。其中,第三个参数为最小字段宽度。为了保证转换后所得的结果至少具有第三个参数指定的最小宽度,在必要时应在所得结果的左边填充一定的空格。
756 0
|
机器学习/深度学习 算法 JavaScript
C程序设计语言第二版习题3-5
编写函数itob(n, s, b) ,用于把整数n转换成以b为基数的字符串并存到字符串s中。例如, itob(n, s, 16) 表示将n转换成16进制数,并存入s中。
971 0
|
算法 JavaScript
C程序设计语言第二版习题3-3
编写函数expand(s1, s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价的完整列表abc...xyz。该函数可以处理大小写字母和数字,并可以处理a-b-c、a-z0-9与-a-z等类似的情况。作为前导和尾随的-字符原样打印。
4380 0
|
移动开发 算法
C程序设计语言第二版习题2-8
问题描述编写一个函数rightrot(x, n),该函数返回将x循环右移n位所得到的值。
912 0