zoukankan      html  css  js  c++  java
  • 模块化编程实例(一)

       本篇是2017年10月14日《含有指针变量的结构体的指针的应用》中的另外一种实现,模块化编程更容易编写:

      首先定义头文件:stuG.h,头文件中一般包括程序中使用的数据结构,数据类型和函数声明等:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 
     5 #ifndef stuG_h
     6 #define stuG_h
     7 
     8 typedef struct _student{
     9     char *name;
    10     short id;
    11     double record;
    12     char sex;
    13 } Student;
    14 
    15 Student *initStudent(int);
    16 void deleteStudent(Student *);
    17 void displayStudent(Student *);
    18 
    19 #endif

      代码说明(一般需要在头文件中加上适当的注释,主要说明函数的用途,函数的参数含义及函数的返回值的说明等):

        (1)、结构体的使用类型定义的方式定义,后期可以直接使用Student定义结构体变量;

        (2)、函数声明中可以不指定形参的名称,必须指定形参的顺序和类型;

      接着,将头文件中定义的函数实现,实现文件主要将前述头文件的函数声明予以实现:

    #include "stuG.h"
    
    Student *initStudent(int i){
        Student *ptrStu = (Student *)malloc(sizeof(Student));
        ptrStu->name = (char *)malloc(sizeof(char) * 20);
        printf("Input the %d'th student info: 
    ", i + 1);
        printf("name: ");
        scanf("%s", ptrStu->name);
        printf("id: ");
        scanf("%d", &ptrStu->id);
        printf("record: ");
        scanf("%lf", &ptrStu->record);
        int tmp = getchar();
        printf("sex: ");
        scanf("%c", &ptrStu->sex);
    
        return ptrStu;
    }
    
    void deleteStudent(Student *ptrStu){
        free(ptrStu->name);
        free(ptrStu);
    
        return;
    }
    
    void displayStudent(Student *ptrStu){
        if(strlen(ptrStu->name) < 4){
            printf("The student %s's info:			", ptrStu->name);
        }else{
            if(strlen(ptrStu->name) < 8){
                printf("The student %s's info:		", ptrStu->name);
            }else{
                printf("The student %s's info:	", ptrStu->name);
            }
        }
        printf("name: %s	", ptrStu->name);
        printf("id: %d	", ptrStu->id);
        printf("record: %f	", ptrStu->record);
        printf("sex: %c
    ", ptrStu->sex);
    
        return;
    }

      代码说明(下面的解释主要是为了说明各个函数的工作原理):

        (1)、函数实现时,必须将函数声明时缺失的形参补全;

        (2)、函数initStudent()主要是完成Student指针的初始化,为了使初始化更加灵活,本例中采用了让用户临时输入的方式;

        (3)、函数initStudent()代码scanf("%lf", &ptrStu->record);注意double类型的数据在scanf中的占位符是%lf,如果使用%f可能会有问题,请自行测试;

        (3)、函数initStudent()代码int tmp = getchar();注意这行代码主要是为了消除上一行代码输入完成后的回车操作,并无实际意义,如果没有此代码,请自行测试;

        (4)使用scanf()函数时,若输入的参数是char类型时,必须加上上边第(3)条说的处理方式,将回车动作,消除,否则char变量中只是存储了回车的字符值;

        (5)、函数initStudent()代码Student *ptrStu = (Student *)malloc(sizeof(Student)); ptrStu->name = (char *)malloc(sizeof(char) * 20);申请了两次内存,并且必须先申请大块的内存ptrStud的内存,然后在ptrStu中申请name的内存,顺序不能错,否则逻辑意义会错;

        (6)、函数initStudent()中传入的参数,主要是为了让提示信息更加清晰明了,同时为了在测试函数中定义和使用结构体指针数组提供方便;

        (7)、函数initStudent()最后将初始化成功的Student指针返回即可;

        (8)、函数deleteStudent()传入结构体指针参数的目标非常明确,要释放内存,必须要有对象;

        (9)、函数deleteStudent()释放内存的顺序必须与创建内存的顺序相反的顺序释放内存即可;

        (10)、函数displayStudent()传入结构体指针与函数deleteStudent()的原理是一样的;

        (11)、实现文件必须包含头文件stuG.h,才能使用头文件中的数据结构和函数定义;

      最后,编写测试文件testc1.c:

    /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
      * 作者代号: *** :guochaoxxl
      * 版权声明: *** :(魎魍魅魑)GPL3
      * 联络信箱: *** :guochaoxxl@gmail.com
      * 文档用途: *** :深入理解C指针
      * 文档信息: *** :~/WORKM/StudyCode/cnblogs_understanding_and_using_c_pointers/chapter6/link/testc1.c
      * 修订时间: *** :2017年第42周 10月17日 星期二 上午06:03 (290天)
      * 代码说明: *** :演示模块化编程,包括头文件stuG.h和与其对应的实现文件stuG.c,
      * 编译方式需要将所有文件包括,gcc -g stuG.c testc1 -o testc1
     * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/
    
    #include "stuG.h"
    
    int main(int argc, char **argv)
    {
        int size;
        printf("please input a number: ");
        scanf("%d", &size);
        Student *arrStu[size];
        for(int i = 0; i < size; i++){
            arrStu[i] = initStudent(i);
        }
        for(int i = 0; i < size; i++){
            displayStudent(arrStu[i]);
        }
        for(int i = 0; i < size; i++){
            deleteStudent(arrStu[i]);
        }
    
        return 0;
    }

      代码说明(主要是实现前期头文件和实现文件的测试需求即可):

        (1)、文件testc1.c中代码int size;主要是为了让用户更加明确需要多少个数据;

        (2)、文件testc1.c中代码Student *arrStu[size]定义结构体指针数组,使用了刚才的size变量;

        (3)、在需要用户输入变量前,最好加上适当的提示信息;

        (4)、在文件中包含头文件stuG.h文件,由于不需要什么头文件,在此将主要头文件放置到stuG.h文件中,从而实现了曲线包含的效果;

        (5)、其他的就是函数的调用,需要的变量需要提前创建,包括内存的申请等;

  • 相关阅读:
    天梯赛5-12 愿天下有情人都是失散多年的兄妹 【dfs】
    poj2718 Smallest Difference【贪心】
    HDU problem 5635 LCP Array【思维】
    codeforces 782C Andryusha and Colored Balloons【构造】
    HDU 4278 Faulty Odometer【进制转换】
    codeforces B. The Meeting Place Cannot Be Changed【二分】
    POJ 3264 Balanced Lineup 【线段树】
    HDU 1850
    CodeForces-714C
    HDU Problem 1247 Hat's Words 【字典树】
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/7679759.html
Copyright © 2011-2022 走看看