c语言结构体与共用体之间的区别
- 格式:doc
- 大小:41.50 KB
- 文档页数:4
c语言结构体共用体数据类型求大小例题(原创版)目录一、C 语言结构体和共用体的概念二、结构体和共用体的大小计算方法三、例题解析四、总结正文一、C 语言结构体和共用体的概念C 语言中,结构体和共用体是两种特殊的数据类型,它们都可以用来描述一个复合数据类型。
结构体和共用体的主要区别在于它们存储数据的方式不同。
结构体是一种复合数据类型,它可以包含多个不同类型的成员变量。
结构体中的成员变量按照定义的顺序排列,并且每个成员变量都有一个唯一的名字。
结构体可以看作是一个数据容器,它可以存储多个相关类型的数据。
共用体是一种特殊的结构体,它的每个成员变量都共享同一段内存空间。
共用体的每个成员变量都有一个基地址,它们之间的关系是连续的。
共用体的大小等于其最大成员变量的大小。
二、结构体和共用体的大小计算方法结构体和共用体的大小计算方法相同,都是按照定义的顺序依次计算每个成员变量的大小,并累加得到总体大小。
需要注意的是,结构体和共用体的大小通常会进行对齐处理,以提高数据访问的效率。
三、例题解析假设有一个结构体如下:```cstruct example {int a;char b;float c;};```首先,我们需要知道每个成员变量的大小。
在 32 位系统下,int 类型占用 4 个字节,char 类型占用 1 个字节,float 类型占用 4 个字节。
因此,结构体 example 的大小为:```size = 4(int a 的大小) + 1(char b 的大小) + 4(float c 的大小)= 9```接下来,我们需要考虑对齐问题。
在 32 位系统下,数据对齐的粒度是 4 个字节。
因此,结构体 example 的大小应该为 4 的倍数。
由于 9 不是 4 的倍数,所以需要进行对齐处理。
将结构体 example 的大小调整为 12,这样每个成员变量都可以从 4 的倍数地址开始存储。
```size = 12```因此,结构体 example 的大小为 12 字节。
C语⾔共⽤体(Union)结构体和共⽤体的区别在于:结构体的各个成员会占⽤不同的内存,互相之间没有影响;⽽共⽤体的所有成员占⽤同⼀段内存,修改⼀个成员会影响其余所有成员。
结构体占⽤的内存⼤于等于所有成员占⽤的内存的总和(成员之间可能会存在缝隙),共⽤体占⽤的内存等于最长的成员占⽤的内存。
共⽤体使⽤了内存覆盖技术,同⼀时刻只能保存⼀个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
共⽤体也是⼀种⾃定义类型,可以通过它来创建变量,例如:1. union data{2. int n;3. char ch;4. double f;5. };6. union data a, b, c;上⾯是先定义共⽤体,再创建变量,也可以在定义共⽤体的同时创建变量:1. union data{2. int n;3. char ch;4. double f;5. } a, b, c;如果不再定义新的变量,也可以将共⽤体的名字省略:1. union{2. int n;3. char ch;4. double f;5. } a, b, c;共⽤体 data 中,成员 f 占⽤的内存最多,为 8 个字节,所以 data 类型的变量(也就是 a、b、c)也占⽤ 8 个字节的内存,请看下⾯的演⽰:1. #include <stdio.h>2.3. union data{4. int n;5. char ch;6. short m;7. };8.9. int main(){10. union data a;11. printf("%d, %d\n", sizeof(a), sizeof(union data) );12. a.n = 0x40;13. printf("%X, %c, %hX\n", a.n, a.ch, a.m);14. a.ch = '9';15. printf("%X, %c, %hX\n", a.n, a.ch, a.m);16. a.m = 0x2059;17. printf("%X, %c, %hX\n", a.n, a.ch, a.m);18. a.n = 0x3E25AD54;19. printf("%X, %c, %hX\n", a.n, a.ch, a.m);20.21. return 0;22. }运⾏结果:4, 440, @, 4039, 9, 392059, Y, 20593E25AD54, T, AD54这段代码不但验证了共⽤体的长度,还说明共⽤体成员之间会相互影响,修改⼀个成员的值会影响其他成员。
浅谈C语⾔共⽤体和与结构体的区别
共⽤体与结构体的区别
共⽤体:
使⽤union 关键字
共⽤体内存长度是内部最长的数据类型的长度。
共⽤体的地址和内部各成员变量的地址都是同⼀个地址
结构体⼤⼩:
结构体内部的成员,⼤⼩等于最后⼀个成员的偏移量+最后⼀个成员⼤⼩+末尾的填充字节数。
结构体的偏移量:某⼀个成员的实际地址和结构体⾸地址之间的距离。
结构体字节对齐:每个成员相对于结构体⾸地址的偏移量都得是当前成员所占内存⼤⼩的整数倍,如果不是会在成员前⾯加填充字节。
结构体的⼤⼩是内部最宽的成员的整数倍。
共⽤体
#include <stdio.h>
//gcc让不同类型的变量共享内存地址 ,同⼀时间只有⼀个成员有效
union data{
int a;
char b;
int c;
};
int main(){
union data data_1 = {1};//初始化时只填写⼀个值。
(同⼀时间只有⼀个成员有效)
data_1.b = 'c';
data_1.a = 10;//后赋值的才有效。
前⾯的赋值被覆盖
//打印地址,发现指向同⼀个地址
printf("%p\n%p\n%p\n",&data_1.a,&data_1.a,&data_1.a);
return 0;
}
以上这篇浅谈C语⾔共⽤体和与结构体的区别就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
C语言知识总结——宏,枚举,结构体,共用体1、define宏定义以#号开头的都是编译预处理指令,它们不是C语言的成分,但是C程序离不开它们,#define用来定义一个宏,程序在预处理阶段将用define定义的来内容进行了替换。
因此在程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存。
define定义的常量,预处理时只是直接进行了替换,,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。
,因此在编译时它不对宏的定义进行检查,作用域不影响对常量的访问。
它的常量值只能是字符串或数字。
该命令有两种格式:一种是简单的常量宏定义, 另一种是带参数的宏定义。
不带参数的宏:#define< 名字 >< 值 > 要注意,没有结尾的分号,因为不是C的语句,名字必须是一个单词,值可以是各种东西,宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。
如有错误,只能在编译已被宏展开后的源程序时发现。
注意.宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。
宏定义其作用域为宏定义命令起到源程序结束。
如要终止其作用域可使用#undef命令带参数的宏:像函数的宏,一般的定义形式:带参宏定义的一般形式为:「#define 宏名」(形参表)字符串,也是没有结尾的分号,可以带多个参数,#define NB(a,b)((a)>(b)?(b):(a)), 也可以组合(嵌套)使用其他宏,注意带参数宏的原则一切都要有括号,参数出现的每个地方都要有括号。
带参数的宏在大型的程序的代码中使用非常普遍,在#和##这两个运算符的帮助下可以很复杂,如“产生函数”,但是有些宏会被inline函数代替(C++的函数)使用宏好处:“提高运行效”。
定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。
结构体与共用体笔记定义结构体C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体(structre)。
在其他一些高级语言中称为“记录”.定义后的结构体类型和系统提供的标准类型(如int, char, float, double 等)具有相似的作用,都可以用来定义变量,只不过int等类型是系统已声明的,而结构体类型是由用户根据需要在程序中指定的。
定义一个结构体类型的一般形式为:struct 结构体名{ 成员表列};注意:1.结构体类型的名字是由一个关键字struct和结构体名组合而成的(例如struct Student) ,结构体名是由用户指定的,又称“结构体标记”,以区别于其他结构体类型。
上面的结构体声明中Student就是结构体名(结构体标记)。
2.花括号内是该结构体所包括的子项,称为结构体的成员。
“成员表列"(member list)也称为“域表”(field list),成员表列由若干个成员组成,每一个成员是结构体中的一个域。
对每个成员也必须作类型说明,其形式为:类型说明符成员名;成员名的命名应符合标识符的书写规定。
例如:struct stu{int num;char name[20];char sex;float score;};3.一个结构体的成员可以属于另一个结构体类型(嵌套)。
例如:struct Date //声明一个结构体类型struct Date{ int month;//月int day;//日int year;//年}struct Student//声明一个结构体类型struct Student{ int num;char name[20];char sex;int age;struct Date birthday;//成员birthday属于struct Date 类型char addr[30];};结构体类型变量1.定义结构体类型变量说明结构变量有以下三种方法。
C语言结构体共用体和动态内存分配共用体是一种特殊的数据类型,可以存储不同类型的数据,但是同一时间只能存储其中的一个成员。
共用体的内存空间是所有成员的最大字节长度。
动态内存分配是在程序运行时,根据需要动态地分配和释放内存空间。
下面将详细介绍C语言中的结构体、共用体和动态内存分配。
结构体是C语言中一种用户自定义的数据类型,它可以同时存储不同类型的数据,使得数据处理更加灵活方便。
结构体由多个不同类型的成员变量组成,每个成员变量可以拥有不同的数据类型。
结构体的定义以关键字struct开头,后面是结构体名称及其成员变量列表。
以下是一个结构体的例子:```cstruct Personchar name[20];int age;float height;};```定义了一个名为Person的结构体,包含了三个成员变量:name、age 和height。
其中name是一个字符数组,age是一个整数,height是一个浮点数。
我们可以通过`.`操作符访问结构体的成员变量:```cstruct Person p;strcpy(, "Tom");p.age = 20;p.height = 1.80;```上述代码中,我们定义了一个结构体Person的变量p,并为其成员变量赋值。
而共用体(union)是一种特殊的数据类型,它可以在相同的内存空间中存储不同的数据类型。
共用体的定义以关键字union开头,后面是共用体名称及其成员变量列表。
以下是一个共用体的例子:```cunion Dataint num;char name[20];float marks;};```定义了一个名为Data的共用体,包含了三个成员变量:num、name 和marks。
共用体的大小取决于其中最大的成员变量,以便为最大的成员分配足够的存储空间。
我们可以通过`.`操作符访问共用体的成员变量:union Data d;d.num = 10;strcpy(, "John");d.marks = 85.5;```上述代码中,我们定义了一个共用体Data的变量d,并为其成员变量赋值。
结构体和共用体注意事项以结构体和共用体为主题,本文将介绍一些需要注意的事项。
结构体和共用体是C语言中非常重要的数据类型,它们可以用来组织和存储不同类型的数据。
在使用结构体和共用体时,需要注意以下几点。
一、结构体的定义和使用结构体是一种自定义的数据类型,它能够将不同类型的数据组合在一起。
在定义结构体时,需要使用关键字struct,并为结构体定义一个名称。
结构体中的成员可以是不同的数据类型,可以是基本类型(如int、float等),也可以是其他结构体类型。
在使用结构体之前,需要先定义结构体的类型。
定义结构体类型的方式如下:```struct Student {char name[20];int age;float score;};```在定义结构体类型后,可以使用该类型创建结构体变量,并对结构体的成员进行赋值。
例如:```struct Student stu1;strcpy(, "Tom");stu1.age = 18;stu1.score = 90.5;```需要注意的是,在访问结构体的成员时,需要使用点操作符(.)来访问成员。
例如,访问stu1的name成员可以使用``,访问stu1的age成员可以使用`stu1.age`。
二、共用体的定义和使用共用体(union)与结构体类似,也是一种自定义的数据类型,可以将不同类型的数据组合在一起。
不同之处在于,共用体的所有成员共享同一块内存空间。
共用体的定义方式与结构体类似,也需要使用关键字union,并为共用体定义一个名称。
共用体中的成员可以是不同的数据类型,但是共用体的所有成员共享同一块内存空间。
使用共用体时,需要注意以下几点:1. 共用体的所有成员占用的内存空间是相同的,因此共用体的大小等于最大成员的大小。
2. 在给共用体的成员赋值时,只能对一个成员进行赋值,对其他成员的赋值会改变已经赋值的成员的值。
下面是一个共用体的定义和使用的示例:```union Data {int num;char ch;float score;};```在定义共用体类型后,可以使用该类型创建共用体变量,并对共用体的成员进行赋值。
/2005/03/25/12365.html
所谓共用体类型是指将不同的数据项组织成一个整体,它们在内存中占用同一段存储单元。
其定义形式为:
union 共用体名
{成员表列};
7.5.1 共用体的定义
union data
{
int a ;
float b ;
d o u b l
e c ;
c h a r
d ;
} obj;
该形式定义了一个共用体数据类型union data ,定义了共用体数据类型变量o b j。
共用体
数据类型与结构体在形式上非常相似,但其表示的含义及存储是完全不同的。
先让我们看一个小例子。
[例7 - 8 ]
union data /*共用体* /
{
int a;
float b;
double c;
char d;
} m m ;
struct stud /*结构体* /
{
int a;
float b;
double c;
char d;
} ;
m a i n ( )
{
struct stud student
printf("%d,%d",sizeof(struct stud),sizeof(union data));
}
程序的输出说明结构体类型所占的内存空间为其各成员所占存储空间之和。
而形同结构体的
共用体类型实际占用存储空间为其最长的成员所占的存储空间。
详细说明如图7 - 6所示。
对共用体的成员的引用与结构体成员的引用相同。
但由于共用体各成员共用同一段内存
空间,使用时,根据需要使用其中的某一个成员。
从图中特别说明了共用体的特点,方便程序设计人员在同一内存区对不同数据类型的交替使用,增加灵活性,节省内存。
7.5.2 共用体变量的引用
可以引用共用体变量的成员,其用法与结构体完全相同。
若定义共用体类型为:
union data /*共用体* /
{
int a;
float b;
double c;
char d;
} m m ;
其成员引用为:m m . a , m m . b , m m . c , m m . d
但是要注意的是,不能同时引用四个成员,在某一时刻,只能使用其中之一的成员。
[例7-9] 对共用体变量的使用。
m a i n ( )
{
union data
{
int a;
float b;
double c;
char d;
} m m ;
m m . a = 6 ;
printf("%d\n",mm.a);
m m . c = 6 7 . 2 ;
p r i n t f ( " % 5 . 1 l f \ n " , m m . c ) ;
m m . d = ' W ' ;
m m . b = 3 4 . 2 ;
p r i n t f ( " % 5 . 1 f , % c \ n " , m m . b , m m . d ) ;
}
程序最后一行的输出是我们无法预料的。
其原因是连续做m m . d = ' W ';m m . b = 3 4 . 2;两个
连续的赋值语句最终使共用体变量的成员m m . b所占四字节被写入34 .2,而写入的字符被覆盖
了,输出的字符变成了符号“ =”。
事实上,字符的输出是无法得知的,由写入内存的数据决
定。
例子虽然很简单,但却说明了共用体变量的正确用法。
[例7-10] 通过共用体成员显示其在内存的存储情况。
定义一个名为t i m e的结构体,再定义共用体d i g:
struct time
{
int year; / *年* /
int month;/ *月* /
int day; / *日* /
} ;
union dig
{
struct time data; /*嵌套的结构体类型* /
char byte[6];
} ;
假定共用体的成员在内存的存储是从地址1 0 0 0单元开始存放,整个共用体类型需占存储空间6个字节,即共用体d i g的成员d a t a与b y t e共用这6个字节的存储空间,存储空间分配示意如图7 - 7所示。
由于共用体成员d a t a包含三个整型的结构体成员,各占2个字节。
由图7 - 7所示可见,d a t a . y e a r是由2个字节组成,用b y t e字符数组表示为b y t e [ 0 ]和byte[1] 。
b y t e [ 1 ]是高字节,
b y t e [ 0 ]是低字节。
下面用程序实现共用体在内存中的存储。
struct time
{
int year; /*年* /
int month; / *月* /
int day; / *日* /
} ;
union dig
{
struct time data; /*嵌套的结构体类型* /
char byte[6];
} ;
m a i n ( )
{
union dig unit;
int i;
printf("enter year:\n");
s c a n f ( " % d " , & u n i t . d a t a . y e a r ) ; / *输入年* /
printf("enter month:\n");
s c a n f ( " % d " , & u n i t . d a t a . m o n t h ) ; / * 输入月* /
printf("enter day:\n");
s c a n f ( " % d " , & u n i t . d a t a . d a y ) ; / *输入日* /
p r i n t f ( " y e a r = % d month=%d day=%d\n", unit.data.year,unit. data. month, unit.
d a t a . d a y ) ; / *打印输出* /
f o r ( i = 0 ; i < 6 ; i + + )
p r i n t f ( " % d , " , u n i t . b y t e [ i ] ) ; / *按字节以十进制输出* /
p r i n t f ( " \ n " ) ;
}
从程序的输出结果来看,1 9 7 6占两个字节,由第0、1字节构成,即7×2 5 6 + 1 8 4 = 1 9 7 6。
4 同样占两个字节,由第2、3字节构成,0×2 5 6 + 4 = 4,2 3由第4、5字节构成,2 3 = 0×2 5 6 + 2 3。