c的练习

为了熟悉一下c ,自己想了一个题目就试着做了起来,发现收获挺多的。

虽然是东拼西凑,整个程序没有很好的结构,所以优化的空间还很大,今天就总结总结这其中的收获。

题目是这样的。

现实的背景是,飞机航线会避开一些指定的区域那么就需要实时更新自己与那些区域的位置关系,

所以我抽象了一下。假设在一个坐标系中我输入 "禁飞区" 的坐标,并记载范围,最好有个记载位置关系的量

这里就用到了结构体

struct point_date
{
    int coor_x;
    int coor_y;
    int range;
    float dis;
}point [SIZE];

整个就是一个位置点的信系 储存在数组中。

文件操作

如果希望自己的数据能被保留下来就需要用到文件的读写,这样既能熟悉文件的用法,还能更好的体现实用性

在文件的操作中首先是写入通过结构体数组记录数据然后将数组数据记录到文件中这就是一个基本思路

    for (i=0;i<SIZE;i++)
    {
        scanf("%d%d%d",&point[i].coor_x,&point[i].coor_y,&point[i].range);
        record ();
    }    

写入数组

void record ()
{
    FILE*fp;
    int i;
    if ((fp=fopen ("point_date","wb"))==NULL)
    {
        printf ("cannot open file \n");
        return ;
    }
    for (i=0;i<SIZE;i++)
        if (fwrite(&point[i],sizeof(struct point_date),1,fp)!=1)
        {
            printf ("file write error \n");
        }
    fclose (fp);
}
    

写入到文件中这里还有点小小的不懂,不是很明白这个操作的含义标记一下明天来解决

记录到文件中了现在就需要把他读出来

void read ()
{
    FILE*fp;
    int i;

    for (i=0;i<SIZE;i++)
    {
        fread(&point[i],sizeof(struct point_date),1,fp);
        int temp,varout,varin;
        for (varout = 1;varout<SIZE;varout++)
        {
            temp = point[varout].coor_x;
            varin = varout - 1;
            while (varin >=0 && temp<point[varin].coor_x)
            {
                point[varin + 1].coor_x = point[varin].coor_x;
                varin--;
            }
            point[varin + 1].coor_x = temp;
        }
        printf ("x=%d  y=%d  rang=%d \n",point[i].coor_x,point[i].coor_y,point[i].range);
    }
}

标记的红色的那句知道作用但是还是缺乏深入的理解,这里不仅是读出来还实现了一个排序的功能,用的哈苏插入排序,后面有时间慢慢的

可以用一些其他的算法提高效率

排完序之后了可以先看一下主函数的逻辑

void main ()
{
    int i;
    int T_x,T_y,T_ran;

    printf ("input the point and range \n"); for (i=0;i<SIZE;i++)     //通过这个循环实现文件写入
    {
        scanf("%d%d%d", &point[i].coor_x,&point[i].coor_y,&point[i].range);
        record ();
    }
    read (); //读出刚才写入的数据并排序按x坐标的大小进行

    printf ("input the target point x y range\n");
    scanf ("%d%d%d",&T_x,&T_y,&T_ran);   //输入现在所处的位置

    float a[SIZE]; 

    for (i=0;i<SIZE;i++)
    {
        count_dis (T_x,T_y,point[i].coor_x,point[i].coor_y); //计算距离的函数 输入所处位置的想x,y的值和数组中每个点的x,y的值
        point[i].dis = count_dis (T_x,T_y,point[i].coor_x,point[i].coor_y);

        a[i] =  point[i].dis; //因为要排序所以把这个取出来方便操作

        printf ("the distance is %lf \n",a[i]);
    }
    range (a); //把距离从小到大排序

    for (i=0;i<SIZE;i++){
        printf (" \n");
        printf ("the distance is %lf \n",a[i]);
    }

}

其实看完main函数基本就结束了下面贴出排序和计算距离的函数

float count_dis (int T_x,int T_y,int x,int y)
{

    int dis,dx,dy;
    int px,py;
    double a;
    dx = T_x - x;
    dy = T_y - y;
    px = abs (dx);
    py = abs (dy);
    dis = px*px + py*py;
    a = sqrt (dis);
    return a;
}

void range (float a[])
{
    int i;
    double  temp;
    for (i=0;i<SIZE-1;i++){
        if (a[i]>=a[i+1]){

            temp = a[i] ;
            a[i] = a[i+1];
            a[i+1] = temp;
        }
    }
}

这里面涉及到比较实用的两个东西一个就是abs()这个函数,就是取绝对值。还有一个就是sqrt()也就是开方

至于排序,应该算是冒泡法就是大小交换位置,小的到最前面。

这基本上就完成了虽然不多但是自己效率不高,还是前前后后有一个多星期。

这个其实就是雏形,还有很多能优化的地方下面列举下,以后自己有能力时间可以试试

1.排序最近距离后输出最近三个点的名称,以及方位参考坐标系来说

2.出去一些重复的东西比如排序用了两次是否能独立开成一个函数

3.其中的数组可以换成链表来操作,提高了扩展性

当然也有一些疑问

1.当我从文件中读出来之后对数组结构体数组进行了重新排序,那文件中储存的内容是否会改变了

2.文件操作中fopen fwrite fclose的用法还不是很理解

3.最后距离的排序上有点小bug有时候并不是按从小到大来的····郁闷中

这又是1点了,今天看到一句话,觉得说的还挺有意思拿出来和大家分享一下

科学家工作到很晚。是因为白天碌碌无为,然后晚上心怀愧疚的做自己的事。

额这事儿到我这就是白天玩了,晚上发现事还没做完又熬夜干完........

意思挺多。。。大家可以多体会体会.

English version coming soon~~~~~

时间: 2024-10-22 16:12:11