linux实验5

本实验通过实际操作,详细介绍了在Linux环境下系统函数的应用,包括数学函数库的使用、随机数生成、时间与日期函数的处理、内存分配以及排序算法的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验五 Linux环境下系统函数的应用

学号:6130116217

专业班级:计算机科学与技术165班

课程名称:Linux程序设计实验

一、实验项目名称

Linux环境下系统函数的应用

二、实验目的

1.掌握数学函数库的使用
2.掌握随机数生成的方法
3.掌握时间与日期函数的使用
4.掌握内存分配函数的使用
5.掌握排序函数的使用

三、实验基本原理

Linux环境下的系统函数

四、主要仪器设备及耗材

硬件: PC机;
软件:Windows OS,VMware,Fedora10.0或其他Linux发行版。

五、实验步骤

1. 数学函数库

设计一个正余弦计算器,程序运行时,询问用户想计算正弦、余弦还是两者均需要计算,输入的是角度还是弧度?确定后,返回相关结果。
代码如下:

#include<stdio.h>
#include<math.h>
int n;
double k;
double pi=acos(-1.0);
int main()
{
    while(1)
    {
        printf("which do you want to calculate: \n");
        printf("1:sin \n");
        printf("2:cos \n");
        printf("3:sin and cos \n");
        printf("4:exit \n");
        scanf("%d",&n);

        switch(n)
        {
        case 1:
            printf("which do you want to input: \n");
            printf("1:angle \n");
            printf("2:radian \n");
            scanf("%d",&n);
            if(n==1)
            {
                printf("please input the angle: \n");
                scanf("%lf",&k);
                printf("sin(%lf)=%lf\n",k,sin(k/180*pi));
            }
            else if(n==2)
            {
                printf("please input the radian: \n");
                scanf("%lf",&k);
                printf("sin(%lf)=%lf\n",k,sin(k));
            }
            break;
        case 2:
printf("which do you want to input: \n");
            printf("1:angle \n");
            printf("2:radian \n");
            scanf("%d",&n);
            if(n==1)
            {
                printf("please input the angle: \n");
                scanf("%lf",&k);
                printf("cos(%lf)=%lf\n",k,cos(k/180*pi));
            }
            else if(n==2)
            {
                printf("please input the radian: \n");
                scanf("%lf",&k);
                printf("cos(%lf)=%lf\n",k,cos(k));
            }
            break;
        case 3:
            printf("which do you want to input: \n");
            printf("1:angle \n");
            printf("2:radian \n");
            scanf("%d",&n);
            if(n==1)
            {
                printf("please input the angle: \n");
                scanf("%lf",&k);
                printf("sin(%lf)=%lf\n",k,sin(k/180*pi));
                printf("cos(%lf)=%lf\n",k,cos(k/180*pi));
            }
            else if(n==2)
            {
                printf("please input the radian: \n");
                scanf("%lf",&k);
                printf("cos(%lf)=%lf\n",k,cos(k));
            }
            break;
        case 3:
            printf("which do you want to input: \n");
            printf("1:angle \n");
            printf("2:radian \n");
            scanf("%d",&n);
            if(n==1)
            {
                printf("please input the angle: \n");
                scanf("%lf",&k);
                printf("sin(%lf)=%lf\n",k,sin(k/180*pi));
                printf("cos(%lf)=%lf\n",k,cos(k/180*pi));
            }
            else if(n==2)
            {
                printf("please input the radian: \n");
                scanf("%lf",&k);
                printf("sin(%lf)=%lf\n",k,sin(k));
                printf("cos(%lf)=%lf\n",k,cos(k));
            }
            break;
        case 4:
            return 0;
        }
    }
    return 0;
}

编译
当使用gcc编译器编译含数学函数的C程序时,会出现undefined reference to `sin’错误.这种错误一般是由于缺少库造成的。-lm
在这里插入图片描述
执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 随机数生成方法

(1)编写一个猜数游戏程序,先产生一个1到1000之间的随机整数,要求用户输入一个数,程序提示猜大了、猜小了和恭喜你猜对了,直到猜中,退出程序。
vim 2.c

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

int n,k;
int main()
{
    srand((int)time(0));
    n=1+1000.0*rand()/(RAND_MAX+1.0);
   // printf("n=%d\n",n);
    k=-1;

    while(k!=n)
    {
        if(k!=-1)
        {
            if(k<n)
                printf("it is too small\n");
            else
                printf("it is too big\n");
        }
        printf("please input the number you guess:\n");
        scanf("%d",&k);
    }
    printf("the number is %d,congratulations on your correct answer",n);

    return 0;
}

编译
在这里插入图片描述
运行
在这里插入图片描述
(2)修改程序,限定猜数次数,则猜数过程中达到猜数次数还未猜中时,提示猜数失败而退出。
vim 22.c

#include<stdlib.h>

int n,k,count;
int main()
{
    srand((int)time(0));
    n=1+1000.0*rand()/(RAND_MAX+1.0);
    printf("n=%d\n",n);
    k=-1;

    while(k!=n)
    {
        if(k!=-1)
        {
            if(k<n)
                printf("it is too small\n");
            else
                printf("it is too big\n");
        }

        if(count++==5)
        {
            printf("sorry,you've run out of guesses and you failed.\n");
            break;
        }
        printf("number of attemtps: %d ,5 times altogether.\n",count);
        scanf("%d",&k);
    }

    if(count<=5)
        printf("the number is %d,congratulations on your correct answer\n",n);
    else
        printf("the number is %d,I'm sorry you failed.\n",n);

    return 0;
}

编译
在这里插入图片描述
运行
猜数成功
在这里插入图片描述
猜数失败
在这里插入图片描述

3. 时间与日期函数

(1)编写程序显示当前格林尼治时间以及北京时间
vim 3.c

#include <time.h>
int main()
{
    time_t timep; /* 时间结构体变量 */
    char *wday[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    struct tm *p;
    time (&timep); /*取得当前的时间*/

    printf("current GMT: \n");
    printf("%s\n",asctime(gmtime(&timep)));/*将时间和日期以字符串格式表示*/
    p=localtime(&timep); /*取得当地时间并按真实世界的时间日期来表示*/

    printf("current Beijing time: \n");
    printf ("%d-%d-%d ",(1900+p->tm_year), (1+p->tm_mon), p->tm_mday);
    printf("%s %d:%d:%d\n",wday[p->tm_wday],p->tm_hour,p->tm_min,p->tm_sec);

    return 0;
}

编译
在这里插入图片描述
运行
在这里插入图片描述
(2)调试课本例4.8

#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#include<unistd.h>
#ifdef __unix__
# include <unistd.h>
#elif defined _WIN32
# include <windows.h>
#define sleep(x) Sleep(1000 * (x))
#endif

int main()
{
    long int begin,sec,stop;
    struct timeval tv1, tv2;
    struct timezone tz;
    char tmp;
    begin=0;
    stop=0;
    sec=0;
    system("clear");
    printf("计时器程序(单位s)\n");

    printf("输入b(begin)计时器开始计时\n");
    printf("输入w(watch)查看已经累计时间\n");
    printf("输入r(rest)重新开始计时\n");
    printf("输入s(stop)暂停计时器\n");
    printf("输入e(end)结束计时器\n");
    while(1)
    {
        scanf("%c",&tmp);
        if(tmp=='b')
        {
            if(begin==1&&stop==0)
                printf("计时器已经启动!\n");
            if(begin==0&&stop==0)
            {
            printf("计时器启动\n");
                gettimeofday(&tv1,&tz);
                sec=0;
                begin=1;
            }
            if(stop==1)
            {
                gettimeofday(&tv1,&tz);
                stop=0;
                printf("暂停结束!\n");
            }
        }
        if(tmp=='w')
        {
            if(stop==0)
            {
                gettimeofday(&tv2,&tz);
                printf("已经计时%ld 秒\n",sec+tv2.tv_sec-tv1.tv_sec);
            }
            if(stop==1)
                printf("已经计时%ld 秒\n",sec);
        }
        if(tmp=='s')
        {
            if(stop==1)
            {
                printf("计时已经暂停!\n");
            }
            if(stop==0)
            {
                gettimeofday(&tv2,&tz);
                sec=sec+tv2.tv_sec-tv1.tv_sec;
                printf("计时暂停,已经计时%ld 秒\n",sec);
                stop=1;
            }
            }
        if(tmp=='r')
        {
            gettimeofday(&tv2,&tz);
            printf("已经计时%ld 秒\n",sec+tv2.tv_sec-tv1.tv_sec);
            printf("计时器在5 秒后被重置!\n");
            sleep(5);
            begin=0;
            sec=0;
            stop=0;
            system("clear");
            printf("计时器程序(单位s)\n");
            printf("输入b(begin)计时器开始计时\n");
            printf("输入w(watch)查看已经累计时间\n");
            printf("输入r(rest)重新开始计时\n");
            printf("输入s(stop)暂停计时器\n");
            printf("输入e(end)结束计时器\n");
        }
        if(tmp=='e')
            break;
    }
    return 0;
}

编译
在这里插入图片描述
运行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 内存分配

编写程序,动态申请一个数组,数组元素个数为10个,数组元素类型为int。程序运行时,提示用户输入10个数,接下来输出该数组的最大值与最小值。
注意:(1)比较malloc和calloc的区别
(2)在程序最后要释放动态申请的内存空间
答:malloc它允许从空间内存池中分配内存,malloc()的参数是一个指定所需字节数的整数.例如:P=(int*)malloc(nsizeof(int));colloc与malloc类似,但是主要的区别是存储在已分配的内存空间中的值默认为0,使用malloc时,已分配的内存中可以是任意的值.colloc需要两个参数,第一个是需要分配内存的变量的个数,第二个是每个变量的大小.
例如:P=(int
)colloc(n,colloc(int));

①使用malloc
#include<stdio.h>
#include<stdlib.h>

int *a;
int max=-0x3f3f3f3f;
int min=0x3f3f3f3f;

int main()
{

    a=(int *)malloc(sizeof(int)*10);
    printf("请输入10个整数\n");
    for(int i=0; i<10; ++i)
    {
        scanf("%d",&a[i]);
        if(a[i]>max)
            max=a[i];
        if(a[i]<min)
            min=a[i];
    }

    free(a);
    a=NULL;
    printf("最大值: %d\n",max);
    printf("最小: %d\n",min);

    return 0;
}

编译运行
在这里插入图片描述

②使用calloc
#include<stdio.h>
#include<stdlib.h>

int *a;
int max=-0x3f3f3f3f;
int min=0x3f3f3f3f;

int main()
{

    a=(int*)calloc(sizeof(int),10);
    printf("请输入10个整数\n");
    for(int i=0; i<10; ++i)
    {
        scanf("%d",&a[i]);
        if(a[i]>max)
            max=a[i];
        if(a[i]<min)
            min=a[i];
    }

    free(a);
    printf("最大值: %d\n",max);
    printf("最小: %d\n",min);

    return 0;
}

编译运行
在这里插入图片描述

5.排序算法

编写程序,从附加文件File1.txt中读数据,每一行为一个字符串,对所有字符串从小到大进行排序,排序结果保存到文件File1-result.txt中。要求:
(1)分别应用快速排序和冒泡排序算法进行排序,并且用getimeofday函数比较两个算法所需时间。
(2)比较不带缓存以及带缓存的文件读写方法

①不带缓存 快速排序

vim 5.c

//不带缓存      快速排序
#include<stdio.h>
#include<string.h>
#include<sys/time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>

int compare( char *version1, char *version2);
int part(char a[255][255],int left,int right);
void quicksort(char a[255][255],int left,int right);

char buf[255][255];
int count,p;
struct  timeval beg,end;
int fp;
char temp[10];

int main() {
        gettimeofday(&beg,NULL);

        if(     (fp = open("File1.txt",O_RDONLY))<0)  {
                printf("打开文件File1.txt出错");
                exit(0);
        }

        printf("排序前:\n");

        while (read(fp, temp, 1) >0) {
                buf[count][p]=temp[0];
                if(buf[count][p]!='\n') {
                        p++;
                } else {
                        printf("%s", buf[count]);
                        p=0;
                        count++;
                }
        }

        printf("单词个数: %d\n\n",count);
        close(fp);
        //快速排序
        quicksort(buf,0,count-1);

        if(     (fp = open("File1-result.txt",O_WRONLY))<0)  {
                printf("打开文件File1-result.txt出错");
                exit(0);
        }
        printf("排序后:\n");
        for(int i=0; i<count; i++) {
                printf("%s",buf[i]);
                p=0;
                while(buf[count][p]!='\0')
                        write(fp,&buf[count][p],1);
        }
        printf("单词个数: %d\n\n",count);
        close(fp);

        gettimeofday(&end,NULL);
        int us= 1000000 * (end.tv_sec-beg.tv_sec)+ end.tv_usec-beg.tv_usec;
        printf(" %d ms\n\n",us/1000);
}

int part(char a[255][255],int left,int right) {
        char temp[255];
        strcpy(temp,a[left]);
        while(left<right) {
                while(left<right&&compare(a[right],temp)>0)
                        right--;
                strcpy(a[left],a[right]);
                while(left<right&&compare(a[left],temp)<=0)
                        left++;
                strcpy(a[right],a[left]);
        }
        strcpy(a[left],temp);
        return left;
}
void quicksort(char a[255][255],int left,int right) {
        if(left<right) {
                int pos=part(a,left,right);
                quicksort(a,left,pos-1);
                quicksort(a,pos+1,right);
        }
}

int compare( char *version1, char *version2) {
        char* ver1 = version1;
        char* ver2 = version2;

        //入参判断
        if(NULL == ver1 || NULL == ver2) {
                if (NULL != ver1) {
                        return -3;
                }
                if (NULL != ver2) {
                        return -2;
                }
                return -1;
        }

        while ((*ver1 != '\0') && !(*(ver1) - *(ver2))) {
        ver1++, ver2++;
        }
        if (*(ver1) == '\0' && *(ver2) == '\0') {
                return 0;
        } else {
                if (*(ver1)-*(ver2)>0) {
                        return 1;
                } else {
                        return -1;
                }
        }
}

编译
在这里插入图片描述
运行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

②带缓存 冒泡排序

vim 55.c

//带缓存        冒泡
#include<stdio.h>
#include<string.h>
#include<sys/time.h>
#include<unistd.h>
#include<stdlib.h>

int compare( char *version1, char *version2);
char buf[255][255];
int count;
struct  timeval beg,end;
FILE *fp;

int main() {
        gettimeofday(&beg,NULL);

        if(     (fp = fopen("File1.txt","r+"))==NULL)  {
                printf("打开文件File1.txt出错");
                exit(0);
        }


        printf("排序前:\n");
        while(!feof(fp)) {
                fgets(buf[count],255,fp);
                printf("%s",buf[count++]);
        }
        printf("单词个数: %d\n\n",count-1);
        fclose(fp);
        //冒泡排序
        for(int i=0; i<count-1; ++i) {
                for(int j=count-1; j>=i+1; --j) {
                        if(compare(buf[j-1],buf[j])>0) {
                                char temp[255];
                                strcpy(temp,buf[j]);
                                strcpy(buf[j],buf[j-1]);
                                strcpy(buf[j-1],temp);
                    }
                }
        }

        //fp = fopen("G:\\大三下\\linux\\实验\\Linux程序设计实验5\\Linux程序设计实验5\\File1-result.txt","w+");
        if(     (fp = fopen("File1-result.txt","w+"))==NULL)  {
                printf("打开文件File1-result.txt出错");
                exit(0);
        }
        printf("排序后:\n");
        for(int i=0; i<count; i++) {
                printf("%s",buf[i]);
                fputs(buf[i],fp);
        }
        printf("单词个数: %d\n\n",count-1);
        fclose(fp);

        gettimeofday(&end,NULL);
        int us= 1000000 * (end.tv_sec-beg.tv_sec)+ end.tv_usec-beg.tv_usec;
        printf(" %d ms\n\n",us/1000);
}

int compare( char *version1, char *version2) {
        char* ver1 = version1;
        char* ver2 = version2;

        //入参判断
        if(NULL == ver1 || NULL == ver2) {
                if (NULL != ver1) {
                        return -3;
                }
                if (NULL != ver2) {
                        return -2;
                }        
                return -1;
        }

        while ((*ver1 != '\0') && !(*(ver1) - *(ver2))) {
                ver1++, ver2++;
        }
        if (*(ver1) == '\0' && *(ver2) == '\0') {
                return 0;
        } else {
                if (*(ver1)-*(ver2)>0) {
                        return 1;
                } else {
                        return -1;
                }
        }
}    

编译
在这里插入图片描述
运行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、实验数据及处理结果

七、思考讨论题

(1)使用数学库函数时,gcc编译需要注意问题?
答:c语言中包含math.h时,用gcc编译时要-lm参数。
(2)除了使用gettimeofday测试程序运行时间,还有什么方法可以测试程序运行时间,这些方法的优缺点有哪些?
答:其他方法如下:
1.GetTickCount() 
2.Clock()
3.Timer()
gettimeofday可以精确到微秒,这些方法没有gettimeofday精确。

八、参考资料

1.金国庆等,Linux程序设计(第二版),浙江大学出版社,2014年4月
2. Neil Matthew,《Linux程序设计》(第4版), 人民邮电出版社,2014年9月
3. 杨宗德,《Linux高级程序设计》(第三版),人民邮电出版社,2012年11月
4. Daniel P.,《深入理解Linux内核》(第三版),中国电力出版社,2013年1月

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值