C语言基础(结构体 共用体 枚举)

结构体

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

定义格式

struct 结构体名

{

        数据类型 成员变量 1;

        数据类型 成员变量 2;

        数据类型 成员变量 3;

        ......

};

结构体变量

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

定义格式

先定义结构体,再定义结构体变量

struct 结构体名

{

        成员变量;

};

struct 结构体名 变量名;

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

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

struct 结构体名

{

        成员变量;

} 变量名;

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

缺省结构体名,定义结构体变量

struct

{

        成员变量;

} 变量名;

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

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

#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; 
} 

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

#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; 
}

大括号点等法赋值

#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; 
} 
访问

通过.访问:结构体变量名.成员变量名

输出:printf("%d %d %f\n", stu.id, stu.age, stu.score,stu.name);

输入:scanf("%d %d %f %s", &stu.id, &stu.age, &stu.score, stu.name);

stu.name 就不用加&,因为这个数组名本身就是地址

#include<stdio.h>
struct student
{
    char name[32];
    int id;
    int age;
    float score;
}stu;
int main(int argc, char const *argv[])
{
    scanf("%s %d %d %d",stu.name,&stu.id,&stu.age,&stu.score);
    printf("name:%s id:%d age:%d\n",stu.name,stu.id,stu.age,stu.score);
    return 0;
}

结构体数组

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

定义格式

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

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

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

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

定义结构体数组同时赋值

#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; 
}

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

#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;
    stu[1].id = 2; 
    stu[1].age = 21; 
    stu[1].score = 89;
    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); 
    } 
    for (i = 0; i < 3; i++)
    {
        if (stu[i].score >= 60)
            printf("name:%s id:%d age:%d score:%f\n", stu[i].name, 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).id = 2;

#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;
} 

结构体大小

结构体大小并不是简单的将每个结构体成员的大小相加就能得到的

sizeof(struct 结构体名); // 结构体类型大小

struct student 
{ 
    int id; 		//8
    int age; 
    float score; 	//8
    char a; 
    double b; 		//8
}; 

sizeof(struct student); // 24

结构体内存对齐规则

 第一个成员变量偏移量为 0 地址处。(结构体的首地址处)

 其他成员变量要对齐到自身大小的的整数倍

 如果嵌套了结构体,嵌套的结构体对齐到自己的最大整数的倍数处,结构体整体的大小就是所有最大对齐数的整数倍

对齐数:该结构体成员自身的大小与编译器默认的大小比较,取小值

注意:32位操作系统默认的对齐数4 | 64位操作系统默认的对齐数8

字节对齐原则

用结构体里面最大的数据类型的大小和8进行比较,按照字节数小的为单位开辟空间

例子:

struct student

{

        double a;

        char b;

        int c;

};

// 16

总结

  • 不能把结构体变量作为整体引用,只能对结构体变量中各个成员变量分别引用
  • 如果成员变量本身属于另一种结构体类型,用若干个成员运算符一级级找到你想要的成员变量
#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; 
} 
  • 可以把成员变量当成普通变量运算
  • 在数组中,数组之间是不能彼此赋值的,结构体变量可以相互赋值

共用体

概念:不同类型的成员变量共用同一块地址空间

定义格式

union 共用体名

{

        成员变量1;

        成员变量2;

}

共用体变量

定义格式

union 共用体名 变量名;

#include <stdio.h> 
union val 
{ 
    int a; 
    char ch; 
}; 
int main(int argc, char const *argv[]) 
{ 
    union val v; 
    v.a = 10; 
    // 他俩不能同时出现,以最后一次赋值为准 
    v.ch = 'a'; 
    printf("%d\n", v.a); 
    return 0; 
} 

特性

1) 共用体成员共用同一块地址空间

2) 赋值顺序以最后一次赋值为准

3) 共用体的大小为成员中类型最大的数据的大小

枚举

概念:用户自定义的数据类型,可以用于声明一组常数

定义格式

enum 枚举名

{

        value1,

        value2,

        value3,

        ...

};

#include <stdio.h> 
enum week 
{ 
    MON = 1, 
    TUE, 
    WED, 
    Thurs, 
    Fri, 
    Set, 
    Sum 
}; 
int main(int argc, char const *argv[]) 
{ 
    int day; 
    scanf("%d", &day); 
    switch (day) 
    { 
        case MON: 
        printf("这是周一的内容\n"); 
        break; 
        case TUE: 
        printf("这是周二的内容\n"); 
        break; 
        case WED: 
        printf("这是周三的内容\n"); 
        break; 
        default: 
        break; 
    } 
    return 0; 
} 

未赋初值,第一个常数会默认为 0,后面常数依次加一(如果第一个值被设置为 1,则默认从 1 开始递增)

存储类型

auto static extern register

auto 自动型

修饰变量,一般省略的时候会认为是 auto 类型

static 静态型

修饰局部变量

1) 变量的存放位置在全局区(静态区) 如果静态变量有初值,存放在数据段,没有初始化存放在.bss 段

2) 生命周期为整个程序

3) 限制作用域:

修饰局部变量:和普通局部变量的作用域没有区别,但是生命周期被延长了

修饰全局变量:限制在本文件中使用

4) 只初始化一次,不手动赋值,初始值 0

#include <stdio.h> 
void fun() 
{ 
    static int a = 0; 
    a++; 
    printf("%d\n", a); 
} 
int main(int argc, char const *argv[]) 
{ 
    int b; 
    printf("%d\n", b); 
    fun(); // 1 
    fun(); // 2 
    return 0; 
}

修饰函数

static 修饰函数,限制在本文件中使用

extern 外部引用

通过extern 可以引用其他文件中的全局变量或函数

//a.c
int a=10;
void fun()
{
    printf("asd");
}

//extern.c
include<stdio.h>
extern int a;
extern void fun();
int main(int argc, char const *argv[])
{
    fun();
    printf("%d\n",a);//10
    return 0;
}

代码示例

#include <stdio.h>

// 定义一个枚举类型,列出一周的天数
enum Weekday {
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
};

// 定义一个共用体,用于存储整数或字符
union Value {
    int i;
    char c;
};

// 定义一个结构体,包含枚举类型、共用体和字符数组
struct Person {
    enum Weekday day;
    union Value value;
    char name[50];
};

int main() {
    // 创建一个结构体变量
    struct Person person;

    // 设置枚举值
    person.day = Wednesday;

    // 使用共用体的整数部分
    person.value.i = 42;

    // 设置名字
    snprintf(person.name, sizeof(person.name), "John Doe");

    // 打印结构体信息
    printf("Name: %s\n", person.name);
    printf("Day: %d\n", person.day);
    printf("Integer value: %d\n", person.value.i);

    // 修改共用体为字符部分,并打印
    person.value.c = 'A';
    printf("Character value: %c\n", person.value.c);

    // 注意:由于共用体在同一时间只能存储一个值,打印整数部分将不再正确
    // 这将打印未定义的值,因为共用体的内存位置现在用于存储字符
    printf("Integer value after changing to character: %d\n", person.value.i);

    return 0;
}
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值