picc结构体用法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
自然对齐(natural alignment)即默认对齐方式,是指按结构体的成员中(类型)size最大的成员作为基本的分配单元,而且与其顺序有这密切的联系。
例如:
struct naturalalign
{
char a;
short b;
char c;
};
在上述结构体中,size最大的是short,其长度为2字节,因而结构体中的char成员a、c都以2为单位对齐,sizeof(naturalalign)的结果等于6;
struct是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如array、struct、union等)的数据单元。对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。缺省情况下,编译器为结构体的每个成员按其自然对齐(natural alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。
Long sno;
Char sex;
Float score [4];
} STU;
Main ()
{
STU a[5];
Printf(“%d\n”,sizeof(a);
}
答案是80,因为union是可变的以其成员中最大的成员作为该union的大小!
但是换成是struct又是多少呢?
Typedef struct student
test pn1;
这样就定义了一test结构体数据类型的结构体变量pn1,结构体成员的访问通过点操作符进行,
pn1.a=10就对结构体变量pn1的成员a进行了赋值操作,
注意:结构体生命的时候本身不占用所有内存空间,只有当你用你定义的结构体类型定义结构体变量的时候计算机才会分配内存。
结构体,同样是能定义指针的,那么结构体指针就叫做结构指针。
cout << "size of D : " << sizeof(D) << endl; /*6字节*/
cout << "size of E : " << sizeof(E) << endl; /*8字节*/
cout << "size of F : " << sizeof(F) << endl; /*12字节*/
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元开始存放*/
unsigned c:4
}
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
main(){
struct bs
{
unsigned a:1;
unsigned b:3;
unsigned c:4;
} bit,*PBit;
bit.a=1;
bit.b=7;
bit.c=15;
printf("%d,%d,%d\n",bit.a,bit.b,bit.c);
PBit=&bit;
PBit->a=0;
struct F
{
char c;
int i;
short s;
};
struct G
{
int i;
char c1;
char c2;
short s;
};
/*与G比较发现,short类型是以2的倍数来对齐的*/
struct H
{
int i;
char c1;
short s;
char c2;
};
int main()
cout<<pn2.a<<"|"<<pn2.b<<endl;
cout<<point->a<<"|"<<point->b<<endl;
cin.get();
}
总之,结构体能描述数组不能够清晰描述的结构,他具有数组所不具有的一些功能特性
自学PIC脚印之C语言的位域结构体问题
在写程序中遇到要用标志位的情况,以为可以和keil51一样进行位定义,虽知道一直报错,后来才知道MC18编译器是不支持位定义的(PICC18编译器倒是支持的)。下面给出一种解决办法——位域结构体。
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct k
{
int a:1
int :2 /*该2位不能使用*/
int b:3
int c:2
};
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。
二、位域的使用
位域的使用和结构成员的使用相同,其一般形式为: 位域变量名·位域名 位域允许用各种格式输出。
如果改为:
struct naturalalign
{
char a;
int b;
char c;
};
其结果显然为12。
那么再回到到原题:结构体中,size最大的是long,size是4,所以,按照顺序,Char name[10];12个字节;Long sno; 4个字节;Char sex; 4个字节(这里对齐了);Float score [4]; 16个字节。于是(12+4+4+16)×5=180,就是了!
结构指针通过->符号来访问成员,下面我们就以上所说的看一个完整的例子:
C++代码
#include<iostream>
#include<string>
usingnamespacestd;
structtest//定义一个名为test的结构体
{
inta;//定义结构体成员a
intb;//定义结构体成员b
};
例子:vc.net2003下运行结果
#include <iostream>
using namespace std;
struct A
{
char c1;
char c2;
};
/*与A比较发现,当只有char类型时,以1个字节的速度增长*/
struct B
{
char c1;
char c2;
char c3;
};
PBit->b&=3;
PBit->c|=1;
printf("%d,%d,%d\n",PBit->a,PBit->b,PBit->c);
}
上例程序中定义了位域结构bs,三个位域为a,b,c。说明了bs类型的变量bit和指向bs类型的指针变量PBit。这表示位域也是可以使用指针的。
程序的9、10、11三行分别给三个位域赋值。( 应注意赋值不能超过该位域的允许范围)程序第12行以整型量格式输出三个域的内容。第13行把位域变量bit的地址送给指针变量PBit。第14行用指针方式给位域a重新赋值,赋为0。第15行使用了复合的位运算符"&=", 该行相当于: PBit->b=PBit->b&3位域b中原有值为7,与3作按位与运算的结果为3(111&011=011,十进制值为3)。同样,程序第16行中使用了复合位运算"|=", 相当于: PBit->c=PBit->c|1其结果为15。程序第17行用指针方式输出了这三个域的值。
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
};
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:
struct bs
{
int a:8;
{
cout << "size of A : " << sizeof(A) << endl; /*2字节*/
cout << "size of B : " << sizeof(B) << endl; /*3字节*/
cout << "size of C : " << sizeof(C) << endl; /*4字节*/
刚才还说过,与顺序有关,呵呵,我们改一下:
Typedef struct student
{
Char name[10];
Char sex;
Long sno;
Float score [4];
} STU;
Main ()
{
STU a[5];
Printf(“%d\n”,sizeof(a);
}
Main ()
{
STU a[5];
cout<<pn1.a<<"|"<<pn1.b<<endl;
cout<<pn2.a<<"|"<<pn2.b<<endl;
test*point;//定义结构指针
point=&pn2;//指针指向结构体变量pn2的内存地址
cout<<pn2.a<<"|"<<pn2.b<<endl;
point->a=99;//通过结构指针修改结构体变量pn2成员a的值
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
什么是结构体?
简单的来说,结构体就是个能包含不同数据类型的一个结构,他是一种能自己定义的数据类型,他的特点和数组主要有两点不同,首先结构体能在一个结构中声明不同的数据类型,第二相同结构的结构体变量是能相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,他本身不是数据类型(而结构体是),数组名称是常量指针,所以不能做为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。
struct C
{
char c1;
char c2;
short s;
};
/*与C比较发现,当引入short类型后,以2个字节的速度增长*/
struct D
{
char c1;
short s;
char c3;
};
struct E
{
char c;
short s;
int i;
};
/*与E比较发现,当引入int类型后,以4个字节的速度增长*/
voidmain()
{wenku.baidu.com
testpn1;//定义结构体变量pn1
testpn2;//定义结构体变量pn2
pn2.a=10;//通过成员操作符.给结构体变量pn2中的成员a赋值
pn2.b=3;//通过成员操作符.给结构体变量pn2中的成员b赋值
pn1=pn2;//把pn2中所有的成员值复制给具有相同结构的结构体变量pn1
int b:2;
int c:6;
}data;
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:
cout << "size of G : " << sizeof(G) << endl; /*8字节*/
cout << "size of H : " << sizeof(H) << endl; /*12字节*/
char c;
cin >> c;
Typedef union student
{
Char name[10];
{
Char name[10];
Long sno;
Char sex;
Float score [4];
} STU;
Main ()
{
STU a[5];
Printf(“%d\n”,sizeof(a);
}
答案是180????为什么不是(10+4+1+16)*5=155?因为struct有个叫对齐方式的问题:
不对齐的数据存取在x86上影响速度,因为在不对齐的时候,对于小的可能会影响其效率,对齐即是多分配一些字节,填充无用数据,以空间的损失来换取消率。
C++中结构体的存储方式
2008-02-28 21:49
C/C++中结构体的存储方式
结构体在内存的存放,遵循两个原则:
1、基本类型对齐原则:
Char 1
Short 2
Int 4
Long 4
Float 4
Double 8
2、结构体类型对齐原则:
以最大成员类型的对齐方式为准,即当需要增长时,增长最大成员类型所占用的字节数。
定义结构体使用struct修饰符,例如:
C++代码
struct test
{
float a;
int b;
};
上面的代码就定义了一个名为test的结构体,他的数据类型就是test,他包含两个成员a和b,成员a的数据类型为浮点型,成员b的数据类型为整型。
由于结构体本身就是自定义的数据类型,定义结构体变量的方法和定义普通变量的方法相同。
相关文档
最新文档