C程序设计语言(第二版)课后习题答案 1-3 章
星海
posted @ 2010年12月29日 21:07
in C代码
, 5687 阅读
K&R C 课后题答案,有不完善的地方还请诸位大虾多多指评!
/* * ========================================================================== * * Filename: 1-6-7.c * * Description: 验证表达式getchar()!=EOF 的值是0还是1 * 编写一个打印EOF值的程序 * * Version: 1.0 * Created: 2010年12月29日 13时07分03秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int main(void) { printf("%d\n", getchar() != EOF); printf("%d\n", EOF); return 0; }
/* * ========================================================================== * * Filename: 1-8.c * * Description: 编写一个统计空格、制表符与换行符个数的程序 * * Version: 1.0 * Created: 2010年12月29日 13时12分21秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int main(void) { int c; int snum, tnum, nnum; snum = tnum = nnum = 0; while ((c = getchar()) != EOF) { if (c == ' ') ++snum; if (c == '\t') ++tnum; if (c == '\n') ++nnum; } printf ("您所输入的字符串中\n 共有空格 %d 个,制表符 %d 个, 换行符 %d 个\n ", snum, tnum, nnum); return 0; }
/* * ========================================================================== * * Filename: 1-9.c * * Description: 将输入复制到输出,并将其中连续的多个空格用一个空格代替 * * Version: 1.0 * Created: 2010年12月29日 13时20分54秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int main(void) { int flags = 1; int c; while ((c = getchar()) != EOF) { if (c == ' ') { if (flags == 1) putchar(' '); flags = 0; } else { putchar(c); flags = 1; } } return 0; }
/* * ========================================================================== * * Filename: 1-10.c * * Description: 制表符替换为\t,回退符替换为\b,反斜杠替换为\\ * * Version: 1.0 * Created: 2010年12月29日 13时33分13秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #define ESC_CHAR '\\' int main(void) { int c; while ((c = getchar()) != EOF) { switch (c) { case '\b': putchar(ESC_CHAR); putchar('b'); break; case '\t': putchar(ESC_CHAR); putchar('t'); break; case ESC_CHAR: putchar(ESC_CHAR); putchar(ESC_CHAR); break; default: putchar(c); break; } } return 0; }
1-11不懂
/* * ========================================================================== * * Filename: 1-12.c * * Description: 编写一个程序,以每行一个单词的形式打印其输入 * * Version: 1.0 * Created: 2010年12月29日 13时44分29秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int main(void) { int c; int flags = 1; while ((c = getchar()) != EOF) { if (c == ' ' || c == '\n' || c == '\t') { if (flags) putchar('\n'); flags = 0; } else { putchar(c); flags = 1; } } return 0; }
/* * ========================================================================== * * Filename: 1-13.c * * Description: 编写一个程序,打印输入中单词长度的直方图 * * Version: 1.0 * Created: 2010年12月31日 21时28分46秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int isspace2(int c) { if (c == ' ' || c == '\n' || c == '\t') return 1; else return 0; } int main(void) { int c; while ((c = getchar()) != EOF) if (!isspace2(c)) putchar('*'); else putchar('\n'); return 0; }
/* * ========================================================================== * * Filename: 1-13.c * * Description: 编写一个程序,打印输入中单词长度的直方图(垂直直方图) * * Version: 1.0 * Created: 2010年12月31日 21时28分46秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #include <ctype.h> #define MAXWORDS 20 //单词最大数量 int main(void) { int c, j, maxlen = 0, i = 0, n = 0; //maxlen为最长长度, i为数组长度,n为单个单词长度 int a[MAXWORDS]; while ((c = getchar()) != EOF) if (!isspace(c)) ++n; else { if (maxlen < n) maxlen = n; a[i++] = n; n = 0; } while (maxlen--) { for (j = 0; j < i; ++j) if ((a[j])-- > 0) putchar('*'); else putchar(' '); putchar('\n'); } return 0; }
/* * ========================================================================== * * Filename: 1-14.c * * Description: 打印输入中各个字符出现频度的直方图 * * Version: 1.0 * Created: 2010年12月31日 23时42分44秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int main(void) { int c, i = 0; int a[95]; //除去不可显示字符1-31,127 for (i = 0; i < 95; ++i) a[i] = 0; while ((c = getchar()) != EOF) if ((c = getchar()) > 31 && (c = getchar()) < 127) ++a[c - 32]; for (i = 0; i < 95; ++i) { printf("%-5c", i + 32); while (a[i] > 0) { putchar('*'); --a[i]; } printf("\n"); } return 0; }
#include <stdio.h> #define MAXLINE 1000 //允许的输入行的最大长度 int main(void) { int c, i, j = 0, sptabnum = 0, tabnum = 0; //sptabnum记录空格或Tab数目,tabnum记录空格数目 char line[MAXLINE]; for (i = 0; i < MAXLINE && (c = getchar()) != EOF; ++i) { line[j++] = c; if (c == '\n') { j = j - sptabnum - 1; line[j] = '\0'; //删除每个输入行末尾的空格及制表符 if ((j + tabnum) > 0) //如果输入行不完全是空格或者非空 printf("%s\n", line); j = sptabnum = tabnum = 0; } else if (c == '\t') { ++tabnum; ++sptabnum; } else if (c == ' ') ++sptabnum; else { sptabnum = 0; tabnum = 0; } } /*如果输入字符为EOF,显示之前输入的行内容 */ if (c == EOF) { line[j] = '\0'; printf("\n%s", line); } return 0; }
/* * ========================================================================== * * Filename: 1-19.c * * Description: reverse(s) * * Version: 1.0 * Created: 2011年01月01日 13时08分11秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> void reverse(char s[]) { int j, temp, i; i = j = 0; while (s[i++]) ; //结果i为字符串S长度,包括\0 i = i - 2; //此时i为字符串s中最后一个字符下标 while (j < i) { temp = s[j]; s[j++] = s[i]; s[i--] = temp; } } int main(void) { char s[] = "wo ai ni,lao po"; reverse(s); printf("%s\n", s); return 0; }
/* * ========================================================================== * * Filename: 1-20.c * * Description: * 将输入中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止位的地方。 * * Version: 1.0 * Created: 2011年01月01日 16时52分57秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> void detab(void) { int tabnum = 0, c; while ((c = getchar()) != EOF) { if (c == '\t') { ++tabnum; printf(" "); //tabsize为8个字符 } else if (tabnum == 0) putchar(c); else if (tabnum > 0) putchar(' '); if (tabnum == 2) tabnum = 0; } } int main(void) { detab(); return 0; }
/* * ========================================================================== * * Filename: 1-21.c * * Description: 编写程序entab, * 将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变。 * * Version: 1.0 * Created: 2011年01月01日 22时03分56秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #include <string.h> #define TABSIZE 4 void entab(char s[]) { int i, j, k = 0, spnum = 0; for (i = 0; i < strlen(s); ++i, ++k) if (s[i] == ' ') ++spnum; else { k -= spnum; for (j = spnum / TABSIZE; j > 0; --j) { s[k++] = '\t'; } for (j = spnum % TABSIZE; j > 0; --j) { s[k++] = ' '; } s[k] = s[i]; spnum = 0; } s[k] = '\0'; } int main(void) { char a[] = "wo ai ni"; printf("%d\n", strlen(a)); entab(a); printf("%s\n", a); printf("%d\n", strlen(a)); return 0; }
未完成
未完成
未完成
/* * ========================================================================== * * Filename: 2-3.c * * Description: * 编写函数htoi(s),把十六进制数字组成的字符串(包括可选的前缀0X或0x)转换为与之等价的整形值。 * * Version: 1.0 * Created: 2011年01月01日 22时23分58秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int htoi(char hexstr[]) { int i = 0, tmp, result = 0, hexg = 0; if (hexstr[i] == '0' && (hexstr[i + 1] == 'x' || hexstr[i + 1] == 'X')) i = 2; while (hexstr[i]) { tmp = hexstr[i]; if (tmp >= '0' && tmp <= '9') hexg = tmp - '0'; else if (tmp >= 'a' && tmp <= 'f') hexg = tmp - 'a' + 10; else if (tmp >= 'A' && tmp <= 'F') hexg = tmp - 'A' + 10; else { printf("Your input is error\n"); result = 0; break; } result = result * 16 + hexg; i++; } return result; } int main(void) { char a[] = "0xF56"; printf("%d\n", htoi(a)); return 0; }
/* * ========================================================================== * * Filename: 2-4.c * * Description: * 编写函数squeeze(s1,s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除 * * Version: 1.0 * Created: 2011年01月02日 10时01分49秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> void squeeze(char s1[], char s2[]) { int i, j, k, eqnum = 0; for (i = k = 0; s1[i] != '\0'; i++) { for (j = 0; s2[j] != '\0'; j++) if (s1[i] == s2[j]) ++eqnum; if (eqnum == 0) s1[k++] = s1[i]; eqnum = 0; } s1[k] = '\0'; } int main(void) { char a[] = "sunbin"; char b[] = "hankangli"; squeeze(a, b); printf("%s\n", a); return 0; }
/* * ========================================================================== * * Filename: 2-5.c * * Description: 编写函数any(s1,s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1 * * Version: 1.0 * Created: 2011年01月02日 10时14分54秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #include <string.h> int any(char s1[], char s2[]) { int i, j; for (i = 0; s1[i] != '\0'; ++i) for (j = 0; s2[j] != '\0'; ++j) { if (s1[i] == s2[j]) return j; } return -1; } int main(void) { char a[] = "shit"; char b[] = "fucking"; printf("%d\n", any(a, b)); printf("%c\n", *strpbrk(a, b)); return 0; }
/* * ========================================================================== * * Filename: 2-6.c * * Description: 编写一个函数setbits(x,p,n,y),该函数返回对x执行下列操作后 * 的结果值:将x从第p位开始的n个二进制位设置为y中最右边n * 位的值,x的其余各位保持不变 * Version: 1.0 * Created: 2011年01月02日 10时45分20秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int setbits(int x, int p, int n, int y) { return (x >> (p - n + 1) & ~(~0 << n)) | (y >> n << n); } int main(void) { int a = 89; int b = 89; printf("%d\n", setbits(a, 4, 3, b)); return 0; }
/* * ========================================================================== * * Filename: 2-7.c * * Description: 编写一个函数invert(x,p,n),该函数返回对x执行下列操作后的 * 结果值:将x中从第p位开始的n个二进制位求反,x的其余各位保持不变 * * Version: 1.0 * Created: 2011年01月02日 11时08分11秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int invert(unsigned int x, int p, int n) { return x ^ ((~0 >> (p + 1 - n)) & ~(~0 << n) << (p + 1 - n)); } int main(void) { printf("%d", invert(156, 4, 3)); return 0; }
/* * ========================================================================== * * Filename: 2-8.c * * Description: * 编写一个函数rightrot(x,n),该函数返回将x循环右移(即从最右端移出的位将从最左端移入)n位后所得到的值 * * Version: 1.0 * Created: 2011年01月02日 14时40分38秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #include <limits.h> int rightrot(unsigned int x, int n) { int y; //y为x所移出N位的值 y = x & ~(~0 << n); return x >> n | (y << (sizeof(x) * CHAR_MAX - n)); } int main(void) { printf("%d\n", rightrot(51, 2)); return 0; }
/* * ========================================================================== * * Filename: 2-9.c * * Description: 重写bitcount函数 * * Version: 1.0 * Created: 2011年01月02日 17时59分43秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> int bitcount(unsigned x) { int b; for (b = 0; x != 0; x &= (x - 1)) b++; return b; } int main(void) { printf("%d\n", bitcount(50)); return 0; }
int binsearch2(int x, int v[], int n) { int low, high, mid; low = 0; high = n - 1; mid = (low + high) / 2; while (low <= high && x != v[mid]) { if (x < v[mid]) high = mid - 1; else low = mid + 1; mid = (low + high) / 2; } if (x == v[mid]) return mid; else return -1; }
/* * ========================================================================== * * Filename: 3-2.c * * Description: 编写一个函数escape(s,t), * 将字符串t复制到字符串s中,并在复制过程中将换行符、指标符等不可见字符分别转换为\n、\t等相应的可见的转移字符序列 * * Version: 1.0 * Created: 2011年01月02日 18时51分17秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #include <string.h> void escape(char s[], char t[]) { int i = 0, j = 0; while (t[i] != EOF) { switch (t[i]) { case '\n': s[j++] = '\\'; s[j++] = 'n'; break; case '\t': s[j++] = '\\'; s[j++] = 't'; break; default: s[j++] = t[i]; break; } ++i; } s[j] = EOF; } int main(void) { char s[50]; char t[20] = "wo ai \n\n haha"; escape(s, t); printf("%s\n", s); return 0; }
/* * ========================================================================== * * Filename: 3-2.c * * Description: 编写一个函数escape(s,t), * 将字符串t复制到字符串s中,并在复制过程中将换行符、指标符等不可见字符分别转换为\n、\t等相应的可见的转移字符序列 * * Version: 1.0 * Created: 2011年01月02日 18时51分17秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> void escape2(char s[], char t[]) { int i = 0, j = 0, k = 0; while (t[i] != EOF) { switch (t[i]) { case '\\': ++k; break; case 't': if (k == 1) s[j++] = '\t'; k = 0; break; case 'n': if (k == 1) s[j++] = '\n'; k = 0; break; default: for (; k > 0; --k) s[j++] = '\\'; s[j++] = t[i]; k = 0; break; } ++i; } s[j] = EOF; } int main(void) { char s[50]; char t[30] = "lao \\t po\\n \\t \\t ha \\n haha"; escape2(s, t); printf("%s\n", s); return 0; }
/* * ========================================================================== * * Filename: 3-3.c * * Description: * 编写函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价的完整列表abc..xyz.该函数可以处理大小写字符和数字,并可以处理a-b-c,a-z,0-9与a-z等类似的情况。作为前导和未遂的-字符原样排印。 * * Version: 1.0 * Created: 2011年01月02日 20时52分01秒 * Revision: none * Compiler: gcc * * Author: SD44 (), sd44sd44@yeah.net * Company: http://sd44.is-programmer.com/ * * ========================================================================== */ #include <stdio.h> #include <ctype.h> void expand(char s1[], char s2[]) { int i, j, k, stag; i = j = 0; for (i = 0; s1[i] != '\0'; i++) { if (s1[i] == '-' && islower(s1[i - 1]) && islower(s1[i + 1]) && ((s1[i + 1] - s1[i - 1]) > 0)) { stag = s1[i - 1]; k = s1[i + 1] - s1[i - 1] - 1; while (k--) s2[j++] = ++stag; } else if (s1[i] == '-' && isupper(s1[i - 1]) && isupper(s1[i + 1]) && ((s1[i + 1] - s1[i - 1]) > 0)) { stag = s1[i - 1]; k = s1[i + 1] - s1[i - 1] - 1; while (k--) s2[j++] = ++stag; } else if (s1[i] == '-' && isdigit(s1[i - 1]) && isdigit(s1[i + 1]) && ((s1[i + 1] - s1[i - 1]) > 0)) { stag = s1[i - 1]; k = s1[i + 1] - s1[i - 1] - 1; while (k--) s2[j++] = ++stag; } else s2[j++] = s1[i]; } s2[j] = '\0'; } int main(void) { char a[] = "h-a-hazz 3-9-5 3-A- "; char b[100]; expand(a, b); printf("%s\n", b); return 0; }
/* * ===================================================================================== * * Filename: 3-4.c * * Description: * 修改itoa函数,使其能够处理最大的负数,即n等于-2(n-1次方)的情况 * * Version: 1.0 * Created: 2011年01月08日 15时30分35秒 * Revision: none * Compiler: gcc * * Author: Sd44 (), sd44sd44@yeah.net * Homepage: http://sd44.is-programmer.com * * ===================================================================================== */ #include <stdio.h> #include <stdlib.h> #include <string.h> void reverse(char a[]) { int c, i, j; for (i = 0, j = strlen(a) - 1; i < j; i++, j--) { c = a[i]; a[i] = a[j]; a[j] = c; } } void itoa(int n, char s[]) { int i, sign; sign = n; i = 0; do { s[i++] = abs(n % 10) + '0'; } while (n /= 10); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } int main(void) { char b[50]; itoa(-2147483647, b); printf("%s\n", b); return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> void reverse(char a[]) { int c, i, j; for (i = 0, j = strlen(a) - 1; i < j; i++, j--) { c = a[i]; a[i] = a[j]; a[j] = c; } } void itoa(int n, char s[]) { int i, sign; sign = n; i = 0; do { s[i++] = abs(n % 10) + '0'; } while (n /= 10); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } int main(void) { char b[50]; itoa(-2147483647, b); printf("%s\n", b); return 0; }
/* * ===================================================================================== * * Filename: 3-6.c * * Description: * itoa函数,使得该函数可以接收三个参数,其中,第三个参数为最小字段宽度。 * * Version: 1.0 * Created: 2011年01月08日 15时55分08秒 * Revision: none * Compiler: gcc * * Author: Sd44 (), sd44sd44@yeah.net * Homepage: http://sd44.is-programmer.com * * ===================================================================================== */ #include <stdio.h> #include <string.h> void reverse(char a[]) { int c, i, j; for (i = 0, j = strlen(a) - 1; i < j; i++, j--) { c = a[i]; a[i] = a[j]; a[j] = c; } } void itoa(int n, char s[], int width) { int i, sign, temp = n, widnum = 0; if ((sign = n) < 0) n = -n; i = 0; do { s[i++] = n % 10 + '0'; ++widnum; // widnum为整数n的位数 } while (n /= 10); if (sign < 0) { s[i++] = '-'; // 如果n为负数,则宽度+1 ++widnum; } for (temp = width - widnum; temp > 0; --temp) s[i++] = ' '; s[i] = '\0'; reverse(s); } int main(void) { char b[50]; itoa(-100, b, 8); printf("%s\n", b); return 0; }