标签:pre ring 变量 -o 代码 malloc stand 完成后 释放
本篇是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: \n", 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:\t\t\t", ptrStu->name); }else{ if(strlen(ptrStu->name) < 8){ printf("The student %s‘s info:\t\t", ptrStu->name); }else{ printf("The student %s‘s info:\t", ptrStu->name); } } printf("name: %s\t", ptrStu->name); printf("id: %d\t", ptrStu->id); printf("record: %f\t", ptrStu->record); printf("sex: %c\n", 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)、其他的就是函数的调用,需要的变量需要提前创建,包括内存的申请等;
标签:pre ring 变量 -o 代码 malloc stand 完成后 释放
原文地址:http://www.cnblogs.com/guochaoxxl/p/7679759.html