-
2020-11-16 20:52:11
目录
概念
结构体变量是指将不同的数据类型整合成一个有机的整体,以便于调用。
struct Student { int num; char name[20]; int score; } Student stud1;//stud1就是结构体变量
结构体指针变量是指指向结构体变量的指针或者指向结构体数组的指针。
Student *stud2;//结构体指针变量
内存分配
在C语言中都是使用库函数malloc和free来分配和撤销内存空间的。C++中提供了较简便而功能较强的运算符new和delete来取代函数malloc和free函数。注意:new和delete是运算符,不是函数。
int main { Student *p p = new Student //用new运算符开辟一个存放Student型数据的空间 . . . delete p; //使用完之后一定要撤销该空间 return 0; }
对象的引用
结构体变量引用成员变量的方式是:
结构体变量名.成员变量名
指针引用结构体变量成员的方式是:
(*指针变量名).成员变量名 //*指针变量名 两边的括号不可以省略 指针变量名->成员名 //->”是“指向结构体成员运算符”,它的优先级同结构体成员运算符“.”一样高。
结构体变量和结构体指针变量作形参的区别
结构体变量作为函数形参。此时sc_para和tm_para传递的是两个结构体变量,包含其内部所有的成员变量,占用的内存空间自然而然就大,具体大小取决于结构体变量的大小。
int REF_STRUCT_PARAM( SC_PARAMS sc_para, TM_PARAMS tm_para ) //SC_PARAMS和TM_PARAMS是两个结构体类型
结构体指针变量作为函数形参。此时*sc_para和*tm_para传递的是两个指针变量,一个指针只占用四个字节空间,而且存储的是结构体变量的首地址。修改为指针后速度变快,占的内存空间也减小。
int REF_POINTER_PARAM( SC_PARAMS* sc_para, TM_PARAMS* tm_para ) //SC_PARAMS和TM_PARAMS是两个结构体类型
以结构体变量和结构体指针变量形参的函数调用
以结构体变量作形参的函数的调用,函数形参部分直接调用定义的结构体名即可。
int main { SC_PARAMS sc_para; TM_PARAMS tm_para; int REF_STRUCT_PARAM(sc_para, tm_para); //SC_PARAMS和TM_PARAMS是两个结构体类型 return 0; }
以结构体指针变量作形参的函数的调用,函数形参位置要引用结构体地址。
int main { SC_PARAMS* sc_para; TM_PARAMS* tm_para; int REF_POINTER_PARAM(&sc_para, &tm_para); //SC_PARAMS和TM_PARAMS是两个结构体类型 return 0; }
更多相关内容 -
结构体内存对齐:如何计算结构体变量的大小
2021-11-19 15:44:21结构体内存对齐:如何计算结构体变量的大小一、 掌握结构体的对齐规则二、例子分析 一、 掌握结构体的对齐规则 1、第一个成员在与结构体变量偏移量为0的地址处。 2、其他成员变量要对齐到某个数字(对齐数)的整数倍...结构体内存对齐:如何计算结构体变量的大小
一、 掌握结构体的对齐规则
1、第一个成员在与结构体变量偏移量为0的地址处。
2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数=编译器默认的一个对齐数与该成员的大小进行比较得出的较小值
vs(博主使用的编译器)中默认为8 gcc当中没有默认对齐数,此时对齐数为成员变量大小。
3、结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。二、例子分析
代码显示:
struct S1 { char c1;//第一个成员变量,在与s1变量偏移量为0的地址处 int a;//int 类型内存大小为4,与8相比,4位第二个成员变量的对齐数,在与s1变量偏移量为4的整数倍的地址处 char c2;//第三个成员变量,char类型 内存大小为1,与8相比,对齐数为1,在与s1偏移量为1的整数倍的地址处 //最后结构体的总大小为最大对齐数即(1,4,1)中最大数4的整数倍 }; struct S2 { char c1; char c2; int a; }; int main() { struct S1 s1 = { 0 }; printf("%d\n", sizeof(s1));//计算结构体变量s1的内存大小 struct S2 s2 = { 0 }; printf("%d\n", sizeof(s2));//计算结构体变量s2的内存大小 return 0; }
结果:
(1)s1的计算过程:
如图,变量s1在内存中开辟一个空间,c1是第一个成员变量,在与结构体变量为0的地址处(红色区域为c1所占内存空间)。a为s1的第二个成员变量(int 类型),它的大小为4字节,对齐数为4(与8比较),位于与s1偏移量为4(4的整数倍)的地址处(紫色区域),c1与a之间的空白为浪费的空间。c2的对齐数为1,它在与s1偏移量为9(1的整数倍)的地址处(粉色区域),因为现在的结构体大小为9,而结构体的总大小要为最大对齐数(4)的整数倍,所以我们还要浪费三个字节的空间,因此此时s1的总大小为12字节。
(2)s2的计算过程:
如图,变量s2在内存中开辟一个空间,c1是第一个成员变量,在与结构体变量为0的地址处(红色区域为c1所占内存空间)。c2为s1的第二个成员变量(char类型),它的大小为1个字节,对齐数为1(与8比较),位于与s1偏移量为1(1的整数倍)的地址处(绿色区域)。a的对齐数为4(与8比较),它在与s1偏移量为4(4的整数倍)的地址处(紫色区域),c2与a之间的空白为浪费的空间,因为现在的结构体大小为8,是最大对齐数(4)的整数倍,所以此时s2的总大小就为8。嵌套结构体变量
代码显示:
struct S3 { double d;//8 char c;//1 int i;//4 }; struct S4 { char c1;//1 struct S3 s3;//对齐数为S3中各对齐数的最大对齐数即max(8,1,4) double d;//8 }; int main() { struct S3 s3 = { 0 }; printf("%d\n", sizeof(s3));//计算结构体变量s3的内存大小 struct S4 s4= { 0 }; printf("%d\n", sizeof(s4));//计算嵌套结构体变量s4的内存大小 return 0; }
结果:
(3)s3的计算过程:
如图,变量s3在内存中开辟一个空间,d是第一个成员变量,在与结构体变量为0的地址处(红色区域为d所占内存空间)。c为s3的第二个成员变量(char类型),它的大小为1个字节,对齐数为1(与8比较),位于与s3偏移量为8(1的整数倍)的地址处(绿色区域)。i的对齐数为4(与8比较),它在与s3偏移量为12(4的整数倍)的地址处(蓝色区域),紫色区域为浪费的空间,因为现在的结构体大小为16,是最大对齐数(8)的整数倍,所以此时s3的总大小就为16。(4)嵌套结构体变量s4的计算:
如图,变量s4在内存中开辟一个空间,c1是第一个成员变量,在与结构体变量为0的地址处(蓝色区域为c1所占内存空间)。s3为s4的第二个成员变量(结构体 类型),s3的对齐数为s3中所有对齐数中最大的对齐数(即max(8,1,4))8,位于与s4偏移量为8(8的整数倍)的地址处(绿色区域)。红色区域为浪费的空间。d的对齐数为4(与8比较),它在与s4偏移量为24(4的整数倍)的地址处(紫色区域),因为现在的结构体大小为32,是最大对齐数(8)的整数倍,所以此时s4的总大小就为32。 -
结构体变量在内存中的位置关系,结构体的对齐结构体的大小
2021-09-04 11:52:03结构体变量才包含数据存储的空间; 2,结构体与数组相似但数组中的数据类型全部相同,结构体中的数据类型不一定相同; 3,结构体变量在内存中的位置关系(不考虑内存对齐的问题) #include struct Student { char s_...1,结构体是一种自己定义的数据类型;是创建变量的模板;不占有内存空间;结构体变量才包含数据存储的空间;
2,结构体与数组相似但数组中的数据类型全部相同,结构体中的数据类型不一定相同;
3,结构体变量在内存中的位置关系(不考虑内存对齐的问题)#include struct Student { char s_id[8]; char s_name[8]; char s_sex[5]; int s_age; }Student; int main() { int a=10,b=20; Student s1={"10906","ljl","man","18"}; return 0; } 内存分布如下
#include<stdio.h> struct Student { 注意vs2019不支持(vs2012支持) char *s_id; char *s_name; char *s_sex; int *s_age; 2019应写为 const char *s_id; const char *s_name; const char *s_sex; int s_age; }Student; int main() { int a=10,b=20; Student s1={"10906","ljl","man","18"}; return 0; } 内存分布如下
4,结构体的自定义会导致程序崩溃5,结构体的嵌套
#include<stdio.h> #include<string.h> struct Date { int year; int month; int day; }; struct Student { char s_id[8]; char s_name[8]; cahr s_sex[5]; struct Date brithday; int s_age; }Student; int main() { int a=10,b=20; Student s1={"10906","ljl","man",{1999,07,08},"18"}; 或者不加{} Student s1={"10906","ljl","man",1999,07,08,"18"}; return 0; }
6.相同的结构体变量可以相互赋值
#include<stdlib.h> #include<string.h> struct Student { char s_id[8]; char s_name[8]; cahr s_sex[5]; int s_age; }Student; int main() { int a=10,b=20; Student s1={"10906","ljl","man","18"}; Student s2,s3; s2=s1; s3=s2; 但是不可以进行以下操作(数组不可以相互赋值) s2.s_id=s1.s_id; strcpy_s(s2.s_id,s1.s_id); return 0; }
结构体为什么要采用对齐方式:
1,cpu并非逐字节的读写内存而是以2,4,或8的倍数的字节快来读取
例如:有一个int类型从三字节开始存放,cpu以2的倍数访问就需要4次才可以读取完该int类型的变量;
2,有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
3,不同的平台采用的对齐方式可能就会不同,因此同样的结构体在不同的平台可能大小也不相同;计算结构体大小的三条规则:
1,结构体变量的首地址必须是结构体变量中最大的基本数据类型所占字节的整数倍;
2,结构体中的每个成员相对于结构体首地址的偏移量都必须是每个变量本身基本数据类型所占字节个数的整数倍;
3,结构体变量的总大小为结构体中最大变量其基本数据类型所占字节数的整数倍;
例如:
1,大小 为12struct node { char a; int b; char c; };
2,大小为24
struct node { char a; double b; char c; };
3,大小为8
4,结构体的嵌套大小为40
注意上图中最大基本类型仍为8,在处理birthday时应偏移量与data结构体中的最大类型
5,结构体大小为48
6,结构体大小为80
7,计算结构体成员的偏移量允许设计结构体变量 #include <stdio.h> struct Eemployr { char a[27]; char b[30]; long int c; long int d; double e; }; int main() { struct Eemployr s; int offer=(char*)&s.d-(char*)&s; printf("%d",offer); return 0; } 打印结果为64 不允许设计结构体变量 #include <stdio.h> struct Employr { char a[27]; char b[30]; long int c; long int d; double e; }; int main() { 将0强转为结构体指针类型在指向d之后再将其地址强转为整型; int offer=(int)&((struct Employr *)0)->d; printf("%d",offer); return 0; } 打印结果为64 #define(type,exa) ((int)&((struct *)0)->exa)
-
【C/C++】一个结构体变量占多大内存空间的问题
2018-10-24 11:25:26原文链接:... 一个结构体变量占多大内存空间的问题 直接来看相同数据结构体的几种书写的格式吧。 格式一: 1. struct tagPhone 2. { 3. char A; 4. int B; 5. ...原文链接:http://blog.sina.com.cn/s/blog_75a2ecd20102xca0.html
一个结构体变量占多大内存空间的问题
直接来看相同数据结构体的几种书写的格式吧。
格式一:
1. struct tagPhone
2. {
3. char A;
4. int B;
5. short C;
6. }Phone1;
格式二:
1. struct tagPhone
2. {
3. char A;
4. short C;
5. int B;
6. }Phone2;
格式三:
1. struct tagPhone3
2. {
3. char A;
4. char B[2];
5. char C[4];
6. }Phone3;
格式四:
1. struct tagPhone3
2. {
3. char A;
4. double B[2];
5. char C[4];
6. }Phone4;
例题:请问下面定义的结构体变量aa在计算机内存中占用多少字节?
#include
main()
{
struct student
{ float height;
short int age ;
char sex ;
}aa;
printf("%d\n",sizeof(aa)); //屏幕上将显示多少?
}
错误解答:我们都知道,char类型占用1个字节,float型占用4个字节,short int类型占用2个字节,int型在VC6.0中占用4个字节(TC2.0中占用2个字节),long占用8个字节,double占用8个字节。因此,我们可能会犯一个错误就是直接4+2+1=7,结构体aa占用7个字节。这是错的。
错误分析:计算结构体大小时需要考虑其内存布局,编译系统为了提高计算机访问数据的效率,在安排结构体每个成员的时候采用了内存对齐的方法,具体是:结构体在内存中的存放按单元进行存放,每个单元的大小取决于结构体中最大基本类型的大小。
对格式一:
因为所有成员中B成员类型最大(int型占用4个字节),故结构体Phone1在内存分布时以4字节为一个单元来存储每个成员。又因为A占用一个字节后,只剩下3字节了,放不下后面紧挨的成员B了,所以必须开辟一个新的单元来存放B,B刚好占满一个单元,接下来的成员C又必须再开辟一个新的单元来存放。这样,Phone1占用的字节数就是:3*4=12;
同理对于格式二,
A后面还有三个字节,足够存放C,所以C就放在了A的后面,然后只剩下一个字节了,不够存放后面的B,于是又开辟一个新单元存放B。这样,Phone2占用的内存字节就为2*4=8。
对于格式三:
上面结构体中,最大数据类型是char,占一个字节,因此它的一个存储单元就是1个字节。sizeof(Phone3) =1 + 2 + 4 = 7, 其大小正好是结构体中各成员所占内存空间之和,这种情况也是最节省存储空间的。
对于格式四:
Phone4中最大的数据类型是double,占8个字节,因此它的一个存储单元就是8个字节。由上图可知sizeof(Phone4)=4*8=32。
综上所述,格式一和格式四是非常浪费存储空间的,应该尽力避免;格式三对存储空间的利用率是最高的;格式二存储空间的利用率居中。作为一个优秀的程序员,应该深入掌握这些写法的差异性,以便视情况选用不同的写法。
-
【C 语言】结构体 ( 结构体类型定义 | 结构体类型别名 | 声明结构体变量的三种方法 | 栈内存中声明结构体...
2021-12-01 10:25:54一、结构体类型定义、 二、结构体类型别名、 三、结构体类型变量声明、 1、使用结构体类型 ( 别名 ) 声明变量、 2、 定义隐式结构体时声明变量、 3、定义普通结构体时声明变量、 二、完整代码示例、 -
C语言结构体变量和结构体数组-学习笔记(十六)
2021-07-20 22:54:53将不同类型的数据组合成一个有机的整体即为结构体。结构体由许多组织在一起的数据项组成,这些数据项不需要属于同一类型。 2、结构体类型及结构体变量定义 (1)结构体类型声明 struct 结构体名 { 成员表列; }; ①–... -
结构体变量
2021-08-09 11:08:09结构是由程序员自己设计的数据类型,用于描述一个事物的各项数据,由若干个不同的基础类组成。 设计: struct 结构体名 { 类型1 成员名1; 类型2 成员名2; … }; 定义结构变量: struct 结构体名 变量名 注意:在... -
【C语言】结构体类型和结构体变量(字节对齐)
2020-10-19 22:22:33结构体是一种构造数据类型,可以把不同类型的数据整合在一起,每一个数据都称为该结构体类型的成员。使用结构体时,首先需要对结构体类型进行定义,结构体类型的定义如下所示: struct 结构体类型名称 { 数据... -
coderit666#CNote#26.结构体变量占用存储空间大小1
2022-07-25 14:09:11结构体变量占用存储空间大小占用内存最大属性是score, 占8个字节, 所以第一次会分配8个字节将第一次分配的8个字节分配给age4个,分配给ch1个, 还剩下 -
C语言中结构体变量到底占多大空间
2018-09-07 21:56:30很久之前就想将内存对齐这块儿知识点总结记录下来,无奈本人患有very very严重的拖拉症,直到今天才下... 结构体到底占多大的空间呢?先看一下下面这道题的输出结果: #include<stdio.h> typed... -
结构体变量和结构体类型的定义
2019-08-02 16:43:19结构体类型定义 定义方式1: Typedef struct LNode { int data; // 数据域 struct LNode *next; // 指针域 } *LinkList; 定义方式2: struct LNode { int data; // 数据域 struct LNode *next; // 指针域 }; ... -
关于结构体的变量内存大小问题
2020-03-01 23:41:42我们知道,struct结构体中可以有不同的数据类型变量,成员定义时依次存储在内存连续的空间,struct结构体变量的首地址就是第一个成员的地址,那么内存偏移量就是各个成员相对于结构体变量地址的... -
结构体变量内存分配问题
2019-03-09 08:44:442.结构体变量内存的总大小必须为sizeof(结构体成员变量)(最大的)的整数倍。 struct Demo{ char a;//sizeof(char)=1 int b;//sizeof(int)=4 flloat c;//sizeof(float)=4 double d;//sizeof... -
结构体、结构体变量、结构体指针、字符串
2021-06-12 15:45:09结构体 数组是用于保存一组相同类型数据的, 而结构体是用于保存一组不同类型数组的 在使用结构体之前必须先定义结构体类型, 因为C语言不知道你的...结构体变量占用存储空间大小 struct Person{ int age; // 4 第 -
结构体变量和结构体指针
2020-07-17 11:20:50结构体变量分配结构体本身大小的空间,结构体指针分配4个字节,其实任何类型的指针都是分配四个字节的指针空间。 所以: A a[3]; //a里面是三个A变量,所以分配三个结构体大小 A *a; //a是一个指针,分配4个字节,... -
c语言之结构体变量的定义
2021-05-20 09:09:38结构体是一种数据类型(像int、char、flaot是数据类型一样),可以用它定义变量。用结构体类型定义变量的方式有三种:一、先定义结构体类型,再定义变量一般形式:struct 结构体名{类型标识符 成员名;类型标识符 成员... -
结构体的大小如何计算?
2020-08-13 14:44:21一,结构体变量的首地址,必须是结构体 "最宽基本类型成员" 大小的整数倍。 二,结构体每个成员相对于结构体首地址的偏移量,都是该成员的整数倍。  .. -
基础电子中的如何计算结构体的大小
2020-11-12 04:58:56作者:曾宏安,华清远见嵌入式学院高级讲师。 运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof...和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体 -
【掌握结构体类型的定义、结构体变量的初始化、赋值与成员访问】(学习笔记13--结构体)
2022-03-14 17:03:39定义无名结构体类型变量结构体变量的初始化与赋值结构体成员的访问结构体的大小结构体的嵌套 前言 变量可以用来存储单个数据,数组可以用来存储一组同类型的数据,但它们都只适合单一属性的数据。结构体属于复合... -
【C++】结构体变量与结构体指针大小区别(Socket sendto函数)
2019-12-25 18:02:53代码如下 # include "stdafx.h" # include ..."结构体变量" ...//结构体变量 ...结构体指针变量与结构体大小不同,下图中,填入sendto函数最后一个参数应该是结构体变量SOCKADDR,而非结构体指针 -
C语言 struct 结构体类型名> 结构体变量名
2021-09-26 16:35:14#include<stdio.h> int main(int argc, char* argv[]) { char name[20] = "旺财"; char dogclass = 'A';...结构体类型名> { <成员类型1> <成员变量名1>; <成员类型2>. -
C语言 如何计算结构体的大小
2020-11-24 16:24:362、结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节的整数倍。(对齐) 3、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节数”的整数倍(补齐) 计算下面... -
C语言中结构体的对齐规则、sizeof(结构体变量)
2021-10-31 18:53:37结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的的整数倍的地方(比如int在32位机器上为4字节,则要从四字节的整数倍开始存储)。考虑如下一段... -
C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?
2017-07-15 14:24:33C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题? -
结构体的大小(不同的顺序会影响结构体的大小)
2018-12-25 19:29:431、结构体变量中该成员的偏移量必须是该成员大小的整数倍(0被认为是任何数的整数倍) 2、结构体大小必须是所有成员大小的整数倍。 注意:1.先根据系统位数、编译器位数判定结构体中成员变量自身的大小; 2.该... -
结构体大小的计算方法
2021-06-09 19:59:101.第一个成员在与结构体变量偏移量为0的地址处。 2.其他成员变量要对齐到对齐数的整数倍的地址处。对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。 VS中默认的值为8 3.结构体总大小为最大对齐数(每个成员... -
结构体变量之间的比较和赋值原理
2018-09-08 09:27:25结构体变量之间可以直接赋值我想大家都知道了。...很多人说那可以自己写个函数啊,自己想怎么实现就怎么实现,况且写个结构体变量之间的比较程序又不是什么难事。但我想问的是你遇到的结构体里面的成员才多少个... -
结构体大小如何计算?
2019-07-26 19:10:31一,结构体变量的首地址,必须是结构体 "最宽基本类型成员" 大小的整数倍(0被认为是任何数的整数倍)。 二,结构体每个成员相对于结构体首地址的偏移量,都是该成员的整数倍。 三,结构体的总大小,为结构体 “最宽...