0%

C/C结构体再学习

Struct

语句格式

1
2
3
4
5
6
struct tag{
member-list
member-list
member-list
...
} variable-list ;
  • tag:结构体标签
  • member-list:标准的变量定义。例如:int i; float j;
  • variable-list: 结构变量,定义在结构的末尾,最后一个分号之前,可以指定一个或者多个结构变量。

用法详解

一般情况下
tag, member-list, variable-list这三部分至少要出现2个。
-w834

结构体的成语可以包含其他结构体,也可以包含指向自己结构体类型的指针。而通常这种指针的应用是为了实现一些更高级的数据结构(如链表和树)。
-w827

如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明。
-w808

结构体变量的初始化

1
2
3
4
5
6
7
8
9
10
11
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book = {"结构体", "nianchu", "Programming", 123321};

int main(){
printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\n", book.title, book.author, book.subject, book.book_id)
}

访问结构体成员

  • 成员访问运算符(.)
  • 使用struct关键字来定义结构体类型的变量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct Books Book1;;


    /* Book1 详情*/
    strcpy(Book1.title,"Matlab程序设计");
    strcpy(Book1.author,"bowenki");
    strcpy(Book1.subject,"编程语言");
    Book1.book_id = 123456;

    /* 输出Book1的详细信息*/
    printf("These is information about Book1:\nTitle:%s\nAuthor:%s\nSubject:%s\nBook_id:%d", Book1.title, Book1.author,Book1.subject,Book1.book_id);

    结构作为函数参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    struct Books {
    char title[50];
    char author[50];
    char subject[100];
    int book_id;

    } book = {"C语言", "niaochu.space","编程语言", 123};


    void printStruct(struct Books book);

    void printStruct(struct Books book){
    printf("Title:%s\n",book.title);
    printf("Author:%s\n",book.author);
    printf("Subject:%s\n",book.subject);
    }

    int main(){

    struct Books Book1;

    strcpy(Book1.title,"Matlab程序设计");
    strcpy(Book1.author,"bowenki");
    strcpy(Book1.subject,"编程语言");
    Book1.book_id = 123456;
    printStruct(Book1);
    }

    指向结构的指针

    为了使用指向该结构的指针访问结构的成员,必须使用->运算符号
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main(){


    struct Books *pointBook;
    struct Books Book2;
    pointBook = & Book2;

    /* 给Book2初始化*/
    strcpy(pointBook -> title, "我真的要疯了");
    strcpy(pointBook -> author,"我太难了");
    strcpy(pointBook -> subject, "神啊,救救我吧");

    printStruct(Book2);
    }

    位域

    前情提示:

    有些信息在存储中,并不需要占用一个完整的字符,而只需要占用几个或一个二进制位。这时候,可以使用位域。

    实例:

    • 用1位二进位存放一个开关变量,只有0和1两种状态
    • 读取外部文件格式– 可以读取非标准的文件格式。例如:9位的整数

      位域的定义和位域变量的说明

      位域定义和结构体定义相仿:
      1
      2
      3
      4
      struct 位域结构名
      {
      位域列表
      };

其中位域列表的形式为:
类型说明符 位域名: 位域长度
例如:

1
2
3
4
5
6
struct bs{
int a:8;
int b;
int c;

} data;

对于位域的几点说明:

  • 一个位域存储在同一个字节中,如一个字节中所剩余空间不够存放另一个位域时,则会从下一个单元起存放该位域。也可以有意使某位域从下一单元开始:
    1
    2
    3
    4
    5
    6
    7
    struct bs{
    unsigned a:4;
    unsigned : 4; /* 空域 */
    unsigned b:4; /* 从下一单元开始存放 */
    unsigned c : 4;

    }
  • 由于位于不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
  • 位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。

* 位域在本质上就是一种结构体类型,但是其成员是按二进制分配的。 *

位域的使用

位域的使用和结构体相同,存在下面两种方法:

  • 位域变量名.位域名
  • 位域变量名 -> 位域名

位域使用的实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
pbit -> b = 0;
pbit -> a = 0;
pbit -> b&3;
pbit -> c|=1;
printf("%d,%d,%d,\n",pbit->a, pbit->b, pbit->c );
}