我眼中的结构体

一,结构体的定义

聚合数据类型:能够同时存储超过一个的单独数据(例如C语言中的数组和结构体)

结构体是一些值的集合,这些值成为它的成员,既是一种自定义类型,也是一种聚合数据类型。

二,结构体的声明及具体使用

1,声明

在声明结构体时,必须列出它包含的所有成员。

struct A 
{ 
  int a;
 char c; 
};

 
 

A仅仅为一个标签,单独的A并不是结构体的类型,struct A才是。a,c为它的成员列表,一定注意后面的分号千万不能丢,没有就出错了。

struct A

{
      int a;
      char c;
}sa1,sa2;

又如这种形式,sa1和sa2是结构体的变量列表,如果没有标签的话,记得一定要有,否则还是错的。

那么,想要在外部定义一个结构体类型的变量又该怎么做呢?

struct A s;
 

好像依旧很麻烦,因为struct还是不能省略,于是,我们又想到了另一个办

typedef  struct S
{
     int a;
     char name[10];
     char c;
}S;
 
这样,我们就可以省略struct了,巧妙地运用类型重命名typedef解决了此问题,有木有很棒呢。 
S s; 
S *ps;
 
声明完成之后,该怎样对它进行赋值呢? 
 

2.初始化

s.a=10;s.name="zhangsan";s.c='w';

 

是这样吗,看似好像没什么问题,然而是no,给你说什么来着,数组名代表数组首元素的地址,看看你又忘了,没好好复习吧,该罚,嘻嘻。当然,你怎么能将一个常量字符串赋给一个地址呢,这样做当然是不对滴。那到底怎样才算对呢,听我细细给你道来.

strcpy(s.name,"zhangsan");

 
又比如 
ps=&s;
 
 

这样一来,我们就可以通过两种方式来访问其内部成员

strcpy(ps-->name,"zhangsan");
strcpy((*ps).name,"zhangsan");

当然,两种方式的效果是一样一样的!

整体初始化:

S s={10,"zhangsan",'w'};
 
 
3.嵌套 
typedef struct S 
{
	int a;
	char c;
}S;
typedef struct Stu
{
	char name[10];
	int age;
	S s;
     char tele[20];
}Stu;


 
 

可通过S.s.a访问S中的成员a,由此可见,结构体内部的多层嵌套可通过‘.’来访问。

初始化则为:

Stu s={"liming",16,{15,'q'},"7417147474741"};


4.结构体的自引用

typedef struct Node
{
	int data;
	struct Node *next;
}Node;

注意成员列表中的struct不能省略

5.不完整的声明

struct B;

struct A
{
	struct B *pb;
};

struct B
{
	struct A* pa;
};
 
因为B中用到了A,A中又用到了B,所以当中必须有一个委曲求全一下,例如B,做了一个不完整的声明 

三,结构体的存储分配----->内存对齐

typedef struct A
{
     char c;
     int i;
}A;
 

你觉得会输出几呢?如果你想的是5,那就错了,因为你没考虑到他的内存对齐,正确结果是8.再看一下下面一段代码:

typedef struct A
{
     char c;
     char d; 
     int i;
}A;


你可能说,上次忘了考虑内存对齐,这次不会了,于是你信誓旦旦的说答案是12,结果是你又错了,答案仍然是8,让我来给你讲讲为什么吧!

首先,我们从两个角度考虑进行分析。

(1)为什么要内存对齐?

(2)内存对齐后,如何求取结构体大小?

在这里,我们需要提到几个新概念

默认对齐数:每个环境下均不相同chengyuan

                     VC------>8          VS------->8            LINUX-------->4

对齐数:成员自身大小和默认对齐数的较小值

偏移数:成员变量在内存中偏移的字节数

规定每个成员必须放到其对齐数的倍数位置处

结构体的大小必须是最大对齐数的倍数


此结构体的大小为8



此结构体的大小仍为8


下面介绍一下结构体中嵌套结构体的内存对齐

此结构体的大小为32。



此结构体大小为40,因为结构体的大小必须为整体最大对齐数的倍数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值