结构体02 共用体 day17

二:通过指针

-> //指向结构体成员运算符

结构体类型的指针-> 结构体的成员变量

	struct studnet s;
	scanf("%s",s.name);
	scanf("%d",&s.socre);
	scanf("%d",&s.sno);
	scanf("%d",&s.sex);

	struct studnet *p = &s;

	printf("name = %s\n",p->name);
	printf("socre = %d\n",p->socre);
	printf("sno = %d\n",p->sno);
	printf("sex = %d\n",p->sex);

三:结构体大小规则

1.在32位的平台上,默认都是按4字节对齐的

2.对于成员变量,各自在自己的自然边界上对齐(默认四字节)。

char 1字节

short 2字节

int 4字节

3.如果成员变量中有比4字节大。此时整个结构体 按照4字节对齐。//32位的平台

4.如果成员变量中没有有比4字节大此时 整个结构体 按照最大的那个成员对齐。


​ 1.结构体成员的对齐放在自然边界(偶数位置)//64位

​ 2.结构体整体的对齐以结构体中最大的成员对齐//64位 (能被其整除)

四:简易学生信息(练习)

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

struct student
{
    char name[20];
    int score;
    int sex;
    int sno;
};

void printStuInfo(struct student *s, int len) 
{
    int i = 0;
    printf("name\t score\t sex\t sno\n");
    for (i = 0; i < len; ++i) 
	{
        printf("%s\t", s[i].name);
        printf("%d\t", s[i].score);
        printf("%d\t", s[i].sex);
        printf("%d\n", s[i].sno);
    }
}

void inputStuInfo(struct student *s, int len) 
{
    int i = 0;
    for (i = 0; i < len; ++i) 
	{
        printf("name: ");
        scanf("%s", s[i].name);
        printf("score: ");
        scanf("%d", &s[i].score);
        printf("sex: ");
        scanf("%d", &s[i].sex);
        printf("sno: ");
        scanf("%d", &s[i].sno);
        puts("-------------------------");
    }
}

void menu(void) 
{
    printf("----------Welcome Student Info System----------\n");
    printf("1 输入学生信息\n");
    printf("2 查看所有学生信息\n");
    printf("3 以分数查看学生信息\n");
    printf("4 以学号查看学生信息\n");
    printf("5 以姓名查看学生信息\n");
    printf("6 退出\n");
    printf(">>>>>>>>>>>>>>>>20250617<<<<<<<<<<<<<<<<\n");
    printf("> ");
}

int cmpScore(const void *a, const void *b) 
{
    const struct student *p = a;
    const struct student *q = b;
    return p->score - q->score;
}

int cmpSno(const void *a, const void *b) 
{
    const struct student *p = a;
    const struct student *q = b;
    return p->sno - q->sno;
}

int cmpName(const void *a, const void *b) 
{
    const struct student *p = a;
    const struct student *q = b;
    return strcmp(p->name , q->name);
}

int main(void)
{
    struct student s[3] = {
        {"Tom", 100, 1, 110},
        {"Alice", 89, 0, 112},
        {"Jack", 99, 1, 111} 
    };

    int len = sizeof(s) / sizeof(s[0]);
    int op = 0;
    while (1)
	{
        menu();
        scanf("%d", &op);

        switch (op) 
		{
            case 1:
                inputStuInfo(s, len);
                break;
            case 2:
                printStuInfo(s, len);
                break;
            case 3:
                qsort(s, len, sizeof(struct student), cmpScore);
                printStuInfo(s, len);
                break;
            case 4:
                qsort(s, len, sizeof(struct student), cmpSno);
                printStuInfo(s, len);
                break;
            case 5:
                qsort(s, len, sizeof(struct student), cmpName);
                printStuInfo(s, len);
                break;
            case 6:
                printf("exit......\n");
                return 0;
        }
    }

    return 0;
}

五:共用体

1.语法

union 共用体名
{
	//各个成员变量
	......
	....
};定义

1.共用体类型的定义和结构体类型的定义 类似

2.共用体中各个成员变量 — 共用一块内存空间因为共用体成员变量共用同一块空间

3.结构体中各个成员变量—–独立各自空间,共用体的大小= 成员变量中最大的那个成员大小

​ 共用体各个成员的起始地址是一样的,但是,因为各个成员变量,本身类型大小不一样,最终能使用到的字节数是 不一样的。

4.共用体初始化时,默认值是给到第一个变量的 //注意:初始化时,要看第一个变量的类型

5.共用体成员可以赋值但是因为共用一块空间,最终空间上结果,要看最后一次给到的结果

union demo
{
	int c;
	char a;
	short b;
};

int main(int argc, const char *argv[])
{
	union demo d = {0x12345678};
	printf("sizeof(union demo) = %ld\n",sizeof(union demo));

	printf("a = %#x\n",d.a);
	printf("b = %#x\n",d.b);
	printf("c = %#x\n",d.c);

	printf("&a = %p\n",&d.a);
	printf("&b = %p\n",&d.b);
	printf("&c = %p\n",&d.c);
	
	return 0;
}

sizeof(union demo) = 4
a = 0x78
b = 0x5678
c = 0x12345678
&a = 0x7ffc11fa01f4
&b = 0x7ffc11fa01f4
&c = 0x7ffc11fa01f4

2.判断大小端

int judLitterENdian(void)
{
	union
	{
		unsigned int a;
		unsigned int b;
	}d = {1};

	return d.b;
}

int main(int argc, const char *argv[])
{
	if(judLitterENdian() == 1)
	{
		printf("little\n");
	}else
	{
		printf("big\n");
	}
	
	return 0;
}

六:共用体和共用体结合实例

struct member
{
	char name[20];
	int sno;
	union
	{
		float score;
		float salary;
	}data;
};

int main(int argc, const char *argv[])
{
	printf("sizeof(struct member) = %ld\n",sizeof(struct member));

	struct member stu = {"tom",110,99.5};
	struct member teacher = {"jerry",110,