【C语言】

结构体

结构体变量的定义及初始化

写法1:
    struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu s1;
    strcpy(s1.name, "zhangsan");
    s1.age = 18;
    s1.sex = 'M';
    //如果是指针操作 必须先明确指针的指向
    struct Stu *p1 = (struct Stu *)malloc(sizeof(struct Stu));
    strcpy(p1->name, "lisi");
    p1->age = 20;
    p1->sex = 'W';
    
写法2:
    struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu s1 = {"zhangsan", 18, 'W'};
    
写法3:
    struct Stu{
        char name[32];
        int age;
        char sex;
    }s1;
    strcpy(s1.name, "zhangsan");
    s1.age = 18;
    s1.sex = 'M';

写法4:
    struct Stu{
        char name[32];
        int age;
        char sex;
    }s1 = {"zhangsan", 18, 'W'};

写法5struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu s1 = {
        .name = "zhangsan",
        .sex = 'M'
    };

写法6:
    struct Stu{
        char name[32];
        int age;
        char sex;
    }s1;
    s1 = (struct Stu){"lisi", 20, 'W'};

结构体数组的赋值和初始化

写法1:
    struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu hqyj[3];//定义了一个结构体数组 定义好之后就不能整体赋值了
    strcpy(hqyj[0].name, "zhangsan");
    hqyj[0].age = 18;
    hqyj[0].sex = 'W';
    strcpy(hqyj[1].name, "lisi");
    hqyj[1].age = 20;
    hqyj[1].sex = 'M';

写法2:
    struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu hqyj[3] = {
        {"zhangsan", 18, 'W'},
        {"lisi", 20, 'M'},
        {"wangwu", 25, 'W'}
    };

写法3:
    struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu hqyj[3] = {
        [0] = {"zhangsan", 18, 'W'},
        [2] = {"lisi", 20, 'M'}
    };

写法4:
    struct Stu{
        char name[32];
        int age;
        char sex;
    };
    struct Stu hqyj[3] = {
        [0] = {
                .name = "zhangsan", 
                .age = 18
            },
        [2] = {
                .age = 20, 
                .sex = 'M'
            }
    };

结构体中可以包含其他结构体的变量

#include <stdio.h>

struct Test1{
	int a;
};

struct Test2{
	int b;
	char c;
	struct Test1 d;
	//struct Test2 e;//错误的 不能包含自己结构体类型的变量
	struct Test2 *p;//正确的 可以包含自己结构体类型的指针 链表中就是这样使用的
};

int main(int argc, const char *argv[])
{
	struct Test2 value;
	value.b = 10;
	value.c = 'M';
	value.d.a = 20;

	printf("%d %c %d\n", value.b, value.c, value.d.a);//10 M 20

	return 0;
}

结构体中可以包含函数指针

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

/*
struct Test{
	int a;
	char b;
	//C语言中 结构体中不允许定义函数  C++中可以
	int my_add(int x, int y){
		return x+y;
	}
};
*/

int my_add(int x, int y){
	return x+y;
}

int my_sub(int x, int y){
	return x-y;
}

struct Test{
	unsigned int a;
	unsigned char b;
	int (*p)(int, int);//C语言的结构体可以封装函数指针
};

int main(int argc, const char *argv[])
{
	struct Test t1 = {10, 20, my_add};
	printf("%d\n", t1.p(t1.a, t1.b));//30
	printf("%d\n", t1.p(30, 40));//70

	struct Test *p1 = (struct Test *)malloc(sizeof(struct Test));
	p1->a = 100;
	p1->b = 200;
	p1->p = my_sub;
	printf("%d\n", p1->p(p1->a, p1->b));//-100
	printf("%d\n", p1->p(30, 40));//-10

	free(p1);
	p1 = NULL;

	return 0;
}

结构体对齐

-----------------------------------64位系统--------------------------------
就是按照最大的元素进行对齐的
//sizeof(long double) == 16
struct A{
char a;
long double b;
};//–>32字节
-----------------------------------32位系统--------------------------------
64位系统将程序按32位编译, 需要加编译选项 -m32

对齐规则:
1.如果结构体中成员都是小于4字节的,按最大的成员对齐
2.如果结构体中有成员大于等于4字节,都按4字节对齐
3.要特别注意char和short连续存储的问题
在这里插入图片描述
结构体中包含其他结构体变量时的对齐规则:

#include <stdio.h>

struct A{
	int a;
	char b;
};

struct B{
	struct A m;
	char c;
	int d;
};//16字节  因为A的大小是8字节 虽然A的成员只占用了5字节
			//但是为了满足A的对齐 多分了 3个字节
			//这3个字节是没法被B的成员占用的
//----------------------------------
struct C{
	short a;
	short b;
	short c;
};

struct D{
	struct C m;
	char d;
	int e;
};//12字节  因为结构体C是6个字节,没有因为满足自身的对齐而多分配空间
			//把C放在D中的时候 为了满足D的对齐,相当于D给C多分了2个字节
			//多分的这两个字节 D中的成员是可以占用的

int main(int argc, const char *argv[])
{
	printf("sizeof(struct B) = %d\n", sizeof(struct B));//16
	printf("sizeof(struct D) = %d\n", sizeof(struct D));//12

	return 0;
}

结构体位域

结构体位域是压缩结构体的一种手段。

#include <stdio.h>

struct LED{
	unsigned char led1:1;//此处是使用 :1 指定成员只占用1个bit位
	unsigned char led2:1;
	unsigned char led3:1;
	unsigned char led4:1;
	unsigned char led5:1;
	unsigned char led6:1;
	unsigned char led7:1;
	unsigned char led8:1;
};

int main(int argc, const char *argv[])
{
	printf("sizeof(struct LED) = %ld\n", sizeof(struct LED));//1
	struct LED my_led;
	my_led.led1 = 0;
	my_led.led2 = 1;

	return 0;
}

共用体(联合体)(union)

格式

union 共用体名{
    类型1 成员1;
    类型2 成员2;
    ...
    类型3 成员3;
};

注意事项

1.共用体中所有的成员是共享同一块内存空间的
2.共用体所有成员的首地址都是相同的
3.共用体的大小取决于类型最大的成员
4.共用体的使用和结构体基本是一模一样的

注意:
因为共用体的所有成员共享同一块儿内存空间。修改一个成员,其他的成员的值也会一起发生变化,所以要谨慎使用。

例如:
#include <stdio.h>
#include <string.h>

typedef union Test{
	char a;
	short b;
	int c;
}hqyj;

int main(int argc, const char *argv[])
{
	printf("sizeof(hqyj) = %ld\n", sizeof(hqyj));//4
	union Test v1;
	hqyj v2;

	memset(&v2, 0, sizeof(v2));//给v2的4个字节都赋值成 0

	printf("&v2.a = %p\n", &v2.a);//一样的
	printf("&v2.b = %p\n", &v2.b);
	printf("&v2.c = %p\n", &v2.c);

	//修改 v2 的 a成员的值为100
	v2.a = 100;

	//其他成员的值也会发生变化 因为用的是同一块内存空间
	printf("v2.a = %d\n", v2.a);//100
	printf("v2.b = %d\n", v2.b);//100
	printf("v2.c = %d\n", v2.c);//100

	return 0;
}
使用共用体写一个简单的代码,来测试你使用的主机是大端存储还是小端存储?
#include <stdio.h>

union Test{
    int a;
    char b;
};

int main(int argc, const char *argv[])
{
	union Test t;
	t.a = 0x12345678;
	if(0x78 == t.b){
		printf("小端\n");
	}else if(0x12 == t.b){
		printf("大端\n");
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值