zoukankan      html  css  js  c++  java
  • 必做作业: Linux C语言编程基础

    Linux C语言编程基础

    安装和配置OpenEuler

    使用前几天安装的OpenEuler完成了本次作业。安装OpenEuler的详细步骤可以参见我这一篇博客:https://www.cnblogs.com/Ressurection-20191320/p/15321497.html

    二叉树

    选择二叉树的相关知识和内容完成了本次作业。本次作业实现了二叉树的存储,以及二叉树的相关功能的实现。包括:

    1. 二叉树的数据结构和结构体实现
    2. 二叉树的先序、中序、后序遍历
    3. 队列的存储和二叉树的层序遍历

    练习过程

    项目目录的构建

    首先创建项目文件夹,然后创建项目内的各个文件夹。下图为创建过程和文件目录树:

    编写各模块

    头文件

    首先编写二叉树的数据结构存储和结构体定义的模块。
    写一个btree.h,放在include中,此为二叉树的头文件。
    btree.h:

    #ifndef __BTREE_H__
    #define __BTREE_H__
    
    typedef struct BinTreeNode
    {
        char data;
        struct BinTreeNode *Left;
        struct BinTreeNode *Right;
    } * BinTree;    //二叉树结构定义,数据类型是字符型
    
    BinTree CreateBinTree();
    void LevelOrder(BinTree t);//层序遍历
    void PreOrder(Bintree t);  //先序遍历
    void InOrder(Bintree t);   //中序遍历
    void PostOrder(Bintree t); //后序遍历
    
    #endif
    

    再写一个用于二叉树层序遍历的队列用的头文件
    queue.h:

    #ifndef __QUEUE_H__
    #define __QUEUE_H__
    
    
    typedef struct SeqQueue
    {
        int max;
        int f, r;
        BinTree *q;
    } * Queue;      //队列结构定义
    
    Queue CreatQueue(int m);//创建队列
    void AddQueue(Queue paqu, BinTree x);//将一个二叉树指针压入队列
    int IsEmptyQueue(Queue paqu);//判断队列是否为空
    BinTree DeleteQueue(Queue paqu);//从队尾删除并取出元素
    
    #endif
    

    模块

    编写各个模块实现不同的功能。
    模块很多,代码不一一列出。需要代码可在最后的码云链接找到。
    模块列表和功能:

    create_bin_tree.c创建一个二叉树并返回
    inorder.c二叉树的中序遍历
    levelorder.c二叉树的层序遍历
    postorder.c二叉树的后序遍历
    preorder.c二叉树的先序遍历
    queue.c队列基本操作(层序遍历时使用)

    gcc练习

    gcc的ESc和iso

    此练习使用一个简单的helloword程序。
    gcc -E 生成.i文件,是编译预处理后的结果,文件内容是预处理后的C代码。

    如执行完图中命令后,生成的.i文件就是包含了头文件后的C代码。
    gcc -S 生成.s文件,是进行汇编后得到的汇编语言,我们知道汇编语言是和机器语言有很强对应的底层语言。

    如图,就是生成的汇编程序。
    gcc -c 生成.o文件,.o文件时二进制文件,是经过编译后得到的机器码,人一般无法阅读。

    图为生成.o文件的gcc指令和部分.o文件内容。

    库练习

    生成.o文件:
    使用命令gcc src/*.c -Iinclude -o lib/*.o就可以生成对应.o并放在lib路径中(*应该替换为自己的文件名)
    静态库:
    将所有.o合成一个静态库,后面编译时就可以使用了,指令如下:
    ar rcs lib/libbintree.a lib/*.o注意后面跟随的.o文件可以是多个。
    动态库:
    动态库生成方式和静态库类似,但要求在生成.o的时候再gcc后加上-fPIC参数,目的是保证地址不与文件相关,才可以使用动态库。
    生成动态库的指令:
    gcc -shared -o lib/libbintree.so *.o
    练习截图就和makefile一起了。

    makefile的编写

    我的makefile

    o=lib/create_bin_tree.o lib/inorder.o lib/preorder.o lib/postorder.o lib/levelorder.o lib/queue.o
    
    OBJ:bin/test lib/libbintree.a lib/libbintree.so
    
    bin/test:test/test.c lib/libbintree.a
    	gcc test/test.c -static -Iinclude -Llib -lbintree -o bin/test
    lib/libbintree.a:$(o)
    	ar rcs lib/libbintree.a $(o)
    lib/libbintree.so:$(o)
    	gcc -shared -o lib/libbintree.so $(o)
    lib/create_bin_tree.o:src/create_bin_tree.c include/btree.h
    	gcc -c -fPIC -Iinclude src/create_bin_tree.c -o lib/create_bin_tree.o
    lib/inorder.o:src/inorder.c include/btree.h
    	gcc -c -fPIC -Iinclude src/inorder.c -o lib/inorder.o
    lib/preorder.o:src/preorder.c include/btree.h
    	gcc -c -fPIC -Iinclude src/preorder.c -o lib/preorder.o
    lib/postorder.o:src/postorder.c include/btree.h
    	gcc -c -fPIC -Iinclude src/postorder.c -o lib/postorder.o
    lib/levelorder.o:src/levelorder.c include/btree.h include/queue.h
    	gcc -c -fPIC -Iinclude src/levelorder.c -o lib/levelorder.o
    lib/queue.o:src/queue.c include/btree.h include/queue.h
    	gcc -c -fPIC -Iinclude src/queue.c -o lib/queue.o
    

    我对makefile的学习心得:

    makefile可以设置常量,如我makefile中的.o就是案例。在有时,生成库的时候会用到很多很多的.o文件,每次都输入非常麻烦,而且每次新加入.o文件后都要全部修改,非常不简洁。可以设置一个.o变量,把所有.o文件写在后面,每次使用的时候用$(o)进行调用,这样就方便多了。这体现了编写代码的“不要重复自己”原则。
    makefile原则上只以第一个文件为目标进行生成、编译,但如果需要同时生成多个文件怎么办?可以将第一个文件设置成一个类似“OBJ”的理想文件,实际上并没有这个文件,在OBJ后面再以它的依赖的形式写上每次需要生成的文件,make时就会自动生成这些文件了。

    make截图


    make后,所有文件都将被有序生成。

    文件目录tree截图

    功能测试

    编写了main函数,测试所有功能。
    test/test.c:

    #include"btree.h"
    #include"queue.h"
    #include<stdio.h>
    
    int main()
    {
        BinTree T;
        printf("请以先序,字符型(不加空格,空用"#"表示)输入二叉树:
    ");
        T = CreateBinTree();
        printf("以先序输出二叉树结果如下:
    ");
        PreOrder(T);
        printf("
    以中序输出二叉树结果如下:
    ");
        InOrder(T);
        printf("
    以后序输出二叉树结果如下:
    ");
        PostOrder(T);
        printf("
    以层序输出二叉树结果如下:
    ");
        LevelOrder(T);
        putchar('
    ');
        return 0;
    }
    

    测试用二叉树:

    测试结果:

    gdb练习

    4种断点:行断点、函数断点、条件断点、临时断点。
    调试时,需要在编译gcc时加入-g参数,才能生成调试信息,进行调试。

    CGDB调试界面:

    设置函数断点: b 函数名

    设置行断点:b 行号

    设置临时断点:tb 行号

    设置条件断点:break 行号 if 条件

    开始运行:run
    查看变量的值:disp 变量名
    单步执行(进入函数):s
    单步执行(不进入函数):n
    跳出函数:finish
    跳出循环:until

    代码链接

    代码已上传至码云:https://gitee.com/Ressurection20191320/code/tree/master/IS/20191320BinaryTree

  • 相关阅读:
    android 防止按钮连续点击的方法(Button,ImageButton等)
    android listview 异步加载图片并防止错位
    Smart3D系列教程6之 《案例实战演练3——倾斜数据正射影像及DSM的生产》
    Smart3D系列教程5之 《案例实战演练2——大区域的地形三维重建》
    Smart3D系列教程4之 《案例实战演练1——小物件的照片三维重建》
    Smart3D系列教程3之 《论照片三维重建中Smart3D几个工作模块的功能意义》
    Smart3D系列教程2之 《为什么三维重建效果这么差?——探探那些被忽略的拍照要求和技巧》
    Smart3D系列教程1之《浅谈无人机倾斜摄影建模的原理与方法》
    如何通过倾斜摄影数据手动配置s3c索引文件?
    无人机倾斜摄影三维展示应该如此简单
  • 原文地址:https://www.cnblogs.com/Ressurection-20191320/p/15334766.html
Copyright © 2011-2022 走看看