结构体

本文详细介绍了C语言中结构体的基本使用方法,包括结构体的定义、初始化、成员访问及作为参数和返回值的使用方式,并探讨了结构体位字段(BitField)的应用,最后展示了无标记名结构体的例子。
一、结构体的基本使用

结构体的使用要注意以下几个方面:

  1. 结构体的标记名不是变量,它和struct连用才表示自定义的数据类型。
  2. 用结构体定义的变量可以是一般变量,也可以是数组或指针。
  3. 一般变量和数组操作元素时用“.”,指针操作元素时用“->”。
  4. 结构体的元素可以是任何数据类型,包括自定义的结构体类型。
  5. 结构体的元素虽可以是指针,但极易造成内存泄漏,宜慎用。
  6. 结构体数组变量名可以当作地址,普通变量名不能当作地址,必须前置“&”。
  7. 元素的地址要看其类型,基本类型时同样要使用“&”。


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

//结构体的定义
struct BOOK {
    char  id[4];       //编号
    char  name[64];    //书名
    float price;       //单价
};

int main(void)
{
    //结构体也可以初始化时直接赋值
    struct BOOK clang = {"101", "劝学网的C语言教程", 25.5};
    struct BOOK books[2];
    struct BOOK *p;

    //变量或数组对结构体元素的赋值
    strcpy(books[0].id, "201");
    strcpy(books[0].name, "劝学网的Oracle教程");
    books[0].price = 35.5;

    //指针对结构体元素的赋值
    p = books + 1;
    strcpy(p->id, "202");
    strcpy(p->name, "小雅的Java教程");
    p->price = 45.5;

    //显示结构体变量的内容
    printf("%s, %s, %f\n", clang.id, clang.name, clang.price);
    printf("%s, %s, %f\n", books[0].id, books[0].name, books[0].price);
    printf("%s, %s, %f\n", p->id, books[1].name, (books+1)->price);

    return 0;
}

二、结构体作参数和返回值

下面例子分别演示结构体变量、指针在作参数和返回值时的各种情况。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct p_type {
    char id[4];       //编码
    char name[16];    //姓名
};

//结构体变量作参数
void setByVar(struct p_type per) {
    strcpy(per.id, "202");
    strcpy(per.name, "张展");

    return ;
}

//结构体指针作参数
void setByAdd(struct p_type *per) {
    strcpy(per->id , "303");
    strcpy(per->name, "张腾");

    return ;
}

//结构体变量作返回值
struct p_type setNewByVar() {
    static struct p_type zh;   //一定要是静态变量才能作为返回值

    strcpy(zh.id, "404");
    strcpy(zh.name, "张翅");

    return zh;
}

//结构体指针作返回值
struct p_type *setNewByAdd() {
    struct p_type *p;

    p = (struct p_type *)malloc(sizeof(struct p_type));
    strcpy(p->id, "505");
    strcpy(p->name, "张去");

    return p;
}

void print(const struct p_type *per) {
    printf("%s, %s\n", per->id, per->name);

    return
}

int main(void)
{
    struct p_type zhang, *p, tmp;

    //变量中的初始值
    strcpy(zhang.id, "101");
    strcpy(zhang.name, "张飞");

    //用变量直接作参数,值不能被修改
    setByVar(zhang);
    print(&zhang);    //结果:101, 张飞

    //用指针直接作参数,值可以被修改
    setByAdd(&zhang);
    print(&zhang);    //结果:303, 张腾

    //用变量直接作返回值,OK
    tmp = setNewByVar();
    print(&tmp);      //结果:404, 张翅

    //用指针直接作返回值,OK
    p = setNewByAdd();
    print(p);         //结果:505, 张去
    free(p);          //释放内存不能忘记

    return 0;
}

由上例可以看出,结构体使用指针作参数时是按地址传送的,不使用指针便按值传送,说明一点,结构体是基本类型的一种扩充,符合基本类型的规律。

三、结构体的位字段(BitField)

当结构体中的元素的取值范围很小时,可以将几个字段按位合成一个字段来表示,起到节省内存空间的作用。


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

struct b_type {
    unsigned char depart: 3 ;   //部门(最大7个部门)
    unsigned char sex: 1 ;      //性别
    unsigned char reason: 2 ;   //理由(共4个)
};

void print(struct b_type *rea) {
    char dep[7];
    char sex[3];
    char res[5];

    switch (rea->depart) {
        case 1:
            strcpy(dep,"财务科");
            break;
        case 2:
            strcpy(dep,"开发科");
            break;
        case 3:
            strcpy(dep,"检测科");
            break;
        case 4:
            strcpy(dep,"生产科");
            break;
        default:
            break;
    }

    switch (rea->sex) {
        case 0:
            strcpy(sex,"男");
            break;
        default:
            strcpy(sex,"女");
            break;
    }

    switch (rea->reason) {
        case 1:
            strcpy(res,"事假");
            break;
        case 2:
            strcpy(res,"病假");
            break;
        case 3:
            strcpy(res,"婚假");
            break;
        default:
            strcpy(res,"无故");
            break;
    }

    printf("%s, %s, %s\n", dep, sex, res);

    return ;
}

int main(void)
{
    struct b_type staff; 

    staff.depart = 2;
    staff.sex = 0;
    staff.reason =4;

    printf("staff的长度:%d\n", sizeof(struct b_type));
    print(&staff);

    return 0;
}

四、没有标记名的结构体

C语言同样允许没有标记名的结构体。


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

int main(void)
{
    struct {
        char id[4] ;       //编码
        char name[16] ;    //姓名
    } staff, *p;

    strcpy(staff.id, "101");
    strcpy(staff.name, "后羿");
    
    p = &staff ;

    printf("%s, %s\n", p->id, p->name);

    return 0;
}

内容概要:本文详细介绍了一种基于Simulink的表贴式永磁同步电机(SPMSM)有限控制集模型预测电流控制(FCS-MPCC)仿真系统。通过构建PMSM数学模型、坐标变换、MPC控制器、SVPWM调制等模块,实现了对电机定子电流的高精度跟踪控制,具备快速动态响应和低稳态误差的特点。文中提供了完整的仿真建模步骤、关键参数设置、核心MATLAB函数代码及仿真结果分析,涵盖转速、电流、转矩和三相电流波形,验证了MPC控制策略在动态性能、稳态精度和抗负载扰动方面的优越性,并提出了参数自整定、加权代价函数、模型预测转矩控制和弱磁扩速等优化方向。; 适合人群:自动化、电气工程及其相关专业本科生、研究生,以及从事电机控制算法研究与仿真的工程技术人员;具备一定的电机原理、自动控制理论和Simulink仿真基础者更佳; 使用场景及目标:①用于永磁同步电机模型预测控制的教学演示、课程设计或毕业设计项目;②作为电机先进控制算法(如MPC、MPTC)的仿真验证平台;③支撑科研中对控制性能优化(如动态响应、抗干扰能力)的研究需求; 阅读建议:建议读者结合Simulink环境动手搭建模型,深入理解各模块间的信号流向与控制逻辑,重点掌握预测模型构建、代价函数设计与开关状态选择机制,并可通过修改电机参数或控制策略进行拓展实验,以增强实践与创新能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值