C语言 指针数组、数组指针、结构体(深浅拷贝问题)、结构体嵌套(一二级指针)

C语言 指针数组、数组指针、结构体(深浅拷贝问题)、结构体嵌套(一二级指针),第1张

C语言 指针数组数组指针、结构体(深浅拷贝问题)、结构体嵌套(一二级指针)

文章目录

1、数组指针2、指针数组3、结构体深浅拷贝4、结构体嵌套一级指针5、结构体嵌套二级指针

1、数组指针
三种定义方式:

1、
	int arr[5] = {1,2,3,4,5};
	// 定义一个ARRAY_TYPE类型
	typedef int (ARRAY_TYPE)[5];
	ARRAY_TYPE* arrp = &arr;
	for(int i=0;i<5;i++)
	{
	    printf("%dn",(*arrp)[i]);
	}

2、
	int arr[5] = {1,2,3,4,5};
	// 定义一个ARRAY_TYPE*类型
	typedef int (*ARRAY_TYPE)[5];
	ARRAY_TYPE arrp = &arr;
	for(int i=0;i<5;i++)
	{
	    printf("%dn",(*arrp)[i]);
	}

3、
	int (*pp)[5] = &arr;
	for(int i=0;i<5;i++)
	{
	    printf("%dn",(*pp)[i]);
	}

除了两种特殊情况外,二维数组名称是,指向第一个数组,数组指针
特殊情况1,sizeof
特殊情况2 对数组名取地址&arr
int arr[3][3] = {1,2,3,4,5,6,7,8,9};
int (*parry)[3] = arr;
printf("%dn",parry[1][2]);
printf("%dn",*(*(parry+1)+2));

2、指针数组

对指针数组进行选择排序,指针数组:实则数组,每一个元素都是一个指针变量

void test03()
{
    // 对指针数组进行排序
    char* pArray[4] = {"aaa","fff","ccc","ddd"};
    for(int i=0;i<4;i++)
    {
        int n = i;
        for(int j=i+1;j<4;j++)
         {
            if(strcmp(pArray[n],pArray[j])<0)
            {
                n = j;
            }
        }
        if(n!=i)
        {
            char* tmp = pArray[i];
            pArray[i] = pArray[n];
            pArray[n] = tmp;
        }
    }
    
    for(int i=0;i<4;i++)
    {
        printf("%sn",pArray[i]);
    }
}
3、结构体深浅拷贝
浅拷贝:
	free(p1.name);
    free(p2.name);
    释放空间时会出问题,出现同一块内存多次释放,因为=是将结构体变量p1逐字节拷贝给p2,
    又因为结构体中的成员变量name是在堆上开辟的空间,所以p1和p2中的name共用一块内存,

解决问题:
	深拷贝:给p2中的name开辟新的空间,然后将数据拷贝进去
void test05()
{
    // 深拷贝,浅拷贝
    struct Person1
    {
        char* name;
        int age;
    };
    
    struct Person1 p1;
    p1.name = (char*)malloc(128);
    strcpy(p1.name,"p1xxxx");
    p1.age = 18;  

    struct Person1 p2;
	p2 = p1;	// 浅拷贝做法
	
	p2.name = (char*)malloc(strlen(p1.name)+1);
	strcpy(p2.name,p1.name);
	p2.age = p1.age;
	
	printf("p1的姓名:%s 年龄:%dn",p1.name,p1.age);
    printf("p1的姓名:%s 年龄:%dn",p2.name,p2.age);
    free(p1.name);
    free(p2.name);
}
4、结构体嵌套一级指针
开辟内存:
	1、先开辟一块每个内容都是结构体指针变量的数组,数组中有三个变量
	2、通过循环将数组中的每个元素进行初始化,因为是结构体指针变量,所以需要手动开辟
	3、然后开辟,数组中每个元素的成员变量name,并初始化

释放内存:
	1、通过循环先释放数组中每个元素的成员变量name
	2、然后逐步释放数组中的每个元素
	3、是否这个结构体数组
struct person
{
    char* name;
    int age;
};

struct person** allocateSpace()
{
    struct person** temp = (struct person**)malloc(sizeof(struct person*)*3);

    for(int i=0;i<3;i++)
    {
        // 创建结构体内存
        temp[i] = (struct person*)malloc(sizeof(struct person));

        // 将结构体姓名,创建在堆上
        temp[i]->name = (char*)malloc(sizeof(char*)*64);
        sprintf(temp[i]->name,"name%d",i+1);
        temp[i]->age = i+10;
    }

    return temp;
}

void printf_person(struct person** p)
{
    for(int i=0;i<3;i++)
    {
        printf("%d %sn",p[i]->age,p[i]->name);
    }
}

void free_person(struct person*** p)
{
    if(p==NULL)
        return;
    for(int i=0;i<3;i++)
    {
        free((*p)[i]->name);
        
        (*p)[i]->name = NULL;
        free((*p)[i]);
        (*p)[i] = NULL;
    }
    free(*p);
    *p = NULL;
}

void test06()
{
    struct person** pArray = NULL;
    pArray = allocateSpace();
    printf_person(pArray);
    free_person(&pArray);
    if(pArray!=NULL)
    {
        printf("不等于空n");
    }
    else
    {
        printf("等于空n");
    }
}
5、结构体嵌套二级指针
// 结构体嵌套二级指针
struct Teacher
{
    char* name;
    char** students;
};

struct Teacher** TeacherSpace()
{
    struct Teacher** temp = (struct Teacher**)malloc(sizeof(struct Teacher*)*3);
    for(int i=0;i<3;i++)
    {
        temp[i] = (struct Teacher*)malloc(sizeof(struct Teacher));

        temp[i]->name = (char*)malloc(sizeof(char)*64);
        sprintf(temp[i]->name,"Teacher%d",i);

        temp[i]->students = (char**)malloc(sizeof(char*)*3);
        for(int j=0;j<3;j++)
        {
            temp[i]->students[j] = (char*)malloc(sizeof(char)*64);
            sprintf(temp[i]->students[j],"students%d",j);
        }
    }
    return temp;
}

void printfTeacher(struct Teacher** p)
{
    for(int i=0;i<3;i++)
    {
        printf("%sn",p[i]->name);
        for(int j=0;j<3;j++)
        {
            printf("    %d--%sn",i,p[i]->students[j]);
        }
    }
}

void freeTeacher(struct Teacher*** p)
{
    if(p==NULL)
        return;
    for(int i=0;i<3;i++)
    {
        free((*p)[i]->name);
        (*p)[i]->name = NULL;
        
        for(int j=0;j<3;j++)
        {
            free((*p)[i]->students[j]);
            (*p)[i]->students[j] = NULL;
        }
        free((*p)[i]->students);
        (*p)[i]->students = NULL;

        free((*p)[i]);
        (*p)[i] = NULL;
    }
    free(*p);
    *p = NULL;
}

void test07()
{
    struct Teacher** pArray = NULL;
    pArray = TeacherSpace();
    printfTeacher(pArray);   
    freeTeacher(&pArray);
    if(pArray==NULL)
    {
        printf("为空n");
    }
    else
    {
        printf("不为空n");
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5713432.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存