Linux C语言:结构体指针和结构体嵌套大小及位域

一、结构体指针

作用:通过指针访问结构体中的成员

语法:struct  结构体名  *指针名;

利用操作符->可以通过结构体指针访问结构体属性

#include <stdio.h>
#include <string.h>
 
//定义结构体
struct student
{
	int num;
	char name[16];
	float score;
};
 
int main(int argc, const char *argv[])
{
	struct student stu;
	struct student *p = &stu;
 
	/*
	 * 通过结构体变量去赋值
	stu.num = 1000;
	strcpy(stu.name, "lisi");
	stu.score = 90;
	*/
 
	//通过结构体指针去赋值
	p->num = 1000;
	strcpy(p->name, "lisi");
	p->score = 90;
 
	printf("num = %d, name = %s, score = %f\n", stu.num, p->name, p->score);
 
	return 0;
}

结构体指针点(.)和箭头(->)的区别

        点(.)是用于结构体变量访问成员,箭头(->)是用于结构体指针访问成员。
        访问结构成员的运算符有两种,一种是结构成员运算符“·”,也称为“圆点运算符”,另一种是结构指针运算符“->”,也称“箭头运算符”。
        圆点运算符是比较古老的写法,不能访问结构体指针变量成员,现在都推荐使用箭头运算符,即->

二、结构体嵌套结构体

含义:结构体中的成员可以是另一个结构体

        语法

        struct  结构体名

        {

          struct 结构体名   成员名; 

        };

#include <stdio.h>
#include <string.h>
 
struct person
{
	char name[16];
	int age;
	char sex;
};
 
struct  student
{
	struct person stu; 
	float score;
};
 
struct teacher
{
	struct person tea;
	char phone[12];
};
 
int main(int argc, const char *argv[])
{
	struct student s;
 
	strcpy (s.stu.name,"zhangsan");
	s.stu.age = 12;
	s.stu.sex = 'm';
	s.score = 98;
 
	printf("name = %s,age = %d, sex = %c, score = %f\n", s.stu.name, s.stu.age, s.stu.sex, s.score);
 
	struct teacher t;
	struct teacher *p = &t;
 
	strcpy (p->tea.name, "lisi");
	p->tea.age = 54;
	p->tea.sex = 'w';
	strcpy (p->phone, "13112341234");
 
	printf("name = %s,age = %d, sex = %c, score = %s\n", t.tea.name, t.tea.age, t.tea.sex, t.phone);
	
	return 0;
}

三、结构体的大小

字节对齐含义:字节对齐主要是针对结构体而言的,通常编译器会自动对其成员变量进行对齐,以提高数据存取的效率;

字节对齐作用:

        平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

        性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

        结构体大小的计算方法:自身对齐、默认对齐、有效对齐。

#include <stdio.h>
 
struct A
{
	char a;
	int b;
	char c;
	char d;
};
 
struct B
{
	char a;
	short b;
	char c;
	char d;
};
 
struct C
{
	char a;
	double b;
	char c;
	char d;
};
 
int main(int argc, const char *argv[])
{
	printf("int = %d,  %d\n",sizeof(int), sizeof(struct A));	
	printf("short = %d,  %d\n",sizeof(short), sizeof(struct B));	
	printf("double = %d,  %d\n",sizeof(double), sizeof(struct C));	
	return 0;
}

四、位域

        所谓的“位域”是把一个字节中的二进制位分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。

位域的一般形式:

        struct 位域结构体名

        {

        位域列表;

        };

其中位域列表的形式为:类型说明符  位域名:位域长度

位域变量的说明:

        struct  位域结构体名  变量名

        struct  位域结构体名  变量名 = {成员1值,成员2值..}

        定义位域结构体时顺便创建变量

#include <stdio.h>
 
struct A
{
	unsigned char a:2;
	unsigned char b:3;
	unsigned char c:3;
}t2 = {2, 3, 1};  //3.定义位域时定义变量
 
int main(int argc, const char *argv[])
{
	printf("%d\n",sizeof(struct A));
	//1.先定义变量再赋值
	struct A t;
	t.a = 1;
	t.b = 2;
	t.c = 3;
 
	printf("%d %d %d\n",t.a, t.b, t.c);
 
	//2.定义变量时进行赋值
	struct A t1 = {2, 1, 3};
	printf("%d %d %d\n",t1.a, t1.b, t1.c);
 
	t2.a = 3;
	t2.b = 1;
	t2.c = 2;
	printf("%d %d %d\n",t2.a, t2.b, t2.c);
	return 0;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值