这几天把C语言巩固了一下,作为一门最基本的编程语言,C语言还是相当基础和非常重要的,个人认为C语言还是很有必要学好吃透的。
今天写的话题是结构体结构体中一级指针和二级指针的创建与释放,以一个例子来说明,笔者这里自己敲得代码,虽然用C语言几年了,但是有的东西还是会遗忘。笔者敲代码过程中也是有bug出现的,经过调试也找到了bug所在,不得不说,巩固也是很重要的。而结构体作为C语言一部分也是很重要的,指针作为C语言的半壁江山也保持着其重要地位。代码不是很长,但里面有很多细节的考虑,特别是一级指针和二级指针的内存的申请和释放。
代码的主要表达是:有三个老师,每个老师都有属性名字,年龄,别名,编号,以及有三个学生名字。老师名字(name)的内存分配是在栈区,别名(alisname)和学生名(stuname)的内存分配是在堆区。个人认为C语言的内存四区(栈区,堆区,全局区,代码区)很重要,所以喜欢从内存四区的角度看代码,对理解C语言的本质是重要,也是理解bug所在的重要原因。
下面是示例代码:
// 结构体 示例
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct Teacher // 定义一个结构体,名称为Teacher
{
char name[64];
int age;
char *alisname;//别名
char **stuname;
int id;
}Teacher;
int createTeacher(Teacher **pT, int num)
{
int i = 0;
int j = 0;
int ret = 0;
Teacher *tmp = NULL;
tmp = (Teacher *)malloc(num * sizeof(Teacher));
if (tmp == NULL)
{
ret = -1;
printf("malloc err: %d\n",ret);
return ret;
}
memset(tmp, 0, num * sizeof(Teacher));
for (i = 0; i < num; i++)
{
char **myp = NULL;
//先创建一级指针
tmp[i].alisname = (char *)malloc(60);
if ( tmp[i].alisname == NULL)
{
ret = -2;
printf("malloc tmp[i].alisname err: %d\n",ret);
return ret;
}
//再创建二级指针
myp = (char **)malloc(3 * sizeof(char *));
if (myp == NULL)
{
ret = -3;
return ret;
}
for (j = 0; j < 3; j++)
{
myp[j] = (char *)malloc(60);
if (myp[j] == NULL)
{
ret = -4;
return ret;
}
}
tmp[i].stuname = myp;
}
*pT = tmp;
return ret;
}
int printTeacherandStu(Teacher *p, int num)
{
int i = 0;
int j = 0;
int ret = 0;
Teacher *tmp = NULL;
if (p == NULL)
{
ret = -1;
printf("p is null : %d\n",ret);
return ret;
}
tmp = p;
for (i = 0; i < num; i++)
{
char **myp = NULL;
printf("teacher name: %s\n",tmp[i].name);
printf(" teacher alisname: %s\n",tmp[i].alisname);
printf(" student's name: ");
myp = tmp[i].stuname;
for (j = 0; j < 3; j++)
{
printf("%s ",myp[j]);
}
printf("\n");
}
return ret;
}
void FreeTeacher(Teacher *p, int num)
{
int i = 0;
int j = 0;
Teacher *tmp = NULL;
tmp = p;
for(i = 0; i < num; i++)
{
char **myp = NULL;
//先释放以及指针
if (tmp[i].alisname != NULL)
{
free(tmp[i].alisname);
}
//再释放二级指针
if (tmp[i].stuname != NULL)
{
myp = tmp[i].stuname;
for (j = 0; j < 3; j++)
{
if (myp[j] != NULL)
{
free(myp[j]);
}
}
free(myp);
tmp[i].stuname = NULL;
}
}
free(tmp);
}
int main()
{
int ret = 0;
int i = 0;
int j = 0;
int num = 3;
Teacher *pArray = NULL;
ret = createTeacher(&pArray, num);
if (ret != 0)
{
printf("func createTeacher() err: %d\n",ret);
return ret;
}
for (i = 0; i < num; i++)
{
printf("\nplease input teacher's name:");
scanf("%s",pArray[i].name);
printf("\n please input teacher's age:");
scanf("%d",&(pArray[i].age));
printf("\n please input teacher's alsname:");
scanf("%s",pArray[i].alisname);
for (j = 0; j < 3; j++)
{
printf("\n please input student name:");
scanf("%s",pArray[i].stuname[j]);
}
}
ret = printTeacherandStu(pArray, num);
if (ret != 0)
{
ret = -2;
printf("func printTeacherandStu() err: %d\n",ret);
return ret;
}
FreeTeacher(pArray, num);
return 0;
}
具体详细细节就不讨论了,不懂的可以问,下面是运行结果: