
例如:
以这种方式定义结构,以后可以定义新变量,例如struct学生Wangwu. 注意: 您不能使用Zhangsan定义新变量. 在这里,张三和李丝都是变量名,而不是结构类型.
方法3: 直接定义结构类型变量
只能在定义结构类型时定义此定义中的结构变量,而不能定义其他变量. 这样定义的结构类型没有名称. 我们还可以使用typedef重命名这种结构类型,例如:
使用typedef后,我们可以使用Zhangsan作为数据类型来定义新变量. 需要注意的是,Zhangsan.num不能直接使用,因为Zhangsan不是变量,而是结构类型.
结构变量初始化:
结构变量的应用
结构中的成员可以像普通变量一样独立使用. 如下例所示,结构变量A中的成员num可以以A.num的方式使用.
结构变量的成员引用: 结构变量名. 成员名
关于结构的注释:
1,不能整体上对结构变量进行操作: printf(“%d,%d \ n”,A);错误scanf(“%d,%d \ n”,&A); //错误printf(“%d,%d \ n”,A.num,A.score); //正确的scanf(“%d,%d \ n”,&Lucy.num,&Lucy.sex); //正确2,当结构变量的成员也是结构类型时,引用必须使用最低级别的成员变量,如下所示:
3,成员名称可以与程序中的变量名称相同,两者代表不同的对象

4. 您可以引用结构变量成员的地址,也可以引用结构变量的地址,例如: scanf(“%d”结构体,&A.num); //输入A.num printf的值(“%d”,&A); //输出Bob的第一个地址用途: 主要用作函数参数结构体,传递结构变量的地址. 5.允许彼此分配相同类型的结构变量. 在其他情况下,则不允许直接分配结构变量.
为自定义数据类型(结构,联合和枚举类型)定义简洁的类型名称
以一个结构为例,下面我们定义一个名为Point的结构:
struct Point {double x; y double z;};
调用此结构时,我们必须像以下代码一样调用此结构:
struct Point oPoint1 = {100,100,0}; struct Point oPoint2;
在这里,结构struct Point是一种新的数据类型. 定义变量时,必须像上面的调用方法一样使用保留字结构. 您不能直接使用Point来定义int和double之类的变量. 现在,我们用typedef定义此结构,如以下代码所示:
typedef struct tagPoint {double x; y double z;}点;
在上面的代码中,实际上完成了两个操作:
1. 定义了一个新的结构类型,代码如下:
struct tagPoint {double x; y double z;};
其中,struct关键字和tagPoint共同构成此结构类型. 无论typedef关键字是否存在,此结构都存在.
2. 使用typedef作为这个称为Point的新结构的别名,即:
typedef struct tagPoint Point
因此,您现在可以直接使用Point来定义变量,例如int和double,如以下代码所示:
点oPoint1 = {100,100,0};点oPoint2;
为了加深对typedef的理解,我们来看一个结构示例,如以下代码所示:
typedef struct tagNode {char * pItem; pNode pNext;} * pNode;

从表面上看,上面的示例代码与先前的定义相同,因此应该没有问题. 但是编译器报告了一个错误,为什么? C语言是否可以在结构中不允许指向自身的指针?
实际上,问题不在于struct的定义. 每个人都应该知道,C语言允许将指针包含在结构中. 我们在实现数据结构(例如链表)时可以看到许多这样的示例. 所以有什么问题?实际上,根本问题在于typedef的应用.
在上面的代码中,在建立新结构的过程中遇到了pNext声明,其类型为pNode. 重要的是在此处注意pNode代表该结构的新别名. 因此出现了问题,当尚未建立结构类型本身时,编译器根本不知道pNode,因为此结构类型的新别名不存在,因此自然会报告错误. 因此,我们需要进行一些适当的调整,例如修改结构中的pNext语句,如下所示:
typedef struct tagNode {char * pItem; struct tagNode * pNext;} * pNode;
或分别定义struct和typedef,如以下代码所示:
typedef struct tagNode * pNode; struct tagNode {char * pItem; pNode pNext;};
在上面的代码中,我们还使用typedef为尚未完全声明的tagNode类型赋予新别名. 但是,尽管C编译器完全支持此做法,但不建议这样做. 建议使用以下规范定义方法:
struct tagNode {char * pItem; struct tagNode * pNext;}; typedef struct tagNode * pNod
计算方法:
The
operator sizeof计算给定类型的大小. 对于32位系统,sizeof(char)= 1; sizeof(int)=4. 基本数据类型的大小易于计算,让我们看看如何计算构造数据类型的大小.
在C语言中,有三种类型的构造数据: 数组,结构和联合.
数组是相同类型元素的集合. 只要计算单个元素的大小,整个数组所占用的空间就等于基本元素的大小乘以元素数.
结构中的成员可以是不同的数据类型,并且成员按照定义的顺序存储在连续的存储空间中. 与数组不同,结构的大小并不是简单地将所有成员的大小相加. 存储结构变量时,需要考虑系统的地址对齐方式. 看一下这样的结构:
struct stu1
{
int i;
字符c;
int j;

};
首先介绍一个相关的概念偏移. 偏移量是指结构变量中成员的地址与结构变量地址之间的差. 结构大小等于最后一个成员的偏移量加上最后一个成员的大小. 显然,结构变量中第一个成员的地址是结构变量的第一个地址. 因此,第一构件i的偏移为零. 第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0 + 4),即4;第三个成员j的偏移量是第二个成员. 成员的偏移量加上第二个成员的大小(4 + 1)的值为5.
实际上,由于在存储变量时地址对齐(现代计算机中的内存空间除以字节,理论上似乎可以从任何地址开始访问任何类型的变量,但是实际情况是访问特定的类型变量通常是在特定的内存地址处访问的,这要求根据特定规则在空间中排列各种类型的数据,而不是一个接一个地顺序排放,这是对齐的.
对齐的作用和原因: 每个硬件平台对存储空间的处理都非常不同. 某些平台只能从某些地址访问某些类型的数据. 例如,某些架构的CPU在访问未对齐的变量时会出错,然后在该架构下进行编程必须确保字节对齐. 其他平台可能没有这种情况,但最常见的是该平台需要对齐数据存储,这将导致访问效率下降. 例如,在某些平台上,每次读取均从偶数地址开始. 如果将int类型(假定为32位系统)存储在偶数地址的开头,则可以在读取周期中读取32位,如果将其存储在奇数地址中,则在开始时将有两个读取周期需要,两次读取结果的高字节和低字节组合在一起以获得32位数据. 显然,阅读效率下降了很多. ),编译器在编译程序时将遵循两个原则: 第一,结构变量中成员的偏移量必须是成员大小的整数倍(0被视为任何数字的整数倍)第二,结构size必须是所有成员大小的整数倍.
与第一个成员相比,上例中前两个成员的偏移量满足要求,但第三个成员的偏移量为5,这不是其自身(int)大小的整数倍. 处理时,编译器将在第二个成员之后追加3个空字节,以使第三个成员的偏移量变为8.
与第二个相比,结构的大小等于最后一个成员的偏移量加上它的大小. 上例计算得出的大小为12,符合要求.
看看遇到第一个而不是第二个的情况
struct stu2
{
int k;
短t;
};
成员k的偏移量为0;成员t的偏移为4,无需进行任何调整. 但是计算得出的大小为6,这显然不是成员k大小的整数倍. 因此,编译器将在成员t之后追加2个字节,以使结构大小8满足第二个要求. 可以看出,每个人在定义结构类型时都需要考虑字节对齐. 不同的顺序将影响结构的大小. 比较下面的两个定义
struct stu3
{
char c1;
int i;
char c2;
}

struct stu4
{
char c1;
char c2;
int i;
}
尽管stu3和stu4的成员相同,但是sizeof(结构stu3)的值为12,sizeof(结构stu4)的值为8.
如果一个结构的成员是另一个结构类型怎么办?只是扩大它. 但是,应注意,扩展结构的第一成员的偏移应为扩展结构的最大成员的整数倍. 看下面的例子:
struct stu5
{
简短的我;
结构
{
字符c;
int j;
} ss;
int k;
}
结构stu5的成员ss.c的偏移量应为4,而不是2. 整个结构应为16.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-162240-1.html
产品价高质次
好坏好坏的
首先我们实力已经显著增强