嵌入式学习day10(结构体)

一丶结构体

定义:

            用户自定义的数据类型,在结构体中可以包含若干个不同类型数据的成员变量(也可以相同),使这些数据项组合起来反映某一个信息

格式:

              struct 结构体名

              {数据类型 成员变量1;
               数据类型 成员变量2;
               数据类型 成员变量3;};

二丶结构体变量

定义:

          通过结构体类型定义的变量

格式:

 1. 先定义结构体,在定义结构体变量

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
};
int main(int argc, char const *argv[])
{
    struct student stu;
    return 0;
}

2. 定义结构体的同时,定义结构体变量

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
} stu;
int main(int argc, char const *argv[])
{
    return 0;
}

3.缺省结构体名定义结构体变量

#include <stdio.h>
struct
{
    int id;
    int age;
    float score;
} stu;
int main(int argc, char const *argv[])
{
    return 0;
}

赋值:

1. 定义变量时直接用大括号赋值

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
};
int main(int argc, char const *argv[])
{
    struct student stu = {1, 20, 88};
    return 0;
}

2.定义变量时未初始化,然后对变量单独赋值

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
};
int main(int argc, char const *argv[])
{
    struct student stu;
    stu.id = 1;
    stu.age = 20;
    stu.score = 88;
    return 0;
}

3.点等法赋值

#include <stdio.h>
struct student
{
    int id;
    char name[32];
    int age;
    float score;
};
int main(int argc, char const *argv[])
{
    struct student stu = {
        .id = 1,
        .age = 20,
        .score = 88
    };
    return 0;
}

访问:

通过.访问 :结构体变量名.成员变量名
scanf("%d %d %f %s", &stu.id, &stu.age, &stu.score, stu.name);
// stu.name就不用加&,因为这个数组名本身就是地址
printf("%d %d %f\n", stu.id, stu.age, stu.score);

三丶结构体数组

概念

              结构体类型相同的变量组成的数组

格式:

   1.  定义结构体同时定义结构体数组

struct student
{
    int id;
    int age;
    float score;
} stu[3];

2.先定义结构体,然后定义结构体数组

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
};

int main(int argc, char const *argv[])
{
    struct student stu[3];
    return 0;
}

初始化

1.定义结构体数组同时赋值

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
};

int main(int argc, char const *argv[])
{
    struct student stu[3] = {
        {1, 20, 88},
        {2, 21, 89},
        {3, 19, 90}
    };
    return 0;
}

2. 先定义结构体数组,在对数组的每一个元素分别赋值

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
} stu[3];

int main(int argc, char const *argv[])
{
    stu[0].id = 1;
    stu[0].age = 20;
    stu[0]. score = 88;
    return 0;
}

结构体数组大小

       结构体类型大小*元素个数

       sizeof(结构体数组名);

结构体输入输出(for循环)

#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
} stu[3];

int main(int argc, char const *argv[])
{
    for (int i = 0; i < 3; i++)
    {
        scanf("%d %d %f", &stu[i].id, &stu[i].age, &stu[i].score);
    }
    return 0;
}

四丶结构体指针

概念:

           指向结构体变量的指针

定义格式:

           struct 结构体名 *结构体指针名;
#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
} stu1, stu2;
struct work
{
    int id;
    int age;
    float score;
} w1, w2;
int main(int argc, char const *argv[])
{
    struct student *p = &stu1;
    struct student *p1 = &w1;  // 错误,结构体类型不匹配
    return 0;
}

赋值:

            // ->:指向的
            格式:指针变量名 -> 成员变量名
                        p -> id = 1;
                        p -> age = 20;
                        p -> score = 88;((*p).score)
#include <stdio.h>
struct student
{
    int id;
    int age;
    float score;
} stu1;
int main(int argc, char const *argv[])
{
    struct student *p = &stu1;
    scanf("%d %d %f", &p->id, &p->age, &p->score);
    printf("%d %d %f\n", p->id, p->age, (*p).score);
    return 0;
}

大小:

          本质是指针,与操作系统有关,64位为8,32位为4

五丶结构体大小

               结构体大小并不是简单的将每个结构体成员的大小相加就能得到的,可以用 sizeof(struct 结构体名); // 结构体类型大小

结构体内存对齐规则

           将结构体成员变量所占字节大小与编译器默认对齐数(64位:8,32位:4)相比较,取较大值从0地址处开始开辟,如果第一个成员变量存放后剩余内存可以存放下一个变量,则不需要开辟,否则就继续按结构体内存对齐原则向下开辟,结构体大小等于所有变量开辟内存大小。

//64位操作系统,默认对齐数为8
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct demo
{
    short a;  // 2     开辟8字节,short存储结束后还剩6字节
    int b;    // 4      int 4字节继续存储于剩余的6字节,还剩2字节
    double c; // 8      double无法存储,再次开辟8字节
} D, *DP;
int main()
{
    printf("%ld",sizeof(D));//结构体大小就为开辟的8+8=16字节
}

为什么要进行字节对齐?

1.  平台原因:不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。(提高程序的移植性)
2.  性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
3.  内存原因:在设计结构体时,通过对齐规则尽可能优化结构体的空间大小至最小空间

六丶结构体总结

            1.  不能把结构体变量作为整体引用,只能对结构体变量中各个成员变量分别引用
            2.  如果成员变量本身属于另一种结构体类型,用若干个成员运算符一级级找到你想要的成员 变量
            3.  可以把成员变量当成普通变量运算

       4.  在数组中,数组之间是不能彼此赋值的,结构体变量可以相互赋值

#include <stdio.h>
struct work
{
    int ip;
};
struct student
{
    int id;
    int age;
    struct work w1;
} stu;
int main(int argc, char const *argv[])
{
    stu.w1.ip = 10;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值