《C程序设计语言》-第3章-习题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《C程序设计语言》-第3章-习题相关的知识,希望对你有一定的参考价值。

  由于第3章第一题网上有很多种非常优秀的解法,我就不贴出来了,大家不妨自己探索。

  练习3-2 编写一个函数escape(s,t),将字符串t复制到字符串s中,并在复制过程中将换行符、制表符等不可见字符分别转换成‘\n‘、‘\t‘等相应的可见的转义字符序列。要求使用switch语句。再编写一个具有相反功能的函数,在复制过程将转义字符序列转换成实际字符。

先解释一下两个run函数和两个escape分别实现上述两个功能:

 1 #include <stdio.h>
 2 
 3 void escape(char s[], char t[]);
 4 void escape2(char s[], char t[]);
 5 
 6 void runEscape() {
 7     char testT[100] = "Hello,\ni am a\nGOOD\tBOY\t!!!!\n";
 8     char testS[100] = "Bye,\t littal Max!\n";
 9 
10     printf("T:%sS:%s", testT, testS);
11     escape(testS, testT);
12     printf("Now,");
13     printf("T:%sS:%s", testT, testS);
14 }
15 void runEscape2() {
16     char testS[100] = "Hello,\ni am a\nGOOD\tBOY\t!!!!\n";
17     char testT[100] = "Bye,\t littal Max!\n";
18 
19     printf("T:%sS:%s", testT, testS);
20     escape2(testS, testT);
21     printf("Now,");
22     printf("T:%sS:%s", testT, testS);
23 }
24 void escape(char s[], char t[]) {
25     int i = 0;
26     int j = 0;
27 
28     while (t[i] != \0) {
29         switch (t[i])
30         {
31         case \t:
32             s[j++] = \\;s[j++] = t;
33             break;
34         case \n:
35             s[j++] = \\; s[j++] = n;
36             break;
37         default:
38             s[j++] = t[i];
39             break;
40         }
41 
42         i++;
43     }
44     s[j] = \0;
45 }
46 void escape2(char s[], char t[]) {
47     int i = 0;
48     int j = 0;
49 
50     while (t[i] != \0) {
51         if (t[i]==\\)
52         {
53             switch (t[i+1])
54             {
55             case t:
56                 s[j++] = \t; i++;
57                 break;
58             case n:
59                 s[j++] = \n; i++;
60                 break;
61             default:
62                 s[j++] = t[i];
63                 break;
64             }
65         }
66         else 
67             s[j++] = t[i];
68         i++;
69     }
70     s[j] = \0;
71 }

  练习3-3 编写函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价多的完整列表abc...xyz。该函数可以处理大小写字母和数字,并可以处理a-b-c、a-z0-9与-a-z等类似情况。作为前导和尾随的-字符原样排印。

 1 #include <stdio.h>
 2 
 3 void expand(char s1[], char s2[]);
 4 
 5 void runExpand() {
 6     char testS[100] = "0-9\na-z\nA-Z\na-b-c\na-a\na-Z\n";
 7     char testT[100] = "Bye, littal Tester!\n";
 8 
 9     printf("T:%sS:%s", testT, testS);
10     expand(testS, testT);
11     printf("\nNow,\n");
12     printf("T:%sS:%s", testT, testS);
13 }
14 
15 
16 void expand(char s1[], char s2[]) {
17     int i = 0;
18     int j = 0;
19 
20     while (s1[i] != \0) {
21         if (s1[i] == -&&s1[i + 1] != \0 && i > 0) {
22             char head = s1[i - 1];
23             char tail = s1[i + 1];
24 
25             if (a <= head&&head <= z&&head < tail
26                 &&a <= tail&&tail <= z) {
27                 for (; head + 1 <= tail;) {
28                     s2[j++] = head + 1;
29                     head++;
30                 }
31             }
32             else if (A <= head&&head <= Z&&head < tail
33                 &&A <= tail&&tail <= Z) {
34                 for (; head + 1 < tail;) {
35                     s2[j++] = head + 1;
36                     head++;
37                 }
38             }
39             else if (0 <= head&&head <= 9&&head < tail
40                 &&0 <= tail&&tail <= 9) {
41                 for (; head + 1 < tail;) {
42                     s2[j++] = head + 1;
43                     head++;
44                 }
45             }
46             else
47                 s2[j++] = -;
48         }
49         else
50             s2[j++] = s1[i];
51         
52         i++;
53     }
54 }

  练习3-4 在数的对二补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-2字长-1的情况。请解释原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。

解释的原因我写在注释代码里面了~~

#include <stdio.h>

void reverse(char s[]);
void itoa(int n, char s[]);

void runItoa() {
    int testn = -1987654321;
    char test[100];

    itoa(testn, test);
    printf("test:%s", test);
}
/*不能正确处理最大负数的原因在于其二进制数形式为10000...如果
对其进行n=-n运算,n将变成0,这显然是不符合我们期望的。因此我
们可以进行检测,如果它是这个特殊的最大负数则将其变为无符号数。*/
    
void itoa(int n, char s[]) {
    int i, sign;
    sign = n;

    if (((unsigned)sign << 1) == 0)
        n = (unsigned)n;
    else if (sign < 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 = 0;
    int j = 0;
    char c[1000];

    while (s[i] != \0) 
        c[i] = s[i++];
    while (i > 0)
        s[j++] = c[--i];
    s[j] = \0;
}

  练习3-5 编写函数itob(n,s,b)将整数n转换为以b为底的数。 并将转换结果以字符的形式保存到字符串s中。

#include <stdio.h>


void reverse(char s[]);
void itob(int n, char s[], int);

void runItob() {
    int testn = 1987654321;
    char test[100];

    itob(testn, test, 10);
    printf("test:%s", test);
}

void itob(int n, char s[], int b) {
    int i = 0;

    do {
        s[i++] = n % b + 0;
    } while ((n /= b) > 0);
    s[i] = \0;

    reverse(s);
}

练习3-6  修改itoa函数,使得该函数可以接收三个参数。第三个参数为最小字段宽度。为了保证转换后结果至少具有第三个参数指定的最小宽度,必要时在结果左边填充一定的空格。

 1 #include <stdio.h>
 2 
 3 void reverse(char s[]);
 4 void itoa2(int n, char s[], int width);
 5 
 6 void runItoa2() {
 7     int testn = -1987654321;
 8     char test[100];
 9 
10     itoa2(testn, test,20);
11     printf("test:%send\n", test);
12 }
13 
14 void itoa2(int n, char s[], int width) {
15     int i, sign;
16     sign = n;
17 
18     if (((unsigned)sign << 1) == 0)
19         n = (unsigned)n;
20     else if (sign < 0)
21         n = -n;
22     i = 0;
23     do {
24         s[i++] = n % 10 + 0;
25     } while ((n /= 10) > 0);
26     if (sign < 0)
27         s[i++] = -;
28     while (width - i > 0) {
29         s[i++] =  ;
30     }
31     s[i] = \0;
32     reverse(s);
33 }

 

以上是关于《C程序设计语言》-第3章-习题的主要内容,如果未能解决你的问题,请参考以下文章

Java语言程序设计(第3版)沈泽刚主编第10,11,12章课后习题答案

Java语言程序设计(第3版)沈泽刚主编第4章课后习题答案

Java语言程序设计(第3版)沈泽刚主编第6,7,8章课后习题答案

C Primer plus 第一章复习题及其编程题

谭浩强版C语言程序设计(第三版)课后习题完整答案附源码--高等教育出版社

谭浩强版C语言程序设计(第三版)课后习题完整答案附源码--高等教育出版社