C語言結構體嵌套與對齊超詳細講解

嵌套結構體

格式:
typedef struct 結構體名 {
struct 結構體名1 結構體變量名1;
struct 結構體名2 *結構體指針變量名1;
}結構體別名_t;

定義結構體普通的變量,訪問結構體中的成員:

結構體別名_t 普通結構體變量名;

普通結構體變量名.結構體變量名1.成員名;
普通結構體變量名.結構體指針變量名1->成員名;

定義結構體指針變量,訪問結構體中的成員

結構體別名_t *結構體指針變量名;

結構體指針變量名->結構體變量名1.成員名;
結構體指針變量名->結構體指針變量名1->成員名;

總結,訪問結構體中的成員時,具體使用.還是->,需要看當前的結構體變量的類型。

測試用例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Person
{
    char *name;
    int age;
    char sex;
} Person_t;
typedef struct Student
{
    Person_t per;
    int score;
} Student_t;
typedef struct Teacher
{
    Person_t *per_p;
    int salary;
} Teacher_t;
int main(int argc, const char *argv[])
{
    /*your code*/
    // 1. 定義結構體類型的變量
    Student_t stu1;
    // 2. 初始化結構體中的成員
    stu1.per.name = (char *)malloc(sizeof(char) * 20);
    if (stu1.per.name == NULL)
    {
        printf("malloc failed\n");
        return -1;
    }
    strcpy(stu1.per.name, "zhoukai");
    stu1.per.age = 18;
    stu1.per.sex = 'M';
    stu1.score = 99;
    printf("姓名:%s 年齡:%d 性別:%c 工資:%d\n",\
        stu1.per.name, stu1.per.age, stu1.per.sex, stu1.score);
    // 使用Teacher_t定義結構體指針類型的變量,使用malloc分配空間
    Teacher_t *t=(Teacher_t *)malloc(sizeof(Teacher_t));
    if(NULL==t)printf("malloc memory filed!\n");
    // 對Teacher_t類型中的per_p成員,使用malloc分配空間,
    t->per_p =(Person_t *)malloc(sizeof(Person_t));
    if(NULL==t->per_p)
    {
        printf("malloc memory filed!\n");
        return -1;
    }
    // 對Person_t中的name成員,使用malloc分配空間。
    t->per_p->name=(char *)malloc(sizeof(char)*20);
    if(NULL==t->per_p->name)
    {
        printf("malloc memory filed!\n");
        return -1;
    }
    // 分配堆區空間時,從外向內進行分配;釋放空間時,從內向外分配空間。
    strcpy(t->per_p->name,"yao");
    t->per_p->age=10;
    t->per_p->sex='M';
    t->salary=100000;
    printf("姓名:%s 年齡:%d 性別:%c 工資:%d\n",\
        t->per_p->name,t->per_p->age, t->per_p->sex,t->salary);
    //釋放空間
    free(t->per_p->name);
    t->per_p->name=NULL;
    free(t->per_p);
    t->per_p=NULL;
    free(t);
    t=NULL;
    return 0;
}

圖解:

結構體內存對齊

32位的操作系統

結構體中成員內存對齊,隻考慮基本的數據類型,不考慮構造類型,構造類型最終也是由基本類型構成。
1> 如果結構體中的成員最大的成員隻占1個字節的空間,則結構體類型的大小為1的整數倍;
2> 如果結構體中的成員最大的成員隻占2個字節的空間,則結構體類型的大小為2的整數倍;
3> 如果結構體中的成員最大的成員隻占4/8個字節的空間,則結構體類型的大小為4的整數倍;
結構體中的成員的地址:
1> 如果結構體中的成員為char類型,此成員的地址是1的整數倍;
2> 如果結構體中的成員為short類型,此成員的地址是2的整數倍;
3> 如果結構體中的成員為int,long int, long long int, float, double 類型,
此成員的地址是4的整數倍;

編譯成32位的可執行程序:

gcc ***.c -m32

測試:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//1> 如果結構體中的成員最大的成員隻占1個字節的空間,則結構體類型的大小為1的整數倍;
typedef struct{
    char name[20];
    char sex;
    char age;
}A_t;
//2> 如果結構體中的成員最大的成員隻占2個字節的空間,則結構體類型的大小為2的整數倍;
typedef struct{
    char name[20];
    short age;
    char sex;
            // 保留一個字節
}B_t;
typedef struct{
    char name[20];
    char sex;
            // 保留一個字節
    short age;
}C_t;
//3> 如果結構體中的成員最大的成員隻占4/8個字節的空間,則結構體類型的大小為4的整數倍;
typedef struct{
    char name[20];
    char sex;
            // 保留三個字節
    int age;
}D_t;
typedef struct{
    char name[20];
    char sex;
            // 保留一個字節
    short score;
    int age;
}E_t;
typedef struct{
    char name[20];
    char sex;
            // 保留一個字節
    short score;
    long long int age;
}F_t;
typedef struct{
    char *name;
    char sex;   
            // 保留一個字節
    short score;
    long long int age;
}G_t;
typedef struct{
    char *name;
    char sex;   
            // 保留一個字節(不同類型的在同一行,不同的那個從後往前補!!!)
    short score;
    char salary; 
    long long int age;
}H_t;
int main(int argc, const char *argv[])
{
    /*your code*/
    printf("A_t type size=%d\n",sizeof(A_t));//22
    printf("B_t type size=%d\n",sizeof(B_t));//24
    printf("C_t type size=%d\n",sizeof(C_t));//24
    printf("D_t type size=%d\n",sizeof(D_t));//28
    printf("E_t type size=%d\n",sizeof(E_t));//28
    printf("F_t type size=%d\n",sizeof(F_t));//32
    printf("G_t type size=%d\n",sizeof(G_t));//16
    printf("H_t type size=%d\n",sizeof(H_t));//20
    printf("-----------G_t中成員的地址-----------\n");
    G_t g;
    printf("G_t成員 char *name 的地址%p\n",g.name);
    printf("G_t成員 char sex 的地址%p\n",&g.sex);
    printf("G_t成員 short score 的地址%p\n",&g.score);
    printf("G_t成員 long long int age 的地址%p\n",&g.age);
    printf("-----------H_t中成員的地址-----------\n");
    H_t h;
    printf("H_t成員 char *name 的地址%p\n",h.name);
    printf("H_t成員 char sex 的地址%p\n",&h.sex);
    printf("H_t成員 short score 的地址%p\n",&h.score);
    printf("H_t成員 char salary 的地址%p\n",&h.salary);
    printf("H_t成員 long long int age 的地址%p\n",&h.age);
    return 0;
}

64位的操作系統

結構體中成員內存對齊,隻考慮基本的數據類型,不考慮構造類型,構造類型最終也是由基本類型構成。
1> 如果結構體中的成員最大的成員隻占1個字節的空間,則結構體類型的大小為1的整數倍;
2> 如果結構體中的成員最大的成員隻占2個字節的空間,則結構體類型的大小為2的整數倍;
3> 如果結構體中的成員最大的成員隻占4個字節的空間,則結構體類型的大小為4的整數倍;
4> 如果結構體中的成員最大的成員隻占8個字節的空間,則結構體類型的大小為8的整數倍;
結構體中的成員的地址:
1> 如果結構體中的成員為char類型,此成員的地址是1的整數倍;
2> 如果結構體中的成員為short類型,此成員的地址是2的整數倍;
3> 如果結構體中的成員為int,float類型,
此成員的地址是4的整數倍;
4> 如果結構體中的成員為long int, long long int, double 類型,
此成員的地址是8的整數倍;
編譯成64位的可執行程序:
8的整數倍;

結構體中的成員的地址:
1> 如果結構體中的成員為char類型,此成員的地址是1的整數倍;
2> 如果結構體中的成員為short類型,此成員的地址是2的整數倍;
3> 如果結構體中的成員為int,float類型,
此成員的地址是4的整數倍;
4> 如果結構體中的成員為long int, long long int, double 類型,
此成員的地址是8的整數倍;
編譯成64位的可執行程序:
gcc ***.c

到此這篇關於C語言結構體嵌套與對齊超詳細講解的文章就介紹到這瞭,更多相關C語言結構體嵌套內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: