《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 < tail26                 &&'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 < tail33                 &&'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 < tail40                 &&'0' <= tail&&tail <= '9') {41                 for (; head + 1 < tail;) {42                     s2[j++] = head + 1;43                     head++;44                 }45             }46             else47                 s2[j++] = '-';48         }49         else50             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章-习题

相关文章:

你感兴趣的文章:

标签云: