13.字符串,结构,联合

C 语言并没有显式的字符串数据类型,因为字符串以字符串常量的形式出现或者存储于字符数组中。
字符串常量适合那些不会对它们进行修改的字符串。所有的字符串都必须存储于字符数组或者动态分配的内存中。

字符串就是一串0个或多个字符,并且以一个位模式全是0NUL字节结尾。字符串的长度不包括 nul 字节。
头文件 string.h 包含了使用字符串函数

结构

数组可以通过下标访问,以为数组的元素长度相同。
结构通过成员名字访问,不能用下标访问。因为它的成员长度不一致。

相同类型的结构变量互相之间尅赋值。
声明结构:

struct tag {
    member-list;
} variable-list;


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

struct {
    int a;
    char b;
    float c;
} y[20], *z;  // 这是2个不同的结构类型, z = &x 错的

所以 ,tag 就派上用处了: // tag 结构标签
struct tag { 
    int a;
    char b;
    float c;
};

struct tag x;
struct tag y[20],*z;
z = &x; //对


另外一个技巧是用 typedef :
typedef struct {
    int a;
    char b;
    float c;
} Simple; //Simple 是个类型名而不是结构标签

Simple x;  // 用类型名来声明
Simple y[20],*z;
结构成员:
struct COMPLEX {
    float f;
    struct SIMPLE s;
    struct SIMPLE sa[10];
};

一个结构的成员名字可以和其他结构的成员的名字相同。

结构成员的直接访问:
结构变量的成员是通过点操作符(.)访问的。
struct COMPLEX comp;
comp.a 

结构成员的间接访问:
拥有一个指向结构的指针,先对指针进行间接访问,获得这个结构。再使用.操作符。
要加括号,因为间接优先级没有.操作符高。
void func(struct COMPLEX *cp);
(*cp).f

由于这个概念不好,C 提供了箭头操作符(->),左操作数必须是指向结构的指针,
箭头操作符对左操作数执行间接访问取得指针所指向的结构,然后和.操作符一样,根据右操作符选择一个指定的结构成员。但是间接访问操作符内建于箭头操作符内。


结构的自引用: (必须是 结构标签 + 指针)
struct tag{
    int a;
    struct tag b;
}; //这种自引用是非法的,因为成员 b 是另外一个完整的结构,其内部还将包含它自己的成员b,无限重复下去。

struct tag{
    int a;
    struct tag *b;
}; // 这个是对的。b 是指针,而非结构。编译器在结构的长度确定之前就已经知道指针的长度了。
所以是合法的。如果你觉得结构内部包含一个指向结构本身的指针有些奇怪,请记住它事实上所
指向的是同一种类型的不同结构。更加高级的数据结构,如链表和树,都是用这种技巧实现的。
每个结构指向链表的下一个元素或者数的下一个分支。


//下面是错误的
typedef struct {
    int a;
    SELF_REF3 *b;
    int c;
} SELF_REF3;
这个声明的目的是为这个结构创建类型名为 SELF_REF3.但是失败了。类型名直到声明的末尾才定义,
所以在结构声明的内部它尚未定义。

//解决方案是定义一个结构标签来声明 b
typedef struct SELF_REF3_TAG{
    int a;
    struct SELF_REF3_TAG *b;
    int c;
} SELF_REF3;
不完整声明:
struct B;
struct A{
    struct B *pb;
};
struct B{
    struct A *pa;
};
在 A 的成员列表中需要标签 B 的不完整声明。一旦A被声明之后,B的成员列表也可以别声明。
结构的初始化:
struct INTT_EX {
    int a;
    short b[10];
    Simple c;
} x = {
    10,
    {1,2,3,4,5},
    {25,'x',1.9}
};
位段:
位段的声明和结构相似,但它的成员是一个或多个位的字段。
这些不同长度的字段实际上存储于一个或多个整形变量之中。
位段的声明和普通的结构成员声明相同,但有2个例外。首先,位段成员必须声明为 
int,signed int 或者 unsigned int 类型。其次,在成员的后面是一个冒号和一个整数。
这个整数指定该位段所占用的位的数目。

struct CHAR{
    unsigned ch : 7;
    unsigned font : 6;
    unsigned size : 19;
};
struct CHAR ch1;

联合

联合的所有成员引用的是内存中相同的位置。
union {
    float f;
    int i;
} fi;


联合的初始化: // 联合变量可以被初始化,但初始值必须是联合的第一个成员的类型
union {
    int a;
    float b;
    char c[4];
} x = {5};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值