经验技巧8-1 结构体变量的存储长度

合集下载

结构体变量及数组

结构体变量及数组

结构体变量及数组结构体变量和数组是在C语言中用于存储和操作数据的重要工具。

结构体变量是一种用户自定义的数据类型,它可以包含多个不同类型的成员,用于表示实际世界中的实体。

数组是一种由相同类型的元素组成的有序集合,用于存储和处理大量相似的数据。

首先,让我们来看一下结构体变量。

结构体变量由多个成员组成,每个成员可以是不同类型的数据。

我们可以根据需要定义不同的结构体变量,并为其成员分配不同的值。

结构体变量的定义如下:```struct studentchar name[20];int age;float score;};```在这个例子中,我们定义了一个名为student的结构体变量,它包含了三个成员。

成员name是一个字符数组,用于存储学生的名字;成员age是一个整型变量,用于存储学生的年龄;成员score是一个浮点型变量,用于存储学生的成绩。

我们可以根据需要为这些成员分配值,如下所示:```struct student s;strcpy(, "Tom");s.age = 18;s.score = 90.5;```上述代码中,我们首先创建了一个名为s的结构体变量,然后使用strcpy函数为成员name分配了一个字符串值,使用赋值语句给成员age 和score分配了整型和浮点型的值。

我们可以使用结构体变量的成员操作符"."来访问和修改结构体变量的成员值。

除了单个结构体变量,我们还可以使用数组来存储多个结构体变量。

下面是一个存储多个学生信息的例子:```struct student s[3];strcpy(s[0].name, "Tom");s[0].age = 18;s[0].score = 90.5;strcpy(s[1].name, "John");s[1].age = 19;s[1].score = 85.0;strcpy(s[2].name, "Lisa");s[2].age = 20;s[2].score = 95.5;```在这个例子中,我们定义了一个大小为3的结构体变量数组s,用于存储学生的信息。

C语言位运算

C语言位运算

第8章位运算C语言是为描述系统而设计的,与其它高级语言相比,它的一个重要特点是具有汇编语言的功能,这主要表现在C语言提供了特有的位运算功能。

8.1 位运算概念C语言的位运算是指在C语言中能进行二进制位的运算。

位运算包括位逻辑运算和移位运算,位逻辑运算能够方便地设置或屏蔽内存中某个字节的一位或几位,也可以对两个数按位相加等;移位运算可以对内存中某个二进制数左移或右移几位等。

为了表示数值,可以采用不同的方法,一般有:原码、反码和补码。

计算机内部是以补码形式存放数值的。

8.2 位运算符C语言提供了六种位运算,如表8-1所示。

表8-1 位运算符及含义说明:1.位运算量a,b只能是整型或字符型的数据,不能为实型数据。

2.位运算符中除按位取反运算符~为单目运算符外,其它均为双目运算符,即要求运算符的两侧各有一个运算量。

8.2.1位逻辑运算符假设a,b为整型的数据,并且设a=123(等于二进制数00000000001111011),b=152(等于二进制数00000000010011000)1.“按位与”运算符&运算规则:参加运算的两个运算量,如果两个数相应位的值都是1,则该位的结果值为1,否则为0。

即:0 & 0 =0;0 & 1 =0;1 & 0 =0;1 & 1 =1。

【例8-1】a的补码:00000000001111011b的补码:00000000010011000& ————————结果的补码:00000000000011000即:a&b=0x18。

2.“按位或”运算符|运算规则:参加运算的两个运算量,如果两个数相应位的值都是0,则该位的结果值为0,否则为1。

即:0 | 0 =0;0 | 1 =1;1 | 0 =1;1 | 1 =1【例8-2】a的补码:00000000001111011b的补码:00000000010011000| ————————结果的补码:00000000011111011即:a|b=0xfb。

C语言 第八章.用户自定义数据类型

C语言   第八章.用户自定义数据类型
printf("%c,%c\n",u2.c[0],u2.c[1]); }
u2占2个字节
例:以下程序输出结果是?
union example { struct { int x,y; e.b e.a e.in.x }in; e.in int a; e.in.y int b; }e; void main() { e.a=1;e.b=2; e.in.x=e.a*e.b; e.in.y=e.a+e.b; printf("%d,%d",e.in.x,e.in.y); }
内存低地址 01100001 00001010
字符变量c占1个字节
整型变量i占2个字节 单精度实型变量f占4个字节
u1.i=10;
例:以下程序输出结果是?
union u_type { char c[2]; u1
p
内存高地址 内存低地址 ‘a’ ‘b’ c1 c2 c[1] c[0] u1占2个字节 内存高地址 内存低地址 ‘A’ ‘B’ ‘a’ ‘b’ c1 c2 c[1] c[0]
{"0208103322","lisi",19,'M'},{"0208103323","lili",20,'F'}, {"0208103324","xulin",21,'M'}};
学号(number) 姓名(name) 年龄(age) 性别(sex)
stu[0] stu[1] stu[2] stu[3]
char name[8];
int age; char sex;
定义结构体类 sizeof(stu) 型的同时创建 =? 结构体数组

结构体变量及数组

结构体变量及数组

一.为什么引入结构体:当一个数据比较复杂,由多个信息进行描述,这个为了将多个信息封装成一个整体,用一个变量进行存储,我们引入结构类型。

结构类型是一个自定义类型。

没有固定的类型名存在。

需要我们根据数据的本身的特征,先定义结构体类型,然后用这个定义的结构体类型定义变量,用该变量存放我们的数据。

二.结构体变量的使用过程:1.定义结构体类型结构体类型定义的一般形式:struct结构体名{成员变量的定义};例如:structstudent{intnum;charname[10];};2.用定义好的结构体类型定义变量students1;3.用结构体变量存放数据s1.num=1001;cin>>;cout<<s1.num<<endl;cout<<<<endl;注意:I.struce关键字,后面表示结构体类型的名字(必须是一个合法的标识符)。

2.结构体类型定义的结束以分号作为结束。

3.结构体中间成员变量的定义,就是定义变量,这些变量用来存放数据的多个信息。

4.当用结构体类型定义变量的时候,该变量被分配空间,其空间的大小由构成该变量的各个成员所占用的空间大小的和决定。

5.结构体变量的使用,不能整体进行输入或输出,只能按照每个成员的方式进行访问。

成员的访问方式:.成员引用运算符结构体变量成员引用的一般形式:结构体变量.成员变量的名字students1,s2;具有相同类型的结构体变量之间可以相互赋值cin>>s1.num;cin>>;s2=s1;例题:#include<iostream>usingnamespacestd;intmain(){structstudent{intnum;charname[18];floatsjjg;floatdl;floatmath;floattotal;};students1;cin>>s1.num;cin>>;cin>>s1.sjjg>>s1.dl>>s1.math;s1.total=s1.sjjg+s1.dl+s1.math;cout<<s1.num<<""<<<<""<<s1.total<<endl;;return0;}三.结构体类型作函数的参数:结构体类型的定义也是有有效区间的,所以我们一般在函数体外,在程序开始的位置定义结构体类型,还可以在另一个文件中定义结构体(.h),在使用该结构体类型的文件中用#include将该头文件包含进去。

C语言结构体内存对齐详解

C语言结构体内存对齐详解

C语⾔结构体内存对齐详解⽬录实例⼀:分析:存储结构图如下实例⼆:分析:存储结构如下实例三:分析:存储结构如下实例四:分析:存储结构图如下总结1、结构体内存对齐是指当我们创建⼀个结构体变量时,会向内存申请所需的空间,⽤来存储结构体成员的内容。

我们可以将其理解为结构体成员会按照特定的规则来存储数据内容。

2、结构体的对齐规则(1)第⼀个成员在相⽐于结构体变量存储起始位置偏移量为0的地址处。

(2)从第⼆个成员开始,在其⾃⾝对齐数的整数倍开始存储(对齐数=编译器默认对齐数和成员字节⼤⼩的最⼩值,VS编译器默认对齐数为8)。

(3)结构体变量所⽤总空间⼤⼩是成员中最⼤对齐数的整数倍。

(4)当遇到嵌套结构体的情况,嵌套结构体对齐到其⾃⾝成员最⼤对齐数的整数倍,结构体的⼤⼩为当下成员最⼤对齐数的整数倍。

3、了解了结构体的对齐规则后,我们通过实战来巩固(实例⼀⾄实例三同类,请细品实例四)实例⼀:分析:存储结构图如下红⾊填充内存为结构体成员a,因其为char类型且是第⼀个成员,由规则(1)可得如下;橙⾊填充为结构体成员b,因其为int 类型且不是第⼀个成员,由规则(2)可得如下;绿⾊填充为结构体成员c,因其为char类型且不是第⼀个成员,由规则(2)(3)可得如下;画红叉内存位置属于因对齐造成的浪费内存。

实例⼆:分析:存储结构如下红⾊填充内存为结构体成员a,因其为char类型且是第⼀个成员,由规则(1)可得如下;橙⾊填充为结构体成员b,因其为char类型且不是第⼀个成员,由规则(2)可得如下;绿⾊填充为结构体成员c,因其为int类型且不是第⼀个成员,由规则(2)(3)可得如下;画红叉内存位置属于因对齐造成的浪费内存。

实例三:分析:存储结构如下红⾊填充内存为结构体成员a,因其为double类型且是第⼀个成员,由规则(1)可得如下;橙⾊填充为结构体成员b,因其为char类型且不是第⼀个成员,由规则(2)可得如下;绿⾊填充为结构体成员c,因其为int类型且不是第⼀个成员,由规则(2)(3)可得如下;画红叉内存位置属于因对齐造成的浪费内存。

嵌入式c高级技巧

嵌入式c高级技巧

嵌入式c高级技巧今天来聊聊嵌入式C高级技巧的一些实用技巧,可都是我自己在实际项目中摸索总结出来的哦。

先来说说这个结构体对齐(struct alignment)的技巧吧。

记得我刚接手一个项目的时候,要和硬件那边进行数据交互。

我定义了一个结构体来存储相关数据,当时没太在意结构体成员的顺序。

结果数据传输就老是出错,可把我急得像热锅上的蚂蚁。

后来我才发现,原来是结构体对齐的问题。

比如说,在某些硬件平台下,处理器对于不同类型数据的存储地址有对齐要求。

如果把一个占据8字节的double型变量跟在一个1字节的char型变量后面的话,中间可能就会出现填充(padding),这就导致在和硬件对接数据时顺序和长度对不上了。

这就好比把不同大小的东西放在一个箱子里,如果不按照一定顺序放,箱子的空间就会浪费而且可能东西还放不稳。

从那时候起,我就知道了定义结构体的时候,要按照类型大小从大到小的顺序来排列成员变量。

这样做的好处就是,可以避免结构体内部数据存储的“七扭八歪”,让数据传输效率更高。

不过这个技巧也是有局限性的,如果在跨平台开发中,不同平台对于对齐的要求可能不一样。

如果遇到这种情况,可以借助预处理指令来进行特殊处理,像pragma pack这种,这样就可以更精确地控制结构体的对齐。

对了,还有个事儿要说。

像函数指针(function pointer)在嵌入式C里也是非常有用的高级技巧。

有一次我们要做一个任务调度系统,不同的任务有不同的处理函数。

要是按照常规来写,代码会很冗杂。

这个时候函数指针就派上用场了。

就像是给每个任务都分配了一个超小的领航员,每个领航员都知道他所负责的任务的处理之道。

你定义一系列的函数指针数组,然后根据任务的状态来调用不同的函数。

但是要注意的地方是,函数指针如果用不好,比如函数签名不匹配,就很容易就引发一些难以排查的Bug。

我一开始就总是犯这种错误,搞得程序老是出莫名其妙的问题,就像你出门总是穿错鞋子一样难受。

C-8

C-8

age
city zip
struct info {char name[20]; int age;
c1.num c1 c2
c2.score=95.5
tud.adr.tel
tel
num num
2B
name sex age score name sex age score 95.5
20B 1B 2B 4B
struct addr adr; } tud ;
17
§8.3结构体指针
结构体变量一旦定义——
系统即按成员顺序分配空间,同时为结构体变量赋予 一个起始地址。
结构体指针变量——
用以指向结构体变量或结构体数组
一.指向结构体变量的指针
定义例型 使用指向结构体的指针访问成员
例8.4使用结构体指针访问结构体成员
18
§8.3结构体指针
定义
例如:struct key { char kword[10]; int kcount; }kdata; struct key *kp=&kdata;
结构体成员引用具有与普通变
量相同的操作功能
12
§8.1 结构体概要
四.结构体类型变量的初始化
一般在定义结构体变量的同时即可以赋初值
例8.2结构体初始化与成员引用举例
结构体要点
结构体类型描述 结构体变量定义 结构体成员变量的初始化与引用 结构体变量赋值——多值赋值
结构体类型及变量的作用域
13
printf(“NUMBER NAME AGE\n”); 例8.2结构体初始化与成员引用举例 printf("%d %s %d\n", #include<stdio.h> a.num, , a.age);

c语言结构体数组传参 -回复

c语言结构体数组传参 -回复

c语言结构体数组传参-回复C语言结构体数组传参结构体数组是C语言中常用的数据类型,它能够存储一组相关的数据,并且可以方便地传递给函数进行处理。

本篇文章将从介绍结构体数组的定义开始,逐步详解结构体数组的传参方法和使用技巧。

一、结构体数组的定义结构体是一种用户自定义的数据类型,它能够将多个不同类型的变量组合成为一个整体。

结构体数组是由多个相同类型的结构体变量组成的数组。

在C语言中,可以通过如下方式定义一个结构体数组:cstruct student {int id;char name[20];int age;} stuArr[100];上述代码定义了一个结构体数组stuArr,其中每个元素都是一个包含id、name和age三个成员变量的结构体变量。

stuArr的长度为100,即可以存储100个学生的信息。

二、结构体数组的传参结构体数组作为函数的参数时,可以通过值传递或指针传递的方式进行。

1. 值传递方式值传递是将结构体数组的副本传递给函数,函数对副本的修改不会影响到原数组。

cvoid printStudents(struct student arr[], int n) {for (int i = 0; i < n; i++) {printf("ID: d\n", arr[i].id);printf("Name: s\n", arr[i].name);printf("Age: d\n", arr[i].age);}}int main() {struct student stuArr[3] = {{1001, "Tom", 18},{1002, "Jerry", 19},{1003, "Alice", 20}};printStudents(stuArr, 3);return 0;}上述代码中,printStudents函数接收一个结构体数组和数组的长度作为参数,遍历数组并打印每个学生的信息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

经验技巧8-1 结构体变量的存储长度
结构体变量的存储长度,跟编译器字节对齐密切相关。

为了使CPU对变量进行快速高效的访问,变量的起始地址应该满足某些特性,即所谓的对齐。

关于字节对齐有两个重要的宏:#pragma pack (n)和#pragma pack。

(1)#pragma pack (n):一般情况下,此宏的作用在于强制编译器以n的倍数进行地址对齐。

(2)#pragma pack:结束前面设置的对齐方式,恢复到编译器默认的对齐方式。

Visual C++默认的字节对齐数为8。

结构体变量中的成员item在结构体中相对于首地址的偏移量应该是X的倍数,X由如下式决定:
X=min(n,sizeof(item)),(item是占字节最大的类型的成员)
【示例1】假设n为8,若有如下定义
struct Test { char c1; char c2; int i;};
struct Test t;
那么在存储结构体变量t的成员i时,X就应该是min(8,sizeof(int))=4的倍数,即i相对于结构体变量首地址的偏移量必须是4的倍数,所以t的大小就应该为8=(2+2+4)字节(在c1和c2后填充了两个字节以满足前述条件)。

而对于struct { char c1; char c2} t;则不会出现填充的的情况,每个成员相对首地址的偏移量也满足是X的倍数(此时X为1),变量t的大小为2字节。

【示例2】若有结构体变量:struct {char c1; double d;} t;,默认情况下结构体变量t占用16=(8+8)字节(在c1后填充7个字节以满足字节对齐)。

如果强制编译器以4字节对齐,即在声明这种结构体变量前有宏定义#pragma pack (4),此时X为4,则此种类型结构体变量占用的内存为12=(4+8)字节。

还有一种特殊情况,就是空结构体。

在Visual C++下其大小为1,即struct{}类型的变量在VC下输出其大小是1,原因就是VC为每个结构体变量分配一个字节的内存,以使该变量有个地址;而在gcc下输出其大小为0。

最后,结构体成员中有结构体变量的情况见下例:
【示例3】若有struct test1 { char c1; int i ; char c2 ;}t1;则X=4,所以t1占用4+4+4=12个字节,那么对于struct test2 { int i; struct test1 t1; char c2; }t2;有X=min{8,max(4,4,1)}=4,所以t2占用4+12+4=20个字节,在确定上述的X时会把t1拆散成基本数据类型来处理,而计算结构体变量t2的大小时又会把t1作为一个整体来对待。

故默认情况下,结构体test2类型变量的大小为:20字节。

相关文档
最新文档