C语言结构体解析

来源:互联网 发布:学会linux能干什么 编辑:程序博客网 时间:2024/05/18 18:21

一.定义和使用结构体变量

1.自己建立结构体类型

 (1) 例如:一个学生的学号(number),性别(sex),年龄(age),分数(score),地址(addr).


C语言允许用户自己建立有不同类型数据组成的组合型的数据结构,它称为结构体。

(2)例如:

struct Student{char number[15];  //学号为字符型char name[8];     //姓名为字符型char sex[5];      //性别为字符型int age;          //年龄为整型float score;      //分数为浮点数char addr[25];    //地址为字符型};      //分号必须有
                            
结构体类型struct  Student(struct是声明结构体类型时所必须使用的关键字,不能省略)

(3)声明一个结构体类型的一般形式

      struct   结构体名

        { 成员列表};

2.定义结构体类型变量

(1)先声明结构体类型,在定义该类型的变量

    之前声明了一个结构体类型struct  Student ,可以用它来定义变量。

例如:

     struct  Student         student1,student2;

     结构体类型                 结构体变量名


这样student1和student2就具有struct  Student 的结构;


(2)在声明类的同时定义变量

例如:

struct Student{char number[15];  char name[8];     char sex[5];      int age;         float score;      char addr[25];   }student1,atudent2;      

它的作用与(1)的方法相同,但是在定义struct  Student 类型的同时定义两个struct  Student 类型变量student1和student2.

(3)其一般形式为:

struct  结构体名

{

成员表列

}变量名表列;

3.不指定类型名而直接定义结构体类型变量

其一般形式为

struct

{

成员表列

}变量名表列;

注:指定了一个无名的结构体类型,它没有名字(不出现结构体名),所以不能再以次结构类型去定义其他变量。

(这种方式用的不多)

4.typedef的用法简单介绍

(1)不用typedef  时创建的结构体

struct Student{char number[15];  char name[8];     char sex[5];        };      

创建一个结构体实例时候命名规则:

            struct Student student;

然后对student.name等等进行操作。

每次创建一个结构体实例的时候就必须调用struct Student A来操作;

(2)使用typedef时创建的结构体

typedef struct Student{char name[10];int age;char sex[10];}bbs;

使用带typedef 的结构体时候,创建一个结构体实例命名规则:

可以像上边不带typedef 的样式创建,也可如下操作:

           bbs student;

它们之间的关系:bbs student = struct Student student;

5.结构体变量的初始化和引用

在定义结构体变量时,可以对它初始化,既赋予初始值。然后引用这个变量(输出它的成员的值)。

#include <stdio.h>struct Student{char number[12];char sex[5];char name[15];int age;float score;}student1 = {"10001","男","liming",20,97.5},student2 = {"10002","女","wangfa",18,87};int main(){printf("%s  %s  %s  %d  %f\n",student1.number,student1.sex,student1.name,student1.age,student1.score);system("pause");return 0;}
输出结果



(1)在定义结构体变量时可以对它的成员初始化。初始化列表是用花括号括起来的一些常量,这些常量一次付给结构体变量中的各成员。<注:是对结构体变量初始化,而不是结构体类型初始化。>

(2)在引用结构体内容时要用点运算符或者指向运算符

一般形式为:

结构体变量名.成员名(或者结构体变量名->成员名)

例如:

      student1 = { "10001", "男", "liming", 20, 97.5 }
获取姓名的两种方式:  student1.name
                                       student1->name


二.结构体的内存存储(内存对齐)

结构体开辟空间时存在内存对齐:

(1)内存对齐的意义:

   各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。

(2)内存对齐的方式:

   首先,要了解所用环境的默认对其数,Vs下的默认对齐数为8,Linux环境下的默认对齐数为4。开辟空间时,从0偏移除开始存放,选取当前类型大小与默认对齐数中的较小值为对齐数开辟空间,最终大小为(结构体中占空间最大的类型与默认对齐数中的较小值的整数倍)。

例如:(默认对齐数为4)

#include<stdio.h>#pragma pack(4)struct Student{char number[6];    //6int age;            float score;};#pragma pack()int main(){printf("%d\n", sizeof(struct Student));    //16system("pause");return 0;}

该结构体大小为16个字节

存放方式:


三.结构体中位段的使用

1.位段的简单使用:

#include<stdio.h>struct Student{        int number:2;    int age:2;            int ch : 2;};int main(){printf("%d\n", sizeof(struct Student));    //4system("pause");return 0;}

2.数据存储方式:


先开辟一个整形大小(32个bit)的空间,存放各数据在不满32bit的情况下不再开辟空间。所以(1)中的结构体大小为4个字节。

3.不同类型的数据使用位端:

#include<stdio.h>struct Student{        char number:2;    int age:2;            char ch : 1;};int main(){printf("%d\n", sizeof(struct Student));    //12system("pause");return 0;}

当不同类型的数据进行位段操作时,就近相同类型的数据可存放,当类型不同时再开辟一块空间

图示:


注:(1)使用位段时不存在内存对齐。

  (2)当使用位段操作时尽量转换成同一类型,否则将浪费更多空间。


 





原创粉丝点击