目录
知识点1【结构体指针】
案例:结构体指针
#include<stdio.h>
typedef struct
{
int num;
char name[16];
int age;
}STU;
//STU 是结构体类型
void test01()
{
STU lucy={100,"lucy",18};
STU *p = &lucy;
printf("num = %d, name=%s, age=%d\n",lucy.num, lucy.name, lucy.age);
printf("num = %d, name=%s, age=%d\n",(*p).num, (*p).name, (*p).age);
printf("num = %d, name=%s, age=%d\n",p->num, p->name, p->age);
printf("num = %d\n", (&lucy)->num );
return;
}
案例:从堆区给结构体申请一个空间
void test02()
{
STU *p = NULL;
//从堆区申请结构体空间
p = (STU *)calloc(1,sizeof(STU));
if(NULL == p)
{
perror("calloc");
return;
}
//获取键盘输入
printf("请输入一个学生的信息num name age\n");
scanf("%d %s %d", &p->num, p->name, &p->age);
//遍历
printf("num = %d, name=%s, age=%d\n",p->num, p->name, p->age);
//释放空间
if(p != NULL)
{
free(p);
p=NULL;
}
return;
}
运行结果:
知识点2【结构体指针作为函数的参数】
void mySetSTUData(STU *p)//p=&lucy
{
printf("请输入一个学生的信息num name age\n");
scanf("%d %s %d", &p->num, p->name, &p->age);
return;
}
void myPrintSTUData(const STU *p)//p =&lucy *p只读
{
//const STU *p 不允许用户借助 p修改 p所指向空间的内容
// p->num = 10000;
printf("sizeof(p)=%d\n", sizeof(p));
printf("num = %d, name=%s, age=%d\n",p->num, p->name, p->age);
}
void test03()
{
STU lucy;
memset(&lucy,0,sizeof(lucy));
//定义一个函数 给lucy的成员获取键盘输入
mySetSTUData(&lucy);
//定义一个函数 打印lucy的成员信息
myPrintSTUData(&lucy);
}
运行结果:
案例:从堆区申请申请一个结构体数组 分函数 实现
STU * get_array_addr(int n)
{
return (STU *)calloc(n,sizeof(STU));
}
//arr代表的是空间首元素地址
void my_input_stu_array(STU *arr, int n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("请输入第%d个学生的信息\n",i+1);
//scanf("%d %s %d", &arr[i].num, arr[i].name, &arr[i].age);
scanf("%d %s %d", &(arr+i)->num , (arr+i)->name, &(arr+i)->age);
}
}
void my_print_stu_array(const STU *arr, int n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("num=%d, name=%s, age=%d\n", \
(arr+i)->num, (arr+i)->name,(arr+i)->age);
}
return;
}
void test04()
{
int n = 0;
STU *arr=NULL;
printf("请输入学生的个数:");
scanf("%d", &n);
//根据学生的个数 从堆区 申请空间
arr = get_array_addr(n);
if(arr == NULL)
{
perror("get_array_addr");
return;
}
//从键盘 给结构体数组arr输入数据
my_input_stu_array(arr, n);
//遍历结构体数组
my_print_stu_array(arr, n);
//释放空间
if(arr != NULL)
{
free(arr);
arr=NULL;
}
}
运行结果:
知识点3【结构体成员指针】
typedef struct hero
{
char *name;//成员指针
int def;
int atk;
}HERO;//HERO是类型名
1、结构体变量在栈区、全局区 成员指针 指向了文字常量区
typedef struct
{
char *name;
int def;
int atk;
}HERO2;//HERO2是类型名
void test02()
{
printf("%d\n", sizeof(HERO2));
HERO2 hero;
hero.name = "德玛西亚";
hero.def = 80;
hero.atk = 100;
hero.name[2]='h';//操作文字常量区 出现段错误
printf("%s %d %d\n", hero.name, hero.def, hero.atk);
}
2、结构体变量在栈区、全局区 成员指针 指向了堆区
#include <string.h>
#include <stdlib.h>
void test03()
{
HERO2 hero;
hero.name = (char *)calloc(1, 16);
if(hero.name == NULL)
{
perror("calloc");
return;
}
strcpy(hero.name, "德玛西亚");
hero.def = 80;
hero.atk = 100;
printf("%s %d %d\n", hero.name, hero.def, hero.atk);
if(hero.name != NULL)
{
free(hero.name);
hero.name = NULL;
}
}
3、结构体空间在堆区 成员指针 指向了堆区
void test04()
{
HERO2 *p = NULL;
//为结构体指针变量p申请结构体空间
p = (HERO2 *)calloc(1,sizeof(HERO2));
if(p == NULL)
{
perror("calloc");
return;
}
p->def = 80;
p->atk = 100;
//为p->name指针成员 申请指向的空间
p->name = (char *)calloc(1, 16);
if(p->name == NULL)
{
perror("calloc");
return;
}
strcpy(p->name, "德玛西亚");
printf("%s %d %d\n", p->name, p->def, p->atk);
//释放成员指向的空间
if(p->name != NULL)
{
free(p->name);
p->name = NULL;
}
//释放结构体的空间
if(p != NULL)
{
free(p);
p = NULL;
}
}
4、结构体指针数组空间在堆区 结构体数组元素在堆区 成员指针 指向了堆区
typedef struct
{
char *name;
int def;
int atk;
}HERO2;//HERO2是类型名
void test05()
{
int n = 0;
printf("请输入结构体指针数组的元素个数:");
scanf("%d", &n);
//p_arr保存堆区空间的结构体指针数组的首元素地址
HERO2 **p_arr = NULL;
p_arr = (HERO2 **)calloc(n,sizeof(HERO2 *));
if(NULL == p_arr)
{
perror("calloc");
return;
}
//给结构体指针数组的每个元素的指向 申请空间
int i = 0;
for ( i = 0; i < n; i++)
{
p_arr[i] = (HERO2 *)calloc(1,sizeof(HERO2));
if(NULL == p_arr[i])
{
perror("calloc");
return;
}
printf("请输入第%d个英雄的信息:", i+1);
char name[128]="";
int def;
int atk;
scanf("%s %d %d", name, &def, &atk);
p_arr[i]->def = def;
p_arr[i]->atk = atk;
//给结构体空间中的成员 申请指向
p_arr[i]->name = (char *)calloc(1, strlen(name)+1);
if(NULL == p_arr[i]->name)
{
perror("calloc");
return;
}
strcpy(p_arr[i]->name, name);
}
//遍历
for ( i = 0; i < n; i++)
{
printf("%s %d %d\n", \
p_arr[i]->name, p_arr[i]->def, p_arr[i]->atk);
}
//释放空间
for ( i = 0; i < n; i++)
{
//释放结构体空间中的name的指向
if(p_arr[i]->name != NULL)
{
free(p_arr[i]->name);
p_arr[i]->name = NULL;
}
//释放结构体的空间
if(p_arr[i] != NULL)
{
free(p_arr[i]);
p_arr[i] =NULL;
}
}
//释放整个结构体指针数组的空间
if(p_arr != NULL)
{
free(p_arr);
p_arr = NULL;
}
return;
}
int main(int argc, char const *argv[])
{
test05();
return 0;
}