21Winter\ C语言\第五章 上机报告

C语言程序设计 第五章 上机报告

expr1

#include<stdio.h>
int main(){
    char string[]="I am a girl.";
    printf("%s\n",string);
    printf("%c,%c\n",string[5],*(string+7));
    return 0;
}

expr1 变式1

#include<stdio.h>
int main(){
    Char string[]="I am a girl.";
    printf("%s\n",string);
    printf("%c,%c\n",string[5],*(string+7));
    return 0;
}

我们可以注意到,虽然看起来二者的输出是完全一样的,但其实上发生了本质的区别。一个是以字符串常量的方式存储,并且由一个声明的指针变量指向这个字符串常量的首地址。另外一个是直接声明一段连续的内存,并且数组名就是头指针

expr1 变式2

查阅可以得到printf函数的原型:

int printf(const char *format, ...);

当printf函数进行打印的时候,如果输出的format是%d,%c则传入的是一个确切的值,而对于%s而言传入的是一个char型的指针。

在这个代码之中出现了错误导致了无法输出的错误。

对代码的L5进行了改动之后:

 printf("%s,%s\n",string[5],*(string+15));

进行分析可以得出,传入的可以认为是先对string取内容之后的值(其实是以对应的字符的ASCII),然后会访问到其他部分的内容,从而导致报错。

expr2

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
    char str[100], *p, *q, *r, c;
    gets(str);    
    for(p = str;*p;p++){
        for(q=p,r=p; *q; q++)
            if(*r > *q)
                r = q;
        if(r!=p){
            c = *r;
            *r = *p;
            *p = c;
        }
    }
    for(p = str; *p; p++){
        for (q = p+1; *q == *p; q++);
        strcpy(p+1,q);
    }
    puts(str);
    return 0;
}

以下对于这一个程序填空的代码进行分析

从Line7到Line15的这一个双重for循环之中,本质上完成的是一个选择排序的过程。以q作为一个二级的指针向后访问找到之后的字符串之中的最大值,然后对于二者进行交换。

注意,“交换”交换的是具体的值而不是后续问题之中的地址交换。

所以进行了这一个双重循环加工之后的字符串,是一个递增的字符串。

然后非常巧妙的用Line18的这一个for空语句实现了while类似的功能,把重复出现的字符给删除掉。

expr3

#include<stdlib.h>
#include<stdio.h>
int main(){
    char *k = (char*) malloc(sizeof(char)*20);
    char str[50];
    int count=0,i=0;
    gets(k);
    while(*k){
        str[i++] = *k++, count++;
        if((count)%3==0) str[i++] = ' ';
    }
    str[i++]='\0';
    puts(str);
    system("pause");
    return 0;
}

要注意的事情是Line12的一个加入‘\0’ 的最后,否则会导致其输出的异常。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gfOnEJeu-1640236445558)(C:\Users\Bealliant\AppData\Roaming\Typora\typora-user-images\image-20211210144202034.png)]

对于这里面的三个变量的解释:

k:标记的是从字符串k,即复制的来源。

i:标记的是把字符复制进字符串str的时候的

count:标记的是复制的次数。

expr4

#include<stdio.h>
#include<stdlib.h>
#define SIZE 5
int stringcmp(char* p1, char* p2){
    while(*p1++ ==* p2++);
    return *--p1 - *--p2;
}
int main(){
    char *p[SIZE];
    for(int i =0; i<SIZE;i++){
        char *temp = (char*)malloc(sizeof(char)*20);
        gets(temp);
        p[i] =  temp;
    }
    char *temp;
    printf("-----------\n");
    for(int i=0;i<SIZE-1;i++){
        for(int j = SIZE-1; j > i; j--){
            if(stringcmp(p[j],p[j-1])>0)
                temp = p[j], p[j] = p[j-1], p[j-1] = temp; 
        }
    }
    for(int i=0;i<SIZE;i++) 
        puts(p[i]);
    return 0;
}

1.注意自定义函数之中的–,因为是边比较边自加,所以会比较完向后加一位。

2.执行的是指针数组之中的一个地址的交换,通过每一个字符串的首地址找到这一整个字符串。

样例只用了五个,方便查看,可以直接在Line3之中对于其进行改变。

expr5

#include<stdlib.h>
#include<stdio.h>
int str2num(char* str, int* num){
    int i=0, temp = 0;
    while(*str){

    if(*str>='0' && *str <= '9') 
        temp*=10, temp+= *str -'0';
    else
        num[i++] = temp,temp=0;

    str++; 
    }
    num[i++] = temp,temp=0; 
    // 最后的时候会碰到一个\0的break; 无法向num之中继续写入存了一半的数字
    // 之所以return的是i而不是 i-1 是因为0-index和1-index的差距。
    return i;

}
int main(){
    int num[20],out[20];char str[40];
    gets(str);
    int size = str2num(str,num);
    int k = 0;
    for(int i=0;i<size;i++){
        int status = 1;
        for(int j=0;j<i && status;j++)
            if(num[j]==num[i])  status=0; 	
        if(status) out[k++] = num[i];
    }
    for(int i=0;i<k;i++){
        printf("%4d",out[i]);
    }
    system("pause");
    return 0;
}

写了一个函数,可以直接字符串转数组。

一个使用额外内存的数组复制问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值