计算机程序设计实训记录(6)

这几天都在摸鱼ヽ(✿゚▽゚)ノ导致进度太慢了,所以赶紧写吧
上一篇我们搞定了五个函数,这篇就继续写剩下的函数吧。

课程任务

交换C-字符串

要求完成 4 个函数的设计,包括函数原型设计、函数定义、测试代码中函数调用。请思考 SWAP1 函数
和 SWAP2(或 SWAP3)函数应用场合能否互换,其原因是什么。要求函数原型设计时尽量做到精准。

虽然这么说但是要求在哪里啊(っ °Д °;)っ
在翻了翻文件后,还是找到了。

SWAP1

char array1[10]="Tom", array2[10]="Jerry";

传入的是两个字符数组的指针,那就直接遍历一遍就好了

void SWAP1(char*a,char*b)
{
    char t;
    for(;*a||*b;a++,b++)
    {
    t=*a;
    *a=*b;
    *b=t;
    }
}

SWAP2

char array1[]="Tom", array2[]="Jerry";
char *p1=array1, *p2=array2;

不难看出,传入的两个指针是分别指向字符数组array1和array2的,用一个二重指针交换他们的值就好了。

void SWAP2(char** a,char** b)
{
    char*t=*a;
    *a=*b;
    *b=t;
}

这里有一个问题,就是传参的时候得用SWAP2(&p1, &p2);来取地址,我曾试过用void SWAP2(char** &a,char** &b),但好像不通过。
不管了不管了,在课程文件的test.c里面并没有规定调用方式

SWAP3

char *p1="Tom", *p2="Jerry";

这里是字符串指针。
他们是指向静态存储区的字符串的指针,按理说同样交换一下就好了。

void SWAP3(char** a,char** b)
{
    char*t=*a;
    *a=*b;
    *b=t;
}

真的这么简单吗(心虚)

STRCAT

================================= in test4() ==================================
p1: "Tom", p2: "Jerry"
指针所记录的地址值 p1: 672F18, p2: 670C60
--- 调用自定义函数 STRCAT,用" & "连接两个字符串 ---
指针所记录的地址值 p1: 670C70, p2: 670C60
--- 请注意观察指针 p1 前后两次所指向的地址值是否改变 ---
p1: "Tom & Jerry", p2: "Jerry"
============================= return from test4() =============================

或许可以按照上一篇的StrCat来修改:

char* STRCAT(char *dst, const char *src)
{
    char *p=" & ";
    char *temp = dst;
    while (*temp != '\0')
        temp++;
    while ((*temp++ = *p++) != '\0');
    temp--;//退一位
    while ((*temp++ = *src++) != '\0');
    return dst;
}

但是这样的话地址根本没有变啊,和题目要求的不一样。
这个时候我们就要想,为什么,要求改换地址。
你听说过,字符串破坏的故事吗?
很明显,依照这种写法,如果长度超出的情况下会影响后面的字符串。
例如,我们用安卓手机上的C语言编译器app运行这段程序,就会得到以下结果

============================== in test4() ==================================
p1: "Tom", p2: "Jerry"
指针所记录的地址值 p1: C142B008, p2: C142B010
--- 调用自定义函数 STRCAT,用" & "连接两个字符串 ---
指针所记录的地址值 p1: C142B008, p2: C142B010
--- 请注意观察指针 p1 前后两次所指向的地址值是否改变 ---
p1: "Tom & Jerry", p2: "rry"
============================= return from test4() =============================

当然,实际上温柔的GCC是会守护这些字符串的
那么我们就得另寻他法,李代桃僵。为合成的字符串寻找新的内存空间。

char* STRCAT(char **dest, const char *source)
{
    const char *p=" & ";//中间插入部分
    char *t = *dest;
    char *temp=(char*)calloc(114514, sizeof(char));
    int n=0;
    for(;*t;t++,temp++){
        *temp=*t;
        n++;
    }
    for(;*p;p++,temp++){
        *temp=*p;
        n++;
    }
    for(;*source;source++,temp++){
        *temp=*source;
        n++;
    }
    *dest=temp-n;//最后传值要回到数组头部
    return *dest;
}

有趣的是,我这里想故技重施使用while((*temp++ = *p++) != '\0'),却出现了一些意料之外的情况╮(╯-╰)╭


做完了这个,就是最后的排序函数了(。・∀・)ノ

排序函数

一系列字符串的集合称为字符串数组。字符串数组有两种不同的存储形式:①二维数组;②字符指针数组。
已经设计了两个不同的函数 Show1 和 Show2 分别用于输出两种形式的字符串数组个元素的值。
对于这两种形式,请分别设计函数对它们进行排序。要求任意选择一种排序算法(例如冒泡排序),编写如下 4个排序函数。

字典序 长度序
二维数组 Sort1A Sort1L
字符指针数组 Sort2A Sort2L
目标效果

原始数据1
enter, number, size, begin, of, cat, case, program, certain, a, cake, side
排序结果(字典序)
a, begin, cake, case, cat, certain, enter, number, of, program, side, size
排序结果(字符串长度序)
a, of, cat, cake, case, side, size, begin, enter, number, certain, program

原始数据2
enter, number, size, begin, of, cat, case, program, certain, a, cake, side
排序结果(字典序)
a, begin, cake, case, cat, certain, enter, number, of, program, side, size
排序结果(字符串长度序)
a, of, cat, cake, case, side, size, begin, enter, number, certain, program
测试程序

char str1[][8]={"enter", "number", "size", "begin", "of", "cat", "case", "program", "certain", "a", "cake", "side"};
char *str2[] = {"enter", "number", "size", "begin", "of", "cat", "case", "program", "certain", "a", "cake", "side"};

str1和str2分别对应二维数组和字符指针数组。
至于两个SHOW函数,我们不难发现他们都是直接展示交换后的数组的,至此,胜利的法则已经确定了。

Sort1A

说到排序,那想必就是冒泡排序了——但是,我拒绝,我要用选择排序!

void Sort1A(char(*str)[8],int size){     //ASCII
    int i,j,k=0;
    char temp[114514];
    for(i=1;i<size;i++){
        for(j=i;j<size;j++){
            if(strcmp(str[j],str[k])<0)
                k=j;
        }
        if(k!=i-1){
            strcpy(temp,str[k]);
            strcpy(str[k],str[i-1]);
            strcpy(str[i-1],temp);
        }
        k=i;
    }
}

Sort1L

void Sort1L(char(*str)[8],int size){     //Length
    int i,j,k=0;
    char temp[114514];
    for(i=1;i<size;i++){
        for(j=i;j<size;j++){
            if(strlen(str[j])<strlen(str[k]))
                k=j;
        }
        if(k!=i-1){
            strcpy(temp,str[k]);
            strcpy(str[k],str[i-1]);
            strcpy(str[i-1],temp);
        }
        k=i;
    }
}

Sort2A

void Sort2A(char**str,int size){     //ASCII
    int i,j,k=0;
    char *temp;
    for(i=1;i<size;i++){
        for(j=i;j<size;j++){
            if(strcmp(*(str+j),*(str+k))<0)
                k=j;
        }
        if(k!=i-1){
            temp=*(str+k);
            *(str+k)=*(str+i-1);
            *(str+i-1)=temp;
        }
        k=i;
    }
}

Sort2L

void Sort2L(char**str,int size){     //Length
    int i,j,k=0;
    char *temp;
    for(i=1;i<size;i++){
        for(j=i;j<size;j++){
            if(strlen(*(str+j))<strlen(*(str+k)))
                k=j;
        }
        if(k!=i-1){
            temp=*(str+k);
            *(str+k)=*(str+i-1);
            *(str+i-1)=temp;
        }
        k=i;
    }
}

至此,我们就都写完了,好耶!(o゜▽゜)o☆

posted @ 2020-08-10 17:25  DoRCL  阅读(333)  评论(0)    收藏  举报