C语言 | 结构体偏移对齐、结构体指针、结构体作为函数参数

目录

一、结构体变量的定义与使用

1.先声明结构体类型再定义变量名

2.在声明类型的同时定义变量

3.直接定义结构体类型变量(无类型名)

二、结构体偏移对齐

三、结构体指针

1.普通成员

2.指针成员

3.结构体指针

四、结构体作为函数参数


一、结构体变量的定义与使用

1.先声明结构体类型再定义变量名

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
struct student {
    char name[21];
    int age;
    char address[51];
};
void main()
{
    struct student stu;
    //stu.name = "张三";//错误,stu.name是数组名,是个常量
    strcpy(stu.name, "张三");
    stu.age = 18;
    strcpy(stu.address, "北京市朝阳区");
    printf("name:%s\n", stu.name);
    printf("age:%d\n", stu.age);
    printf("address:%s\n", stu.address);

    struct student stu1 = { "李四",18,"北京市海淀区" };
    printf("name:%s\n", stu1.name);
    printf("age:%d\n", stu1.age);
    printf("address:%s\n", stu1.address);
}

2.在声明类型的同时定义变量

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

struct student {
    char name[21];
    int age;
    char address[51];
} stu;

void main()
{
    //stu.name = "张三";//错误,stu.name是数组名,是个常量
    strcpy(stu.name, "张三");
    stu.age = 18;
    strcpy(stu.address, "北京市朝阳区");

    printf("name:%s\n", stu.name);
    printf("age:%d\n", stu.age);
    printf("address:%s\n", stu.address);

}

3.直接定义结构体类型变量(无类型名)

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

struct {
    char name[21];
    int age;
    char address[51];
}stu;

void main()
{
    //stu.name = "张三";//错误,stu.name是数组名,是个常量
    strcpy(stu.name, "张三");
    stu.age = 18;
    strcpy(stu.address, "北京市朝阳区");

    printf("name:%s\n", stu.name);
    printf("age:%d\n", stu.age);
    printf("address:%s\n", stu.address);
}

二、结构体偏移对齐

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

struct student {
    char name[21];
    int age;
    char address[51];
};

void main()
{
    struct student stu[3] = {
         {"张三",20,"北京昌平"},
         {"李四",22,"北京朝阳"},
         {"王五",19,"北京海淀"}
    };
    printf("结构体数组字节大小%d\n", sizeof(stu));//240
    printf("结构体字节大小%d\n", sizeof(stu[0]));//80
    printf("结构体字节大小%d\n", sizeof(struct student));//80
    printf("结构体元素个数%d\n", sizeof(stu) / sizeof(struct student));//3
}

student 结构体字节大小并不是21+4+51=76,而是21+2+4+51+2=80。

结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每个元素放置到内存中时,它都会认为内存是按照自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始

结构体总大小为最大类型所占字节数的整数倍

name[21]占21个字节;下一个位置为22

age为int类型,占4字节,但是第22位不是4的整数倍,第24位才是,所以偏移2位后存age;下一个位置为28

address[51],类型为char,char占1个字节,第28位是char的整数倍,一共占51个字节;此时总大小为78,但78不是最大类型int 所占字节数4的整数倍,所以student 结构体字节大小为80.

【举个例子】下方student结构体字节大小为76,不需要进行偏移。

struct student {
    char name[21];
    char address[51];
    int age;
};

三、结构体指针

1.普通成员

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
    char name[21];
    int age;
    char address[51];
};
void main()
{
    struct student stu1 = { "张三",20,"北京昌平" };
    struct student stu2 = stu1;
    strcpy(stu2.name, "李四");
    printf("%s\n", stu1.name);//张三
}

2.指针成员

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
    char* name;
    int age;
    char* address;
};
void main()
{
    struct student stu1 = { "张三",20,"北京昌平" };
    struct student stu2;
    //strcpy(stu2.name, "小三");//报错,使用了未初始化的局部变量stu2

    stu2.name = "李四";//正确

    stu2.name = (char*)malloc(sizeof(char) * 21);
    strcpy(stu2.name, "李四");//正确

    stu2.age = 30;

    stu2.address = "北京海淀";//正确

    stu2.address = (char*)malloc(sizeof(char) * 51);
    strcpy(stu2.address, "北京海淀");//正确

    printf("%s\n", stu2.address);//张三
}

3.结构体指针

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
    char* name;
    int age;
    char* address;
};
    struct student stu = { "张三",20,"北京昌平" };
    struct student* p = &stu;
void main()
{
    struct student* stu = (struct student*)malloc(sizeof(struct student) * 3);
    for (size_t i = 0; i < 3; i++)
    {
        stu[i].name = (char*)malloc(sizeof(char) * 21);
        stu[i].address = (char*)malloc(sizeof(char) * 51);
        scanf("%s%d%s", stu[i].name, &stu[i].age, stu[i].address);
    }
    for (size_t i = 0; i < 3; i++)
    {
        printf("%s ", stu[i].name);
        printf("%d ", stu[i].age);
        printf("%s\n", stu[i].address);
    }
}
void main()
{
    struct student stu1 = { "张三",20,"北京昌平" };
    struct student* stu2 = &stu1;
    stu2->name= "李四";
    printf("%s\n", stu1.name);//李四
}

四、结构体作为函数参数

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
    char* name;
    int age;
    char* address;
};
void GetStudent(struct student stu)
{
    stu.name = "Lisa";
    stu.age = 29;
    stu.address = "another nation";
    printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lisa's age is 29,she is from another nation
}
void main()
{
    struct student stu = {"Lin",22,"China"};
    printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lin's age is 22,she is from China
    GetStudent(stu);
    printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lin's age is 22,she is from China
}
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
    char* name;
    int age;
    char* address;
};
void GetStudent(struct student* stu)
{
    //(*stu).name = "Lisa";
    stu->name = "Lisa";
    stu->age = 29;
    stu->address = "another nation";
    printf("%s's age is %d,she is from %s\n", stu->name, stu->age, stu->address);//Lisa's age is 29,she is from another nation
}
void main()
{
    struct student stu = {"Lin",22,"China"};
    printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lin's age is 22,she is from China
    GetStudent(&stu);
    printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lisa's age is 29,she is from another nation
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值