《C语言程序设计实验》实验报告

C语言程序设计实验》实验报告

指导老师:李盘林

专业:信息安全  

班级:0441001   

学号:2010212137

姓名:钟志成    

日期:20##-05-29 

重庆邮电大学计算机科学与技术学院

实验一

实验名称:一维数组程序设计

实验目的:

1、              熟练掌握使用一维数组编程的方法。

2、            熟练掌握排序算法。

实验内容:

1、  调试示例

输入一个整数n(0<n<9)和一组数,再输入一个整数,把x插入到这个数据中,使该组数据仍然有序。

源程序:略

调试好的程序:

#include<stdio.h>

int main()

{

int i,j,n,x,a[10];

printf("输入数据的个数n:");

scanf("%d",&n);

printf("输入%d个整数:",n);

for(i=0;i<n;i++)

scanf("%d",&a[i]);

printf("输入要插入的整数:");

scanf("%d",&x);

for(i=0;i<n;i++)

{

        if(x>a[i])continue;

        j=n-1;

        while(j>=i){

               a[j+1]=a[j];

               j--;

        }

        a[i]=x;

        break;           

}

if(i==n)a[n]=x;

for(i=0;i<=n;i++)

printf("%d\t",a[i]);

return 0;

}

2、  编程题1

输入一个正整数n(0<n<=10),再输入n个整数,输出平均值(保留两位小数)。

程序代码:

#include<stdio.h>

int main()

{

       int i,n,sum=0,a[10];

       float av;

       printf("输入数据的个数n:");

       scanf("%d",&n);

       printf("输入%d个整数:",n);

       for(i=0;i<n;i++)

       scanf("%d",&a[i]);

      

       for(i=0;i<n;i++)

       {

              sum+=a[i];

       }

       av=(float)sum/n;

       printf("%0.2f\t",av);

       return 0;

}

3、  编程题2

输入一个正整数n(0<n<=10),再输入n个整数,按逆序输出这些数。

程序代码

#include<stdio.h>

int main()

{

       int i,n,a[10];

       printf("输入数据的个数n:");

       scanf("%d",&n);

       printf("输入%d个整数:",n);

       for(i=0;i<n;i++)

       scanf("%d",&a[i]);

       for(i=n-1;i>=0;i--)

       printf("%d\t",a[i]);

       return 0;

}

4、  编程题3

输入一个正整数n(0<n<=10),再输入n个整数,输出最大值及其下标(设最大值唯一,下标从零开始)。

程序代码:

#include<stdio.h>

int main()

{

       int i,j,n,x,a[10];

       printf("输入数据的个数n:");

       scanf("%d",&n);

       printf("输入%d个整数:",n);

       for(i=0;i<n;i++)

       scanf("%d",&a[i]);

       x=a[0];

       for(i=0;i<n;i++)

       {

              if(a[i]>x){x=a[i];j=i;}         

       }

       printf("最大数:%d\t下标:%d\t",x,j);

       return 0;

}

5、  编程题4

输入一个正整数n(0<n<=10),再输入n个整数,将最小值与第一个数交换,最大值与最后一个数交换,然后输出交换后的n个数。

程序代码:

#include<stdio.h>

int main()

{

       int i,n,j=0,k=0,x,y,a[10];

       printf("输入数据的个数n:");

       scanf("%d",&n);

       printf("输入%d个整数:",n);

       for(i=0;i<n;i++)

       scanf("%d",&a[i]);

       y=a[0];

       x=a[0];

       for(i=0;i<n;i++)

       {

              if(a[i]>x){x=a[i];j=i;}

              if(a[i]<y){y=a[i];k=i;}  

       }

       a[j]=a[0];

       a[0]=y;

       a[k]=a[i-1];

       a[i-1]=x;

       for(i=0;i<n;i++)

       printf("%d\t",a[i]);

       return 0;

}

6、  编程题5

输入一个正整数n(0<n<=10),再输入n个整数,再将它们从小到大排序后输出。

程序代码:

#include<stdio.h>

int main()

{

       int i,n,j=0,x,a[10];

       printf("输入数据的个数n:");

       scanf("%d",&n);

       printf("输入%d个整数:",n);

       for(i=0;i<n;i++)

       scanf("%d",&a[i]);

       x=a[0];

       for(i=0;i<n-1;i++)

       {

              for(j=i;j<n-1;j++)

              {

                     if(a[i]>a[j+1])

                     {

                            x=a[i];a[i]=a[j+1];a[j+1]=x;

                     }

                     else continue;

              }    

       }

       for(i=0;i<n;i++)

       printf("%d\t",a[i]);

       return 0;

}

实验总结:

本次C语言上机实验,主要是对一维整数数组进行处理,通过本次实验,我熟练掌握了一维数组元素的处理组排序算法(冒泡排序法和选择排序法)。

实验二

实验名称:字符串程序设计

 【实验1判断回文

从键盘输入一串字符,判断该字符串是否是回文,即该字符串从左向右读,与从右向左读都一样,如“ABCBA”、“ABCCBA”。

编程思路:

定义指针start和end,分别指向字符串首、尾。分别从串首、尾开始向中间比较,若指针所指字符不同,则不是回文。

源程序:

#include<stdio.h>

#include<string.h>

int is(char*ptr);

void main()

{

       char str[100];

       printf("input a string\n");

       gets(str);

       if(is(str))

       {printf("%s is a Palindrome\n",str);}

       else

       {printf("%s is a not palindrome\n",str);}

}

int is(char*ptr)

{

       int i,a,flag=0;

       a=(int)strlen(ptr)-1;//数组下标从0开始!

       for(i=0;a>=0;i++,a--)

       {

              if(ptr[a]==ptr[i])

                     flag=1;

              else

              {

                     flag=0;

                     break;

              }

       }

       return flag;

}

【实验2】删除排序

已知某已排好序的数组,其元素为{1,3,5,7,9},从键盘输入x的值,若数组中存在与x相等的元素,则删除。

编程思路:

搜索整个数组判断x是否存在于数组中;如果在,定位待删除元素的下标 ;从该下标开始,将所有后续元素往前移。注意移动顺序应从最后一个元素开始,还是先从待删除元素的位置开始!

源程序:

#include<stdio.h>

#include<stdlib.h>

int *Delete(int a[],int n,int x)

{

       int i,pos,k;

       for(i=0;i<n;i++)

       {

              if(a[i]==x)

              {     pos=i;

                  break;

              }

       }

           for(k=pos;k<n-1;k++)

                     a[k]=a[k+1];

       return a;

}

int main()

{

       int arr[5]={1,3,5,7,9},x,i;

       printf("input x= ");

       scanf("%d",&x);

       printf("before delete");

       for(i=0;i<5;i++)

              printf("%4d",arr[i]);

       printf("\n");

       Delete(arr,5,x);

       printf("after delete");

       for(i=0;i<4;i++)

              printf("%4d",arr[i]);

       printf("\n");

       return 0;

}

实验总结:

通过这次实验,了解了字符串的特点,它在数组中有结束标志“\0”,而其长度又不将起算在内,牢记这点对编程速率很有帮助。

实验三

实验名称:指针和二维数组

实验1N个字符串进行排序

编程思路:

第一种实现方式:要求从键盘输入N个字符串,将其存储在二维数组中,在主函数中进行排序。

第二种实现方式:要求定义指针数组指向N个字符串,调用函数sort()进行排序。sort()具有如下原型:

/*

函数返回值:多级指针类型char**,返回指针数组首地址

形式参数:指针p,char *,用于操纵N个字符串

line,int,表示字符串个数

*/

char ** sort(char * p[],int linel)

源程序:

#include <stdio.h>

#include <string.h>

#define N 5

int main()

{

       /*定义二维数组*/

       int i,k,j;

       char a[N][30],temp[20];

       /*从键盘输入N 个字符串*/

       printf("从键盘输入%d个字符串\n",N);

       for(i = 0;i < N;i++)

       gets(a[i]);

      

    for(i=0;i<N-1;i++)

       {

            k = i;

           /*若当前字符串大于 str[k],记录其下标*/

                     for(j=i+1;j<N;j++)

                     {

                            if(strcmp(a[k],a[j])<0)//a[i]改为a[k]

                                   k=j;

                     }

           if(k!=i)

           {

                 /*交换字符串 str[k]和 str[i]*/

                        strcpy(temp,a[i]);strcpy(a[i],a[k]);strcpy(a[k],temp);

           }

       }

      puts("\nAfter sort:");

      for( i = 0;i < N;i++)

           puts(a[i]);

       return 0;

}

【实验2】找众数

定义函数实现:

(1)输出整数数组中重复出现的数和重复的次数。

(2)找出整数数组中的众数(即出现次数最多的数)

并编写相应的主函数测试之。

编程思路:

先对数组排序,排序后数组内的元素如有相同值就会紧邻存储。

定义maxCount、maxI、seek,分别表示最多重复次数、最多重复次数对应的元素下标、当前正在查找的数值,将两数置0。从头扫描整个数组,统计每个元素出现的次数,如果出现次数大于maxCount,记录其出现次数和该元素对应下标。扫描完毕即可找到众数及其出现次数。

源程序:

#include <stdio.h>

#include <string.h>

#define N 6

int main()

{

       int a[N];

       int i,j,k,temp;

       int maxCount = 0,maxI = 0,seek = 0,count = 0;

       for(i = 0;i < N ;i++)

       {

           printf("请输入第%d 个数:",i + 1);

           scanf("%d",a + i);

       }

      /*选择法对数组排序*/

          for(i=0;i<N-1;i++)

          {

                 k=i;

                 for(j=i;j<N;j++)

                        if(a[k]>a[j])//a[i]改为a[k]

                               k=j;

                        if(i!=k)

                        {temp=a[i];a[i]=a[k];a[k]=temp;}

          }

       for(i = 0,seek = a[0];i <= N;i++)

       {

           if(seek == a[i])

           {

                 /*计数器加 1*/

                        count++;

           }

           else

           {

                 /*输出前一元素的值和出现次数*/

              printf("Number = %d,Count =%d\n",a[i-1],count);

        /*如果前一元素的出现次数比maxCount 大,则修改maxCount 和 maxI*/

              if(count>maxCount)

              {

                     maxCount=count;

                     maxI=i-1;

              }

             count = 0;

             count++;

             seek = a[i];

           }

       }

       printf("\nmaxNumber = %d,maxCount = %d\n",a[maxI],maxCount);

       return 0;

}

实验总结:

本次实验运用了选择法对数组进行排序,不管是二维数组,还是一维数组,其思路是一样的,只是具体的实现有所不同,比如比较字符串要用函数strcmp()。

实验四

实验名称:结构体

【实验1】计算椭圆面积

已知坐标系统中两点p1、p2构成的矩形是椭圆的外切矩形,如图3-1所示。

定义结构体

struct ellipse

{

struct point

{

int x;

int y;

}p1,p2;

double a ;

double b ;

};

从键盘输入p1、p2的坐标值,计算椭圆面积,已知积计算公式为:S = Πab。

程序代码:

#include <stdio.h>

#include <math.h>

struct ellipse

{

       struct point

       {

              int x;

              int y;

       }p1,p2;

       double a ;

       double b ;

};

typedef struct ellipse ell;

int main()

{

       ell e;

       double s;

       printf("请输入左上角顶点坐标:");

       /*输入坐标*/

       scanf("%d%d",&e.p1.x,&e.p1 .y);

       printf("请输入右下角顶点坐标:");

       /*输入坐标*/

       scanf("%d%d",&e.p2.x,&e.p2.y);

       /*计算椭圆面积*/

       e.a=abs((e.p1 .y-e.p2 .y))/2.0;//取整函数abs()

       e.b=abs((e.p1 .x-e.p2 .x))/2.0;

       s=3.14*e.a*e.b;

       printf("area = %lf\n",s);

       return 0;

}

实验总结:

这次实验用到了结构体的嵌套定义,通过实验,让我更深入了解结构体的定义,使用,访问等操作。

实验五

实验名称:指针强化1

【实验1】字符串逆序存储

编写一个函数inverse,实现将字符串逆序存放,即原字符串为“abcdef”,将其重新存储为“fedcba”。

实验思路:

从字符串中第一个字符开始,使其和最后一个字符交换,第二个字符和倒数第二个字符交换,……,一直到字符串中间的字符为止。

程序代码:

#include <stdio.h>

#include <string.h>

char * inverse(char *p)

{

      /*定义需要用到的变量*/

      int i,len;

      char tmp;

      len = strlen(p);

      /*将原字符串逆序存储于p所指数组中*/

      for(i=len-1;i>=len/2;i--)

      {

           tmp=*(p+i);*(p+i)=*(p+len-1-i);*(p+len-1-i)=tmp;

      }

      return p;

}

int main()

{

      char str[100];

      printf("请输入字符串:");

      gets(str);

      puts(inverse(str));

      return 0;

}

【实验2】字符串逆序存储

删除字符串s中所有出现的与变量c相同的字符。

程序代码:

#include <stdio.h>

#include <string.h>

char * squeez(char *s,char c)

{

      int i,j;

      for(i = j = 0;i<strlen(s);i++)//___请填空___

      {

           if(s[i] != c)

           {

                 s[j]=s[i];//___请填空___

                 j++;

           }

      }

      s[j] = '\0';

      return s;

}

int main()

{

      char s[100],c;

      printf("请输入字符串:");

      gets(s);

      printf("请输入变量:");

      c = getchar();

      puts(squeez(s,c));

      return 0;

}

实验总结:

这次与前面的某次实验的内容差不多,用到了知识点是指针,字符串。

实验六

实验名称:指针强化2

【实验1实现库函数atoi

已知C标准库函数atoi实现将字符串转换为整数的功能,如:

char str[] = "123456";

printf("对应的整数为:%d\n",atoi(str));

自定义函数:int atoi(char *str),使其实现同名标准库函数的功能。

实验思路:

先考虑最简单的情况,字符串中只有数字,如果是负数,字符串第一个元素是负号。定义变量sign,若字符串中第一个元素是'﹣',则sign值为-1,并让字符串指针指向下一元素。

指针指向字符串“-123456”的第一个数字字符'1',将其转换为对应数字1,放入变量t中,指针下移至后一元素'2',再将其转换为对应数字2,将t中1变成10,再加2,如此循环,至字符串结束。返回变量t*sign即可。

程序代码:

#include<stdio.h>

#include<string.h>

int atoi(char *str);

int main()

    {

         char str[100];

         printf("请输入字符串:");

         gets(str); //此处不能否替换成 scanf()!

         printf("对应的整数为:%d\n",atoi(str));

            return 0;

    }

int atoi(char*str)

{

      int i=0,a,s=0,sign=0,p=1;

      for(i=0;*(str+i)!='\0'&&p;i++)

      {

           if(*(str+i)=='-'&&(*(str+i+1)>=48&&*(str+i+1)<=57||i==0))

                 sign=-1;

           if(*(str+i)>=48&&*(str+i)<=57)

           {

                 a=*(str+i)-48;

                 s=s*10+a;

                 if(*(str+i+1)<=48&&*(str+i+1)>=57&&p)

                 p=0;

           }        

      }

      if(sign)

           s*=sign;

      return s;

}

【实验2】译码

编写change函数实现:将大于0小于1000的阿拉伯数字转换为罗马数字输出。阿拉伯数字和罗马数字对应关系如下:

并编写相应的主函数测试该函数。

实验思路:

先考虑最简单的情况,字符串中只有数字,如果是负数,字符串第一个元素是负号。定义变量sign,若字符串中第一个元素是'﹣',则sign值为-1,并让字符串指针指向下一元素。

指针指向字符串“-123456”的第一个数字字符'1',将其转换为对应数字1,放入变量t中,指针下移至后一元素'2',再将其转换为对应数字2,将t中1变成10,再加2,如此循环,至字符串结束。返回变量t*sign即可。

程序代码:

#include<stdio.h>

/*定义数据结构code 存储罗马字符*/

typedef struct

      {

           char s[3];//别忘了'\0'

           int a;

      }COD;

int change(COD *code,int num);

int main()

{

      COD code[13]={{"M",1000},{"CM",900},{"D",500},{"CD",400},{"C",100},{"XC",90},{"L",50},{"XL",40},{"X",10},{"IX",9},{"V",5},{"IV",4},{"I",1}};

       int x;

       printf("请输入一个阿拉伯数字:");

       scanf("%d",&x);

       if(x>0&&x<4000)

      change(code,x);

       else

             printf("输入的阿拉伯数字超出范围!!!\n");

      return 0;

}

int change(COD *code,int num)

{

      int i,a,last=0;

      while(num)

      {

           a=num/(*(code+last)).a;

           if(a<=0)last++;

           else

           {

                 for(i=0;i<a;i++)

                      printf("%s",(*(code+last)).s);

                 num%=(*(code+last)).a;//有点类似进制型问题

           }

      }

      putchar(10);

      return 0;

}

实验总结:

这次实验译码实验给我的印象比较深,开始在算法上有点纠结,后来想到了以上程序中的算法,其实是个逐减和取余的问题,另外还用到了结构体,指针等知识,综合性还是比较大的。但算法是面向过程程序设计的灵魂,想到算法就好办了。

实验七

实验名称:模拟1

简单题:计算卡片的最大数量

将一摞卡片按照图1所示叠放,使其中一部分悬于桌外(卡片数量为n,每张卡片长度为1)。当n=1时,仅有一张卡片,其最大可悬空长度为1/2;当n=2时, 置于底部的那张卡片其悬空长度是1/3,而置于顶部的卡片其悬空长度是1/2,故悬于桌外的总长度是1/2 + 1/3 = 5/6。可以推断,当有n张卡片时,悬空部分的总长度是:1/2 + 1/3 + 1/4 + ... + 1/(n + 1)。

从键盘输入一个最大悬空长度值,判断该长度下最多能叠放几张卡片。

图1 卡片最大可悬空长度示意图

程序代码:

#include<stdio.h>

int main()

{

      int i,maxl;

      float l,sum=0;

      printf("input length:\n");

      scanf("%f",&l);

      for(i=1;sum<l;i++)

      {

           sum+=(floata)1/(i+1);

           maxl=i;

      }

      printf("最多能放%d张。\n",maxl);

      return 0;

}

高难度题:图书管理(可选用结构体数组或链表完成)

图书馆的书对应的数据类型定义如下:

struct book

{

Char name_of_book[100];

Char author[25];

};

编写函数实现:

(1)统计某一作者编写了几本书。

(2)将所有书的记录存储到文件a.txt。

然后编写相应的主函数调用这两个函数。

程序代码:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

typedef struct book

{

       char book_name[50],

               author[20];

       struct book *next;

}BOOK;

/**********输入链表单元内容************/

void input(BOOK *p)

{

       printf("book name:\n");

       scanf("%s",p->book_name);

       printf("please input the author name:\n");

       scanf("%s",p->author); 

}

/**********创建一个链表单元**********/

BOOK *creat_node()

{

       BOOK *p;

       p=(BOOK *)malloc(sizeof(BOOK));

       if(p == NULL)

              {     printf("No enough memory !");

                     exit(0);

              }

       input(p);

       p->next=NULL;

       return p;

}

/**********创建一个链表**********/

BOOK *creat_list()

{

       BOOK *head=NULL,*tail=NULL,*p;

       char str[4];

       printf("List creating...\n");

       do

       {

              printf("Do you want to continue (yes/no) :");

              scanf("%s",str);

              if(strcmp(str,"yes")==0)

              {

                     p=creat_node();

                     if(head==NULL){head=tail=p;continue;}

                     tail->next=p;

                     tail=p;

              }

              if(strcmp(str,"yes")!=0&&strcmp(str,"no")!=0)

              {

                     printf("You must input 'yes' or 'no'.\n");

                     //getchar();

                     continue;

              }

             

              if(strcmp(str,"no")==0)break;

              //getchar();

       }while(1);

       printf("List create end...\n\n");

       return head;   

}

/************输出一个链表头部**********/

void print_a_head()

{

       printf("bname author\n");     

}

/************输出链表**********/

int print_list(BOOK *book)

{

       BOOK *p=book;

       if(book==NULL)

       {

              printf("no records!!!\n");

              return (0);

       }

       print_a_head();

       while(p!=NULL)

       {

              printf("%s;\t%s;\n",book->book_name,book->author);

              p=p->next;

       }

       putchar(10);

       return (0);

}

/**********查找统计链表name**********/

int count(BOOK *book, char name[])

{

       int count=0;

       BOOK *p=book;

       while(p!=NULL)

       {

              if(strcmp(p->author,name)==0){count++;}

              p=p->next;

       }

       return count;

}

/**********输入外部*********/

int output(BOOK *book)

{

       FILE *fp;

       BOOK *p=book;

       if((fp=fopen("a.txt","w"))==NULL)

       {printf("can not open!");return -1;}

       while(p!=NULL)

       {

              fputs(p->book_name,fp);

              fputc(32,fp);

              fputs(p->author,fp);

              fputc(10,fp);

              p=p->next;

       }

       return 0;

}

int main()

{

       char name[20];

       BOOK *book;

       book=creat_list();

       //print_list(book);

       printf("输入某作者的名字:\n");

       scanf("%s",name);

       printf("%s写的的书数:%d\n",name,count(book,name));

       output(book);

       return 0;

}

实验总结:

这次试验的第一题算法上想得到的话能很开做出来。“图书管理(可选用结构体数组或链表完成)”这题用到的知识点比较多,综合性也比较大,和我们之前布置的一道作业题目很相似,我用了动态链表+文件做这道题,算法上基本没什么难度,就是工作量比较大,做出来的代码也很长,这样编程的速率就很重要了,要求编程者各方面的能力都必须过硬,比如打字、对知识点的熟练程度、编程调试技巧等。

实验八

实验名称:文件

【实验1】抓交通肇事犯(复习循环)

一辆卡车交通肇事后逃逸。现场有三人目击事件,但是都没有记住车号,只记下车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前两位不同;丙是位数学家,他说:四位车号组成的数字刚好是一个整数的平方。请根据以上线索求出车号的四位数字。

程序代码:

#include <stdio.h>

#include <math.h>

int main()

{

       int i,j,k,num;

       for(i=0;i<=9;i++)

              for(j=0;j<=9;j++)

              {

                     if(i==j) continue;

                     num=1100*i+11*j;

                     for(k=0;k<=(int)sqrt(num);k++)

                     if(num==k*k)

                            printf("The number is: %6d\n",num);

              }

}

【实验2】写入数据至文件

从键盘输入一个字符串,将其中的小写字母全部转换为大写字母,然后输出到磁盘文件“test”中保存。输入的字符串以“!”结束。

程序代码:

#include <stdio.h>

#include <stdlib.h>

 void PutToFile(char *FileName);

 void ReadFromFile(char *FileName);

 void PutToFile(char *FileName)

 {

       char ch;

       FILE *fp = fopen(FileName,"w");

       if(fp == NULL)

       {

           printf("打开文件失败!\n");

           exit(EXIT_FAILURE);

       }

       printf("请输入数据:");

       while((ch=getchar())!='!') /*当前输入字符不是‘!’*/

       {

           if(ch>96&&ch<123)ch-=32;/*若是小写字母,将其换为大写字母*/

            if((fputc(ch,fp))==EOF)/*将当前输入字符写入文件*/

            /*判断写入是否成功,如果不成功,打印失败信息,终止程序*/

                     {

                        printf("打印失败!\n");

                        exit(EXIT_FAILURE);

                     }

       }

       fclose(fp);

       printf(" 向文件写入信息成功!\n");

 }

 void ReadFromFile(char *FileName)

 {

        char ch;

       FILE *fp = fopen(FileName,"r");

       if(fp == NULL)

       {

           printf("打开文件失败!\n");

           exit(EXIT_FAILURE);

    }

       ch=fgetc(fp);

       while(ch!=EOF)

       {

              putchar(ch);

              ch=fgetc(fp);

       }

       putchar(10);

       fclose(fp);

       printf("成功!\n");

 }

 int main()

 {

       PutToFile("test.dat");

       ReadFromFile("test.dat");

       return 0;

 }

实验总结:

这次试验主要练习文件处理,把那些相关的知识点记牢了,加上前面的编程的经验积累,难度还不是很大的。

实验九

实验名称:链表

实验1计算折线长度

已知如下结构体类型:

struct point

{

int x; //横坐标

int y; //纵坐标

struct point *next;

};

编程实现按一次enter键,动态产生一个point类型的节点,该节点的横纵坐标值随机产生,且坐标值只能在[0,100],敲击5次enter键以后,计算动态产生的5个点构成的折线总长度。

编程思路:

定义函数pt * CreateLink()实现链表的创建。在该函数中,用户敲击一次ENTER键,程序调用malloc或者calloc创建一个节点p,利用随机函数rand()给p->x和p->y赋值,再将该节点连接到head指针所指链表尾部(具体办法见8-0)。

定义函数void DestroyLink(pt * head)实现链表的销毁。具体办法是:让指针p指向头指针head所指的第一个节点,此时p所指节点即为本次循环要销毁的当前节点,然后让头指针指向下一个节点,即head = head ->next,最后free(p)。这样就销毁了一个节点。利用循环即可按此方法消除所有节点。

定义函数void PrintLink(pt * head)实现链表的打印。具体办法是:用p遍历整个链表所有节点,每遍历一个节点,即打印当前节点的横纵坐标,直到p指向链表的最后一个节点。

定义函数double CalcLen(pt *head)实现折线长度的计算。具体办法是:定义指针pr、p,分别指向第一节点和第二节点的前一个节点,计算两个节点的距离,累加到累加器中,再让pr、p分别挪向下一结点,指向第二节点和第三节点,在计算它们的距离,再进行累加,直到p指向最后一个节点。最后返回累加器的结果。

程序代码:

#include <stdio.h>

 #include <stdlib.h>

 #include <math.h>

 #include <time.h>

 struct point

 {

       int x; //横坐标

       int y; //纵坐标

       struct point *next;

 };

 typedef struct point PT;

 void PrintLink(PT * head)

 {

       PT *p = head;

       puts("打印所有点的坐标:");

       puts("---------------------------");

       while(p)

       {

           printf("(%d,%d)\n" ,p -> x , p -> y );

           p = p->next;

       }

 }

 PT * CreateLink()//前插法

{

       PT *p,*head=NULL;

       int i=0;

       while(getchar()=='\n'&&i<5)

       {

              p=(PT *)malloc(sizeof(PT));

              if(p == NULL)

                     {     printf("No enough memory !");

                            exit(0);

                     }

              p->x=rand()%101-1;

              p->y=rand()%101-1;

              p->next=head;

              head=p;

              i++;

              printf("(%d,%d)\n",p->x,p->y);

       }

       return head;

}

 double CalcLen(PT * head)

 {

       double length=0;

       PT * p1=head,* p2=head->next;

       while(p2!=NULL)

       {

              length+=sqrt(pow((p2->x-p1->x),2)+pow((p2->y-p1->y),2));

              p1=p1->next;

              p2=p2->next;

       }

       return length;

 }

 void DestroyLink(PT * head)//脱节再释放

 {

        PT * p=head,*p1;

        while(p!=NULL)

        {

              p1=p;

              p=p->next;

              p1->next=NULL;

              free(p1);

        }

        printf("成功释放链表!\n");

 }

 int main()

 {

        PT * head = CreateLink();

        double length;

     srand(time(NULL));      

     PrintLink(head);

     length = CalcLen(head);

     printf("length = %lf\n",length);

     DestroyLink(head); //这个函数没有,考试至少扣 5 分!!!

     return 0;

 }

实验总结:

这次试验主要练习链表处理,把那些相关的知识点记牢了,加上前面的编程的经验积累,虽然难度是比较大的,但多练,多实践,总会有收获的。

实验十

实验名称:综合程序设计1

任务1获取当前系统日期和时间

已知标准C库文件<time.h>中,有如下结构体和函数可以获取系统当前的日期和时间:

(1)与系统时间和日期相关的结构体

struc tm

{

int tm_sec; //秒,0-59

int tm_min; //分,0-59

int tm_hour; //时,0-23

int tm_mday; //天数,1-31

int tm_mon; //月数,0-11

int tm_year; //自1900的年数

int tm_wday; //自星期日的天数0-6

int tm_yday; //自1月1日起的天数,0-365

int tm_isdst; //是否采用夏时制,采用为正数

};

(2)获取时间的两个函数

long time(long *tloc) //本函数给出自格林威治时间197011日凌晨至现在所经

//过的秒数,并将该值存于tloc所指的单元中

struct tm *localtime(long *clock) //把clock所指的时间(如函数time()返回的时间)

//转换成当地标准时间,并以结构体tm形式返回

程序代码:

#include<stdio.h>

#include<time.h>

int main()

{

       struct tm *cc;

       long tt=0;

       time(&tt);

       //printf("%ld\n",tt);

       cc=localtime(&tt);

       printf("\n\n\t\t**********************************\n");

       printf("\t\t**\t%d年 %d月 %d日\t\t**\n\t\t**\t%d : %d : %d\t\t**\n",1900+cc->tm_year,1+cc->tm_mon,cc->tm_mday,cc->tm_hour,cc->tm_min,cc->tm_sec);

       printf("\t\t**********************************\n");

       return 0;

}

【任务2】利用OPENGL实现可视化时钟

【问题描述】

请仔细查找资料完成任务2。重点查找VC++中如何加入OPENGL相应库文件和头文件的方法。关于OPENGL相关知识,请自相参阅已上传到群中的《OpenGL编程指南(第四版)》、

(没有做)

实验总结:

这次试验我想应该是考察我们学习新知识的能力,用到的主要知识都是题中给出的,第二题要用到绘图的知识,由于没有资料参考,我没做出来。自学对一个编程者是很重要的,因为现今世界IT技术发展很快。

实验十一

实验名称:综合程序设计1

【实验10-1】数字校园一卡通

完成如下程序(可以采用结构体+文件、链表+文件、动态数组+文件等方法完成)。最好每个方法都实验一次。

srtuct one_card

{

char ID[9]; //一卡通编号

char name[20]; //姓名

char type; //’s’表示学生,’t’表示教师

double balance; //余额

};

请编写函数实现下列功能:

1、 为每张教师用卡补助100元(1、2任选一)

2、 从学生一卡通中扣除网费50元

3、 按一卡通编号查找某人信息(3、4、5任选一)

4、 按姓名查找某人信息

5、 按一卡通编号排序

6、 插入一个元素(6、7任选一)

7、 删除一个元素

8、 将信息写入文件a.txt(8、9任选一)

9、 从a.txt文件中读出所有信息

10、      编写主函数

程序代码:

#include<stdio.h>

#include <stdlib.h>

#include<string.h>

typedef struct one_card

    {

        char ID[9];   //一卡通编号

        char name[20]; //姓名

        char type;    //’s’表示学生,’t’表示教师

        double balance; //余额

              struct one_card *next;

    }CARD;

CARD * CreatLink(int n)

{

       CARD *head = NULL,*p,*pr;

       int i;

       for(i = 1;i <= n;i++)

       {

              p = (CARD *)malloc(sizeof(CARD));//生成新结点

              if(p == NULL)

              {

                     puts("can not satisfy the need to memory!");

                     exit(0);

              }

              //初始化当前结点

              puts("input ID:\t");

              getchar();

              gets(p->ID);

              puts("input name:\t");

              //getchar();

              gets(p->name);

              puts("input type:\t");

              //getchar();

              scanf("%c",&p->type);

              puts("input balance:\t");

              scanf("%lf",&p->balance);          

              p->next = NULL;

              if(head == NULL)//如果是创建的第一个结点

              {

                     head = p;

                     pr = p;

              }

              else

              {

                     pr->next = p;

                     pr = p;

              }

       }

       return head;

}

CARD * findID(CARD *head,char ID[])

{

       CARD *p=head;

       int i=1;

       while(p->next!=NULL)

       {

              if(strcmp(p->ID,ID)!=0)

                     p=p->next;

              else

              {

                     i=0;

                     break;

              }

       }

       if(i)

              return p;

       else

       {

              puts("not found!\n");

           return NULL;

       }

}

void putnode(CARD *p)

{

       puts(p->ID);

       puts(p->name);

       printf("%c\n",p->type);

       printf("balance:%5lf\n",p->balance);

}

void deltID(CARD *head,char ID[])

{

       CARD *p=head,*p1=NULL;

       int i=0;

       while(p!=NULL)

       {

              if(strcmp(p->ID,ID)!=0)

              {

                     p1=p;

                     p=p->next;

                     i=1;

              }

              else

              {

                     p1->next=p->next;

                     free(p);

                     i=0;

                     break;

              }

       }

       if(i)

              puts("ID error!\n");

}

void output_sreen(CARD *head)

{

       CARD *p=head;

       while(p!=NULL)

       {

              putnode(p);

              p=p->next;

       }

}

void output_file(CARD *head)

{

       FILE *fp;

       CARD *p=head;

       fp = fopen("a.txt","w");

       if(fp == NULL)

       {

           printf("打开文件失败!\n");

           exit(0);

       }

       while(p!=NULL)

       {

              fputs(p->ID,fp);putchar(10);

              fputs(p->name,fp);putchar(10);

              putc(p->type,fp);putchar(10);

              fprintf(fp,"%5lf\n",p->balance);

              p=p->next;

       }

       fclose(fp);

}

void add(CARD *head,char ID[])

{

       CARD *p;

       p=findID(head,ID);

       p->balance+=50;   

}

int main()

{

       CARD *head,*p;

       int i=0;

       char ID[9];

       printf("input linknode number:\n");

       scanf("%d",&i);

       head=CreatLink(i);

       output_sreen(head);

       printf("input add ID:\n");getchar();

       gets(ID);

       p=findID(head,ID);

       putnode(p);

       printf("add:\n");

       add(head,ID);

       putnode(p);

       printf("input find ID:\n");getchar();

       gets(ID);

       p=findID(head,ID);

       printf("result :\n");

       putnode(p);

       printf("input Delete ID:\n");getchar();

       gets(ID);

       p=findID(head,ID);

       putnode(p);

       deltID(head,ID);

       output_sreen(head);

       output_file(head);

       return 0;

}

实验总结:

这次试验我想应该是考察我们知识的综合运用能力,这次试验是四节连上的,而这个程序我用了三节课来写,但还不是很完善,有一些特殊情况程序还不能正确处理,只是大体满足要求。今后应该多练习编写较为复杂的程序来提高编程能力,特别是编程速速。

相关推荐