----2013-01-19----
习题4-7
编写一个函数ungets(s),将整个字符串s压回到输入中。ungets函数需要使用buf和bufp吗?它能否仅使用ungetch函数?
代码如下:
void ungets(char s[])
{
int i;
void ungetch(int);
for (i = 0; i < strlen(s) && s[i] != '\0'; i++)
ungetch(s[i]);
}
ungets函数调用ungetch来处理对buf和bufp的操作,但是但是难道上面的代码木有问题吗???getch返回的是最后一个字符。要想让字符串s正确打印,需要经字符串s逆序存到buf中。代码更改如下:( 要是没瞅到答案,真的考虑不到这些,囧囧)
void ungets(char s[])
{
int i;
void ungetch(int);
for (i = strlen(s) - 1; i >= 0 && s[i] != '\0'; i--)
ungetch(s[i]);
}
习题4-8
假定最多只压回一个字符。请相应地修改getch与ungetch这两个版本。
代码如下:
char buf = 0;
int getch(void)
{
int c;
if (buf != 0) { /* buf不为空,则返回buf存储的字符 */
c = buf;
buf = 0;
return c;
}
else /* buf为空,从输入读入一个字符 */
return getchar();
}
void ungetch(int c)
{
if (buf != 0)
printf("error: buf is not empty!\n");
else
buf = c;
}
习题4-12(递归版本的itoa函数)
教训:递归一直没有理解的特别明白,编写的时候卡壳,课本上74页递归形式的快排一直木有明白。
特别是这里
swap(v, left, (left + right)/2);
last = left;
for (i = left + 1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i); //尤其是++last,很让人费解。
swap(v, left, last);
习题4-12的代码如下:
#include <stdio.h>
void itoa(int n, char []);
int main()
{
int x = 1343523, j;
char s[8];
itoa(x, s);
for (j = 0; j < 7; j++)
printf("%c ", s[j]);
printf("\n");
return 0;
}
int i = 0;
void itoa(int n, char s[])
{
int sign;
if ((sign = n) < 0)
n = -n;
if (sign < 0)
s[i++] = '-'; /* 刚才忘考虑'-' */
if ((n / 10) > 0)
itoa(n / 10, s);
s[i++] = n % 10 + '0';
s[i] = '/0'; /* 刚才没有考虑空字符 */
}
练习4-13(教材75页)
递归版本reverse(s)函数。自己实现的版本一是这样的:
void reverse(char s[])
{
static int i, j; /* 串内循环变量 */
if (s[i] != '\0') { /* 字符串没有到结尾 */
i++;
reverse(s);
}
s[j++] = s[i];
s[j] = '\0';
}
运行结果是打印一个空行。原因是当跳出
if(s[i] != '\0')
时, s[i] = '\0',然后一直执行
s[j++] = s[i];
s[j] = '\0';
导致字符数组s里面全为'\0',所以执行main函数(这里未给出main函数代码)时打印一个空行。
参考课本49页for循环实现reverse函数。

实现:
#include <stdio.h>
#include <string.h>
void reverse(char [], int, int);
int main()
{
int i;
char s[] = "abcdefghi";
reverse(s, 0, strlen(s) - 1);
for (i = 0; i < 6; i++)
printf("%c ", s[i]);
printf("\n");
return 0;
}
void reverse(char s[], int i, int j) /* 调用时,i = 0, j = len - 1*/
{
int c;
if (i < j) {
c = s[j];
s[j] = s[i];
s[i] = c;
reverse(s, ++i, --j);
}
}
练习4-14(教材77页)
定义宏swap(t, x, y),以交换类型的两个参数。(使用程序块会对你有所帮助。)
所定义的宏如下所示:
#define swap(t, x, y) { t temp; \
temp = y; \
y = x; \
x = temp; }