《C和指针》读书笔记(第十章 结构和联合)(上)

简介: 《C和指针》读书笔记(第十章 结构和联合)(上)

0 简介

在C语言中,相同类型的数据元素若想放在一起,可以采用数组,那不同类型的元素呢?

有的计算机语言是不会care这个问题的,比方说python,毕竟python本来就是所谓的弱数据类型的语言;C语言虽然出生较早,但历尽千帆,仍能常年在计算机语言排行榜中名列前茅,其优势之一便是对数据类型和内存的精准把控。而结构和联合,正是这种思想的完美诠释与实践。

在部分的教材和资料中,结构也称为结构体,联合也称为联合体共同体共用体

正所谓“一花独放不是春,百花齐放春满园”,因其可以容纳多种类型的数据,在实际开发中,结构和联合经常合作发力,为项目开发提供了很大的便利。

本篇内容概览

1 结构基础知识

聚合数据类型能够同时存储超过一个的单独数据。C提供了两种类型聚合数据类型,数组结构。结构是一些值的集合,这些值称为它的成员

数组可以元素可以通过下标访问,这只是因为数组的元素长度相同。但是在结构中情况并非如此。由于一个结构的成员可能长度不同,所以不能使用下标来访问他们。

1.1 结构声明

结构体的声明形式如下:

struct tag {member-list} variable-list;

除了结构标签的不完整声明,所有可选部分不能全部省略,至少要出现两个。这句话有点费解 ,只需要看几个例子便可以明白,在实际开发中,结构体常见的声明方式只有两种,将在下面进行说明。

struct {
  int a;
  char b;
  float c;
}x;

这里声明了一个名叫x的变量,包含三个成员,声明没有什么错误,但是因为拓展性不强,在实际开发中并不常用,较为常用的是以下两种。

struct SIMPLE{
  int a;
  char b;
  float c;
};

这种有了标签,就可以避免重复造轮子,有点像C++中创建的对象。对于具有相同属性的事物,只需要创建一次即可,在具体的使用中,可根据自己的需要进行变量的创建。

还有一种更加方便的方法,也就是采用typedef创建一种新的类型。

typedef struct {
  int a;
  char b;
  float c;
}Simple;

这种方法看起来在定义的时候稍微复杂了一点点,但是在使用的时候方便了一些,举个例子:

#include <stdio.h>
struct SIMPLE{
  int a;
  char b;
  float c;
};
typedef struct {
  int a;
  char b;
  float c;
}Simple;
int main()
{
    //定义结构体变量
  struct SIMPLE s1;
  Simple s2;
  //给结构体变量赋值
  s1.a = 10;
  s1.b = '?';
  s1.c = 3.1415;
  s2.a = 20;
  s2.b = '!';
  s2.c = 3.1415;  
  //打印输出
  printf("s1.a = %d\n",s1.a);
  printf("s1.b = %c\n",s1.b);
  printf("s1.c = %f\n",s1.c);
  printf("s2.a = %d\n",s2.a);
  printf("s2.b = %c\n",s2.b);
  printf("s2.c = %f\n",s2.c);
  return 0;
}

运行,打印输出:

可以看到如果采用了typedef关键字来声明结构体,则在定义结构体变量的时候就可以少写一个struct关键字,看似不会简洁太多,但是在大型项目开发中,会省去更多的时间。

1.2 结构成员

到目前为止的例子里,我只使用了简单类型的结构成员。但可以在一个结构外部声明的任何变看都可以作为结构的成员。尤其是,结构成员可以是标量数组指针甚至是其他结构(标量一般指的是整型或者浮点型的数据)。

比如:

struct COMPLEX(
  float f;
  int   a[20];
  long  *lp;
  struct SIMPLE s;
  struct SIMPLE sa[10];
  struct SIMPLE *sp;
};

1.3 结构成员的直接访问

结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数,左操作数就是结构变量的名字,右操作数就是需要访问的成员的名字。这个表达式的结果就是指定的成员。例如,考虑下面这个声明:

struct COMPLEX comp;

比方说,表达式

((comp.sa)[4]).c

下标引用和点操作符具有相同的优先级,他们的结合性都是从左向右,所以可以省略所有的括号。变成了下面的表达式

comp.sa[4].c

此二者等效。

所以在访问嵌套的数据类型的时候,与普通的数据元素访问没有什么区别。只需要一层一层访问即可。

1.4 结构成员的间接访问

当我们拥有一个指向结构的指针时,该如何访问这个结构的成员呢?首先就是对指针执行间接访问操作。然后使用点操作符来访问它的成员。但是点操作符的优先级高于间接访问操作符,所以在访问结构的成员的时候就出现了下面的情况。

先定义一个指向结构体的指针:

struct COMPLEX *CP;

然后用访问其元素:

(*cp).f

这样的操作符显然过于繁琐,于是在C语言中就出现了->操作符,结构体指针可用来访问结构体成员,如下:

cp->f
cp->a
cp->s

表达式1访问一个浮点数成员,表达式2访问一个数组名,表达式3访问一个结构。

1.5 结构的自引用

结构体中包含一个同类型的结构体是否合法呢?答案是否定的。因为这样可以无穷无尽地包含下去,导致程序无法执行。比如:

struct SELF_REF1 {
  int a;
  struct SELF_REF1 b;
  int c;
};

但是结构体中包含指向同类型结构体的指针是合法的,比如:

struct SELF_REF2 {
  int a;
  struct SELF_REF2 *b;
  int c;
};

因为我们仅仅是多了一个指向同类型结构体的指针,不会出现层层包含,无穷无尽的情况。在实际开发中,经常用来实现一些数据结构,比方说链表,每个节点都可能指向相同类型的下一个节点(有时不止一个)。

1.6 不完整的声明

通常情况下,我们的声明都是完整的,但若是有两个相互包含的结构体,究竟应该先定义哪一个呢?

这个时候,我们的不完整声明就派上用场了,如下所示:

struct B;
struct A {
    struct B *partner;
};
struct B {
    struct A *partner;
};

虽然声明了结构体B,但是并未完全声明,因为结构体成员未给出,主要是没法给出,若是给出A,但A也尚未定义。于是就有了这样的处理方法。

如此一来,就形成了“你中有我,我中有你”的两个结构体。如下图所示:

1.7 结构的初始化

结构体的初始化方式和数组的初始化很类似。在一对花括号内用逗号分隔,然后再分别对各个成员进行初始化(赋值)即可。如果初始列表的值不够,剩余的结构成员将使用缺省值进行初始化。举个例子:

struct INIT_EX {
  int a;
  short b[10];
  Simple c;
}x = { 10,{1,2,3,4,5},{10,'x', 3.14} };

可以看到成员中有个数组b,我们仅初始化了起始的5个元素,其余元素则会采用缺省值进行初始化,一般情况下初始化为0。如下图所示:

相关文章
|
存储 C++
04-深入了解isa指针以及内部结构
04-深入了解isa指针以及内部结构
70 0
04-深入了解isa指针以及内部结构
|
存储 搜索推荐 算法
《C和指针》读书笔记(第十一章 动态内存分配)
《C和指针》读书笔记(第十一章 动态内存分配)
|
存储 C语言
《C和指针》读书笔记(第十章 结构和联合)(下)
《C和指针》读书笔记(第十章 结构和联合)(下)
《C和指针》读书笔记(第九章 字符串、字符和字节)(下)
《C和指针》读书笔记(第九章 字符串、字符和字节)(下)
|
程序员 C语言
《C和指针》读书笔记(第九章 字符串、字符和字节)(中)
《C和指针》读书笔记(第九章 字符串、字符和字节)(中)
|
存储 C语言
《C和指针》读书笔记(第九章 字符串、字符和字节)(上)
《C和指针》读书笔记(第九章 字符串、字符和字节)(上)
|
5月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
26天前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
19 0
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
3月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)