C程序设计语言(第二版)课后习题答案 1-3 章
星海
posted @ 2010年12月29日 21:07
in C代码
, 5728 阅读
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;
}
评论 (0)