1. 程式人生 > >《明解C語言》示例程式碼和練習程式碼[第11章]

《明解C語言》示例程式碼和練習程式碼[第11章]

第11章 字串和指標


示例程式碼:


示例程式碼11-1

/*
    用陣列實現的字串和用指標實現的字串 
*/

#include <stdio.h>

int main(void)
{
    char str[] = "ABC";        // 用陣列實現的字串
    char *ptr  = "123";        // 用指標實現的字串
    
    printf("str = \"%s\"\n", str);
    printf("ptr = \"%s\"\n", ptr);

    return (0);
}

示例程式碼11-2

/*
    用陣列實現的字串和用指標實現的字串的相同點 
*/

#include <stdio.h>

int main(void)
{
    int i;
    char str[] = "ABC";
    char *ptr  = "123"; 
    
    for (i = 0; str[i]; i++)
        putchar(str[i]);                // str[i]是第一個字元之後的第i個元素 
    putchar('\n');
    
    for (i = 0; ptr[i]; i++)
        putchar(ptr[i]);                // str[i]是第一個字元之後的第i個元素
    putchar('\n'); 
    
    printf("str = \"%s\"\n", str);      // str是指向第1個字元的指標 
    printf("ptr = \"%s\"\n", ptr);      // ptr是指向第1個字元的指標  
    
    return (0); 
}

示例程式碼11-3

/*
    字串賦值(?) 
*/ 

#include <stdio.h>

int main(void)
{
    char str[] = "ABC"; 
    char *ptr  = "123"; 
    
    str = "DEF";                    // 錯誤:不能這樣賦值
    ptr = "456";                    // 正確:指向另一個字串字面量    
    
    printf("str = \"%s\"\n", str);
    printf("ptr = \"%s\"\n", ptr); 
    
    return (0);
} 

示例程式碼11-4

/*
    用陣列實現的字串和用指標實現的字串(其二) 
*/

#include <stdio.h>

int main(void)
{
    char str[6] = "ABC";       // 用陣列實現的字串
    char *ptr   = "123";       // 用指標實現的字串
    
    printf("str = \"%s\"\n", str);
    printf("ptr = \"%s\"\n", ptr); 
    
    return (0);
}

示例程式碼11-5

/*
    用“陣列實現的字串”的陣列和“用指標實現的字串”的陣列 
*/

#include <stdio.h>

int main(void)
{
    int i;
    char st[3][6] = {"Turbo", "NA", "DOHC"};
    char *pt[3]   = {"12345", "12", "1234"};
    
    for (i = 0; i < 3; i++)
        printf("st[%d] = \"%s\"\n", i, st[i]); 
    
    for (i = 0; i < 3; i++)
        printf("pt[%d] = \"%s\"\n", i, pt[i]);
    
    return (0);
}

示例程式碼11-6

/*
     判斷字串的長度(指標版) 
*/

#include <stdio.h>

// 返回字串s的長度
size_t str_length(const char *s)
{
    size_t len = 0;
    
    while (*s++)
        len++;
    
    return (len);       
} 

int main(void)
{
    char st[100];
    
    printf("請輸入字串:");
    scanf("%s", st);
    
    printf("字串%s的長度為%u。\n", st, (unsigned)str_length(st));
    return (0);    
}

示例程式碼11-7

/*
    複製字串 
*/

#include <stdio.h>

// 將字串s複製到d
char *str_copy(char *d, const char *s)
{
    char *t = d;
    
    while (*d++ = *s++)
        ;
    return (t);     
} 

int main(void)
{
    char s1[128] = "ABCD";
    char s2[128] = "EFGH";
    
    printf("字串s1:");    scanf("%s", s1);
    
    str_copy(s2, s1);
    
    puts("s1複製到了s2。");
    printf("s1 = %s\n", s1);
    printf("s2 = %s\n", s2);
    
    return(0);   
}

示例程式碼11-8

/*
    複製字串(誤例) 
*/

#include <stdio.h>

// 將字串s賦值到d
char *str_copy(char *d, const char *s)
{
    char *t = d;
    
    while (*d++ = *s++)
        ;
    return (t);     
} 

int main(void)
{
    char str[128] = "ABCD";
    char *ptr     = "EFGH";
    
    printf("字串str:");    scanf("%s", str);
    
    str_copy(ptr, str);
    
    puts("str複製到了ptr。");
    printf("str = %s\n", str);
    printf("ptr = %s\n", ptr);
    return(0);    
}

示例程式碼11-9

// 返回字串s的長度 

size_t strlen(const char *s)
{
    size_t len = 0;
    
    while (*s++)
        len++;
    return (len);       
}

示例程式碼11-10

// 將字串s2新增到s1之後
char *strcat(char *s1, const char *s2)
{
    char *tmp = s1;
    
    while (*s1)    s1++;            // 前進到s1的末尾處 
    while (*s1++ = *s2++);          // 迴圈複製直至遇到s2中的‘\0’ 
    return (tmp);      
} 

// 將字串s2的前n個字元複製到s1 
char *strcat(char *s1, const char *s2, size_t n)
{
    char *tmp = s1;
    while (*s1)    s1++;                   // 前進到s1的末尾處 
    while (n--)
        if (!(*s1++ = *s2++))    break;    // 遇到 ‘\0’就結束迴圈 
    *s1 = '\0';                            // 在s1的末尾插入‘\0’ 
    return (tmp);
}

示例程式碼11-11

// 將字串s2新增到s1之後
char *strcat(char *s1, const char *s2)
{
    char *tmp = s1;
    
    while (*s1)    s1++;            // 前進到s1的末尾處 
    while (*s1++ = *s2++);          // 迴圈複製直至遇到s2中的‘\0’ 
    return (tmp);      
} 

// 將字串s2的前n個字元複製到s1 
char *strcat(char *s1, const char *s2, size_t n)
{
    char *tmp = s1;
    while (*s1)    s1++;                   // 前進到s1的末尾處 
    while (n--)
        if (!(*s1++ = *s2++))    break;    // 遇到 ‘\0’就結束迴圈 
    *s1 = '\0';                            // 在s1的末尾插入‘\0’ 
    return (tmp);
}

示例程式碼11-12

// 比較字串s1和s2
int strcmp(const char *s1, const char *s2)
{
    while (*s1 == *s2) {
        if (*s1 == '\0')
            return (0);                         // 相等 
        s1++;
        s2++;
    }
    return ((unsigned char)*s1 - (unsigned char)*s2);
} 

// 比較字串s1和s2的前n個字元 
int strncmp(const char *s1, const char *s2, size_t n)
{
    while (n && *s1 && *s2) {
        if (*s1 != *s2)                         // 不相等 
            return ((unsigned char)*s1 - (unsigned char)*s2);
        s1++;
        s2++;
        n--; 
    }    
    if (!n)    return (0);                      // 相等
    if (*s1)   return (1);                      // s1 > s2
    return (-1);                                // s1 < s2
}

示例程式碼11-13

// stoi函式的執行情況

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char str[] = "12345";
    
    printf("str  =\"%s\"\n", str);
    printf("atoi(str) = %d\n", atoi(str));
    return (0);    
} 


練習程式碼:

練習程式碼e11-1

/*
    依次顯示字串中的字元 (不使用下標運算子)
*/

#include <stdio.h>

// 顯示字串(不換行)
void put_string(const char str[])
{    
     while (*str)
         putchar(*str++);
} 

int main(void)
{
    char str[100];
    
    printf("請輸入字串:");
    scanf("%s", str);
    
    put_string(str);
    putchar('\n');

    return (0);    
}

練習程式碼e11-2

/*
    編寫如下函式,若字串str中含有字元c(若含有多個,以先出現的為準),、
    則返回指向該字元的指標,否則返回NULL。 
*/

#include <stdio.h>

char *str_chr(const char *str, int c)
{
    char *p = NULL;
    
    while (c == *str) {
        p = str;
        str++;
    }
    return (p);     
}

int main(void)
{
    char str[100];
    char c;
    
    printf("請輸入字串:");    scanf("%s", str); 
    
    getchar();                   // 清除快取 
    
    printf("請輸入要查詢的字元:");    scanf("%c", &c);
    
    printf("\n返回的指標地址是:%p。\n", str_chr(str, c));
    
    return (0);   
}

練習程式碼e11-3

/*
    編寫如下函式,不使用下標運算子,返回字串str中字元c的個數
    (若不存在則為0)。 
*/

#include <stdio.h>

int str_chnum(const char *str, char c)
{
    int n = 0;
    
    while (*str) {
        if (c == *str++)    n++;
    }    
    return (n);
}

int main(void)
{
    char str[100];
    char c;
    
    printf("請輸入字串:");    scanf("%s", str); 
    
    getchar();                   // 清除快取 
    
    printf("請輸入要查詢的字元:");    scanf("%c", &c);
    
    printf("\n字串\"%s\"中含有%d個字元\'%c\'。\n", str, str_chnum(str, c), c);

    return (0);    
}

練習程式碼e11-4

/*
    不使用下標運算子,寫出與程式碼清單9-13中的str_toupper函式
    和str_tolower函式功能相同的函式。 
*/ 

#include <ctype.h>  
#include <stdio.h>  
  
// 將字串中的英文字元轉換為大寫字母  
void str_toupper(char *str)  
{  
    while (*str)
        *str = toupper(*str++);     
}   
  
// 將字串中的英文字元轉換為小寫字母  
void str_tolower(char *str)  
{  
    while (*str)
        *str = tolower(*str++);    
}  
  
int main(void)  
{  
    char str[100];  
      
    printf("請輸入字串:");  
    scanf("%s", str);  
      
    str_toupper(str);  
    printf("大寫字母:%s\n", str);  
      
    str_tolower(str);  
    printf("小寫字母:%s\n", str); 
    
    return (0);  
}  

練習程式碼e11-5

/*
    不使用下標運算子,編寫如下函式,刪除字串str中的所有數字字元
    (例如將傳入的“AB1C9”變為“ABC”) 
*/

#include <stdio.h>

// 返回字串長度

int length(const *str) 
{
    int len = 0;
    while (*str++)    len++;
    return (len); 
}

// 去除字串中的數字
void del_digit(char *s)
{   
    char *p = s;
    
    while (*p)
        if ((*p >= '0') && (*p <= '9'))
            p++;
        else
            *s++ = *p++;
    *s = '\0';    
} 

int main()
{
    char s[100];
    
    printf("請輸入字串:");    scanf("%s", s);
    
    printf("輸入的字串是:%s。\n", s);
    
    del_digit(s);
    printf("去數的字串是:%s。\n", s);

    return (0);    
}

練習程式碼e11-6

/*
    編寫如下函式,實現與庫函式atoi、atol、atof相同的功能。 
*/

int len(const char *nptr)
{
    int len = 0;
    while (*nptr++)    len++;
    return (len);
}


double power_10(long n)
{
    double p = 1; 
    
    if (n > 0)
        while (--n)    p *= 10;
    else if (n < 0)
        while (n++)    p /= 10;
    else
        p = 1;
    return p;
}

// 字串轉換為整形 
int strtoi(const char *nptr)
{
    int n = len(nptr);
    int num = 0;
    
    while (*nptr) {
        num += (*nptr - '0') * power_10(n--);
        nptr++;
    }
    return (num);
}

// 字串轉換為長整形 
long strtol(const char *nptr)
{
    long n = len(nptr);
    long num = 0;
    
    while (*nptr) {
        num += (*nptr - '0') * power_10(n--);
        nptr++;
    }
    return (num);
}

// 字串轉換為浮點形 
double  strtof(char *nptr)
{
    char *p1 = nptr;
    char *p2;
    char *p3;
    
    int n1 = 0;
    int n2 = 0;
    int n3;
    
    double num = 0.0;
    
    while (*p1 != '.') {
        n1++;
        p1++;
    }

    p2 = ++p1;

    p3 = p2;
    
    while (*p3++)    n2--;
    
    while (*nptr != '.') {
        num += (*nptr - '0') * power_10(n1--);
        nptr++;
    }
    
    n3 = n2;
    
    while (*p2) {
        num += (*p2 - '0') * power_10(n3 - ++n2);
        p2++;
    }
    
    return (num);
}

int main(void)
{
    char s[100];
    
    printf("請輸入一個整數:");    scanf("%s", s);
    
    printf("\n轉換成整形:%d\n", strtoi(s));
    
    printf("\n請輸入一個長整數:");    scanf("%s", s);
    
    printf("\n轉換成長整形:%ld\n", strtol(s));
    
    printf("\n請輸入一個浮點數:");    scanf("%s", s);
    
    printf("\n轉換成浮點形:%lf\n", strtof(s));

    return (0);    
}