第四章(二)

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


發佈了37 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章