C杂讲 结构体与指针

目录

知识点1【结构体指针】

 知识点2【结构体指针作为函数的参数】

 知识点3【结构体成员指针】


知识点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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值