第四章(二)

----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; }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值