七叶笔记 » golang编程 » 结构体的对齐方式以及结构体嵌套指针的使用方法

结构体的对齐方式以及结构体嵌套指针的使用方法

结构体数组

定义结构体数组的方法很简单,同定义结构体变量是一样的,只不过将变量改成数组。或者说同前面介绍的普通数组的定义是一模一样的,如:

 struct STUDENT stu[10];  

这就定义了一个结构体数组,共有 10 个元素,每个元素都是一个结构体变量,都包含所有的结构体成员。

 #define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

typedef struct Teacher
{
    char name[50];
    //char* name;
    int age;
}Teacher;
int main()
{
    Teacher  a[3] = { 
        {"a",11},
        {"b",12},
        {"c",13} 
    };
    //静态
    Teacher a2[3] = { "aa",13,"bb",12 ,"cc",13};
    for (int i = 0; i < 3; i++)
    {
        printf("%s, %d\n", a2[i].name, a2[i].age);
    }
    int b[3] = { 0 };
    int* pB = (int*)malloc(3 * sizeof(int));
    free(pB);
    //Teacher p[3]
    Teacher* p = (Teacher*)malloc(3 * sizeof(Teacher));
    if (p==NULL)
    {
        return -1;
    }
    char buf[50];
    for (int i = 0; i < 3; i++)
    {
        sprintf(buf, "name%d%d%d", i, i, i);
        strcpy(p[i].name, buf);
        p[i].age = 20 + i;
    }
    for (int i = 0; i < 3; i++)
    {
        printf("第%d个:%s,%d\n", i + 1, p[i].name, p[i].age);
    }
    printf("\n");

    if (p!=NULL)
    {
        free(p);
        p = NULL;
    }
    return 0;
}  

结构体嵌套一级指针

 #define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>



typedef struct Teacher
{
    char* name;
    int age;
}Teacher;

showTeacher(Teacher* q, int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("%s ,%d\n", q[i].name, q[i].age);
    }
}

freeTeacher(Teacher* q, int n)
{
    for (int i = 0; i < n; i++)
    {
        if (q[i].name != NULL)
        {
            free(q[i].name);
            q[i].name = NULL;
        }
    }

    if (q != NULL)
    {
        free(q);
        q = NULL;
    }
}

Teacher* getMem( int n)
{ 
    Teacher*q = (Teacher*)malloc(sizeof(Teacher));
    //Teacher q[3]
    char buf[30];
    for (int i = 0; i < n; i++)
    {
        q[i].name = (char*)malloc(30);
        sprintf(buf, "name%d%d%d", i, i, i);
        strcpy(q[i].name, buf);

        q[i].age = 20 + i;
    }
    return q;
}
Teacher* getMem2(Teacher**temp,int n)
{
    if (temp==NULL)
    {
        return -1;
    }
    Teacher* q = (Teacher*)malloc(sizeof(Teacher));
    //Teacher q[3]
    char buf[30];
    for (int i = 0; i < n; i++)
    {
        q[i].name = (char*)malloc(30);
        sprintf(buf, "name%d%d%d", i, i, i);
        strcpy(q[i].name, buf);

        q[i].age = 20 + i;
    }
    *temp = q;
    return 0;
}
int main()
{
    char* name = NULL;
    name = (char*)malloc(30);
    strcpy(name, "aa");
    printf("name=%s\n", name);
    if (name!=NULL)
    {
        free(name);
        name = NULL;
    }

    //1
    Teacher t;
    t.name = (char*)malloc(30);
    strcpy(t.name, "s");
    t.age = 22;
    printf("name=%s  age=%d\n", t.name, t.age);
    if (t.name!=NULL)
    {
        free(t.name);
        t.name = NULL;
    }

    //2
    Teacher* p = NULL;
    p = (Teacher*)malloc(sizeof(Teacher));
    p->name = (char*)malloc(30);
    strcpy(p->name, "ss");
    p->age = 22;
    printf("name=%s  age=%d\n", p->name, p->age);

    if (p->name!=NULL)
    {
        free(p->name);
        p->name = NULL;
    }
    if (p!=NULL)
    {
        free(p);
        p = NULL;
    }
  
    //3
    Teacher* q = NULL;
    //q = getMem(3);
    int ret = 0;
    ret = getMem2(&q, 3);
    if (ret!=NULL)
    {
        return ret;
    }
    showTeacher(q,3);
    freeTeacher(q, 3);
    p = NULL;
    return 0;
}  

结构体嵌套二级指针

 #define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

//一个导师有若干学生
typedef struct Teacher
{
    int age;
    char**stu;//二维内存
}Teacher;

//n1老师个数  n2每个老师带的学生数
int createTeacher(Teacher** temp, int n1,int n2)
{
    if (temp==NULL)
    {
        return -1;
    }

   Teacher* q = (Teacher*)malloc(sizeof(Teacher) * n1);
    //Teacher q[3]
    for (int i = 0; i < n1; i++)
    {
        //q[i].stu
            //(q+i)->stu
        q[i].stu = (char**)malloc(sizeof(char*)*n2);
        //char* stu[3]
        for (int j = 0; j < n2; j++)
        {
            q[i].stu[j] = (char*)malloc(30);
            char buf[30];
            sprintf(buf, "name%d%d%d%d", i, i, j, j);
            strcpy(q[i].stu[j], buf);
        }
        q[i].age = 20 + i;
    }
    
    *temp = q;
    return 0;
}

void showTeacher(Teacher* q, int n1, int n2)
{
    if (q=NULL)
    {
        return;
    }

    for (int i = 0; i < n1; i++)
    {
        printf("[age=%d]\t", q[i].age);
        for (int j = 0; j < n2; j++)
        {
            printf("%s, \n", q[i].stu[j]);
        }
        printf("\n");
    }
    printf("\n");
}

void sortTeacher(Teacher*p,int n)
{
    if (p==NULL)
    {
        return;
    }
    Teacher temp;
    for (int i = 0; i < n-1; i++)
    {
        for (int j = i+1; j < n; j++)
        {
if (p[i].age < p[j].age)//降序
            {
                temp = p[i];
                p[i] = p[j];
                p[j] = temp;
            }
        }
    }

}

void freeTeacher(Teacher** temp, int n1, int n2)
{
    if (temp==NULL)
    {
        return;
    }
    Teacher* q = *temp;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            if (q[i].stu[j] != NULL)
            {
                free(q[i].stu[j]);
                q[i].stu[j] = NULL;
            }
        }
        if (q[i].stu != NULL)
        {
            free(q[i].stu);
            q[i].stu = NULL;
            *temp = NULL;
        }
    }


    if (q != NULL)
    {
        free(q);
        q = NULL;
    }
}

int main()
{

    char** name = NULL;
    //char* name[3]
    int n = 3;
    name = (char**)malloc(sizeof(char*) * 3);
    for (int i = 0; i < n; i++)
    {
        name[i] = (char*)malloc(30);
        strcpy(name[i], "aaa");
    }
    for (int i = 0; i < n; i++)
    {
        printf("%s\n", name[i]);
    }

    for (int i = 0; i < n; i++)
    {
        if (name[i]!=NULL)
        {
            free(name[i]);
            name[i] = NULL;
        }
    }
    if (name!=NULL)
    {
        free(name);
        name = NULL;
    }


    //1
    Teacher t;
    //t.stu[3]

    //char* t.stu[3]
    int n = 3;
    t.stu = (char**)malloc(sizeof(char*) * 3);
    for (int i = 0; i < n; i++)
    {
        t.stu[i] = (char*)malloc(30);
        strcpy(t.stu, "aaa");
    }
    for (int i = 0; i < n; i++)
    {
        printf("%s\n",t.stu[i]);
    }

    for (int i = 0; i < n; i++)
    {
        if (t.stu[i] != NULL)
        {
            free(t.stu[i]);
            t.stu[i] = NULL;
        }
    }
    if (t.stu != NULL)
    {
        free(t.stu);
        t.stu = NULL;
    }


    //2
    Teacher* p = NULL;
    //p->stu[3]
    p = (Teacher*)malloc(sizeof(Teacher));

    //char* t.stu[3]
    int n = 3;
    p->stu = (char**)malloc(sizeof(char*) * 3);
    for (int i = 0; i < n; i++)
    {
        p->stu[i] = (char*)malloc(30);
        strcpy(p->stu, "aaa");
    }
    for (int i = 0; i < n; i++)
    {
        printf("%s\n", p->stu[i]);
    }

    for (int i = 0; i < n; i++)
    {
        if (p->stu[i] != NULL)
        {
            free(p->stu[i]);
            p->stu[i] = NULL;
        }
    }
    if (p->stu != NULL)
    {
        free(p->stu);
        p->stu = NULL;
    }

    if (p!=NULL)
    {
        free(p);
        p = NULL;
    }

    //3
    Teacher* q = NULL;
    int ret = 0;
    ret = createTeacher(&q, 3,3);
    //Teacher* q[3]
    //q[i].stu[3]
    printf("排序前\n");
    showTeacher(q, 3, 3);

    sortTeacher(q, 3);
    printf("排序后\n");
    showTeacher(q,3,3);

    freeTeacher(&q, 3, 3);
 
    return 0;
}
  

结构体的深拷贝与浅拷贝

 #define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>


typedef struct Teacher
{
    char* name;
    int age;
}Teacher;

//结构体中嵌套指针,而且动态分配空间
//同类型结构体变量赋值
//结构体成员指针变量指向同一块内存
int main()
{
    Teacher t1;
    t1.name = (char*)malloc(30);
    strcpy(t1.name, "tom");
    t1.age = 22;

    Teacher t2;
    t2 = t1;
    //深拷贝,人为增加内容,重新拷贝一下
    t2.name= (char*)malloc(30);
    strcpy(t2.name, t1.name);

    printf("[t2]%s,%d\n", t2.name, t2.age);

    if (t1.name!=NULL)
    {
        free(t1.name);
        t1.name = NULL;
    }
    //重复释放  
    //浅拷贝:t2的值还指向同一块内存 t1.name  t1释放后t2又释放 导致出现错误
    if (t2.name != NULL)
    {
        free(t2.name);
        t2.name = NULL;
    }
    return 0;
}
  

结构体的对齐方式

结构体的对齐公式:

记住以下这些规则,把结构体往里面套就可以了。结构体对齐的原则就是牺牲空间的方式来减少时间的消耗,空间用完还可以复用,而时间过去了就再也不会回来了。

  • 以 #pragma pack(x) 中 x 的大小和结构中占用空间最大的成员做比较,取小值为 n(外对齐依据)
  • 以 n 值和结构体每个成员比较,得到结果列表为 m[x]
  • 根据每个成员的大小依次向内存中填充数据,要求填充 成员的起始地址 减去 构体起始地址 的差都可以整除 m[x] ,如不能整除则向后移动,直到可以整除再填充成员到内存(内对齐依据)
  • 当全部成员填充完毕后所占用的字节若不能整除 n,则扩充内存到可以整除 n 为止。

举个例子:

在这个例子中struct data的大小为8个字节。

相关文章