哈尔滨学校网站建设关于室内设计的网站有哪些
目录
前言
一、定义结构
结构体变量的创建和初始化
二、结构的特殊声明
特别注意:
结构的⾃引⽤
三、结构体内存对⻬
对⻬规则
优化结构体
#pragma
结构体传参
四、结构体实现位段
位段的内存分配
位段的跨平台问题
前言
C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
结构体中的数据成员可以是基本数据类型(如 int、float、char 等),也可以是其他结构体类型、指针类型等。
一、定义结构
结构体定义由关键字 struct 和结构体名组成,结构体名可以根据需要自行定义。
结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
例如:
 struct Stu  
 
 {  
 
 char name[20];//名字  
 
 int age;//年龄  
 
 char sex[5]; 
 
 char id[20];//学号  
  };  
  
结构体变量的创建和初始化
 #include <stdio.h>  
 
 
 struct Stu  
 
 {  
 
 
        char name[20];//名字  
 
        int age;//年龄  
 
        char sex[5];//性别  
 
        char id[20];//学号  
 
 };  
 
 
 int main()  
 
 {  
 
 
         //按照结构体成员的顺序初始化  
 
        struct Stu s = { "张三", 20, "男", "20230818001" };  
 
        printf("name: %s\n", s.name);  
 
        printf("age : %d\n", s.age);  
 
        printf("sex : %s\n", s.sex);  
 
        printf("id : %s\n", s.id);  
 
 
 //按照指定的顺序初始化  
 
 struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex =  
 
 "⼥" };  
 
 
        printf("name: %s\n", s2.name);  
 
        printf("age : %d\n", s2.age);  
 
        printf("sex : %s\n", s2.sex);  
 
        printf("id : %s\n", s2.id);  
 
 
       return 0;  
 
 } 
 
 
二、结构的特殊声明
 在声明结构的时候,可以不完全的声明。  
  ⽐如:  
  // 匿名结构体类型  
  struct  
  {  
      int  a;  
      char  b;  
 float c;
}x;
 struct  
  {  
        int  a;  
       char  b;  
       float  c; 
   }a[ 20 ], *p;  
   特别注意:
 编译器会把上⾯的两个声明当成完全不同的两个类型,所以是⾮法的。  
  匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使⽤⼀次。  
   结构的⾃引⽤
 例如,定义⼀个链表的节点:  
   struct Node  
  {  
         int data;  
          struct Node next;  
  }; 
   仔细分析,其实是不⾏的,因为⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的⼤ ⼩就会⽆穷的⼤,是不合理的。 
   正确的⾃引⽤⽅式: 
  struct Node  
  {  
         int data;  
         struct Node* next;  
  }; 
  三、结构体内存对⻬
对⻬规则
 ⾸先得掌握结构体的对⻬规则:  
    1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处  
  2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。  
  对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。  
   -  VS  中默认的值为  8  
  - Linux中 gcc 没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩  
    3. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的  
  整数倍。  
    4. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构  
  体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。 
   优化结构体
 那在设计结构体的时候,我们既要满⾜对⻬,⼜要节省空间,如何做到: 
    //例如:  
   struct S1  
   {  
          char c1;  
          int i;  
          char c2;  
   };  
     struct S2  
   {  
        char c1;  
        char c2;  
        int i;  
   };  
 #pragma
 #pragma  这个预处理指令,可以改变编译器的默认对⻬数。  
    #include <stdio.h>  
  #pragma pack(1)//设置默认对⻬数为1  
   struct S  
  {  
          char c1;  
          int i;  
          char c2;  
  };  
   #pragma pack()//取消设置的对⻬数,还原为默认  
   int main()  
  {  
   printf("%d\n", sizeof(struct S));  
  return 0;  
  }  
  结构体传参
 struct  S  
  {  
       int  data[ 1000 ];  
       int  num;  
  };  
   struct  S s  = {{ 1 , 2 , 3 , 4 },  1000 };  
  // 结构体传参  
   void  print1 ( struct  S s)  
  {  
  printf ( "%d\n" , s.num);  
  }  
   // 结构体地址传参  
  void  print2 ( struct  S* ps)  
  {  
  printf ( "%d\n" , ps->num);  
  }  
    int  main ()  
  {  
   print1(s);  // 传结 构体  
  print2(&s);  // 传地址  
   return  0 ;  
  } 
   print2函数是要优于print1函数的 
  原因: 
  函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。  
  如果传递⼀个结构体对象的时候,结构体过⼤,参数压栈的的系统开销⽐较⼤,所以会导致性能的下降 
   总结: 
  结构体传参的时候,要传结构体的地址。  
  四、结构体实现位段
 位段的声明和结构是类似的,有两个不同:  
   1.  位段的成员必须是  int 、 unsigned int  或 signed int  ,在C99中位段成员的类型也可以  
  选择其他类型。  
   2.  位段的成员名后边有⼀个冒号和⼀个数字。 
   例如: 
  struct A  
  {  
      int _a:2;  
      int _b:5;  
      int _c:10;  
      int _d:30;  
  };  
   位段的内存分配
 1.  位段的成员可以是  int unsigned int signed int  或者是  char  等类型  
   2.  位段的空间上是按照需要以4个字节(  int  )或者1个字节(  char  )的⽅式来开辟的。  
   3.  位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使⽤位段。 
   struct S  
  {  
      char a:3;  
      char b:4;  
      char c:5;  
      char d:4;  
  };  
  struct S s = {0};  
       s.a = 10;  
       s.b = 12;  
       s.c = 3;  
       s.d = 4; 
   位段的跨平台问题
1. int 位段被当成有符号数还是⽆符号数是不确定的。
 2.  位段中最⼤位的数⽬不能确定。(16位机器最⼤16,32位机器最⼤32,写成27,在16位机器会  
  出问题。  
  3.  位段中的成员在内存中从左向右分配,还是从右向左分配,标准尚未定义。  
   4.  当⼀个结构包含两个位段,第⼆个位段成员⽐较⼤,⽆法容纳于第⼀个位段剩余的位时,是舍弃  
  剩余的位还是利⽤,这是不确定的。 
   总结:  
  跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。  
 