C语言笔记(六)

五十一、枚举类型

51.1、定义

枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读

enum 枚举名 {枚举元素1,枚举元素2,……};

如果一个变量只有几种可能的值,那么就可以将其定义为枚举类型。

  • 如果不用枚举,我们需要使用 #define 来为每个整数定义一个别名

  • 枚举类型是被当做 int 或者 unsigned int 类型来处理的——不会是其他数据类型!!!

  • 所以按照 C 语言规范是没有办法遍历枚举类型的

  • 特殊情况:用 for 来遍历枚举的元素【只是赋值了一个整型类型的值】必须连续!!!

  • 第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1

可以在定义枚举类型时改变枚举元素的值:

enum season {spring, summer=3, autumn, winter};

没有指定值的枚举元素,其值为前一元素加 1

也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5
在这里插入图片描述

  • 枚举类型无法修改

在这里插入图片描述
在这里插入图片描述

51.2、枚举变量的定义

1、先定义枚举类型,再定义枚举变量

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

2、定义枚举类型的同时定义枚举变量

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

3、省略枚举名称,直接定义枚举变量

enum
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

五十二、位域

52.1、位域

在这里插入图片描述
有些信息在存储时,并不需要占用一个完整的字节
而只需占几个或一个二进制位
例如在存放一个开关量时,只有 0 和 1 两种状态,用 1 位二进位即可
为了节省存储空间,并使处理简便
C 语言又提供了一种数据结构,称为"位域"或"位段
是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数
每个域有一个域名
位域在本质上就是一种结构类型,不过其成员是按二进位分配的
带有预定义宽度的变量被称为位域

52.2、如何定义

  • 使用位域的做法是在结构体定义时,在结构体成员后面使用冒号(:)和数字来表示该成员所占的位数
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 位域的宽度不能超过它所依附的数据类型长度。比如上面a位域长度不能超过32位,因为int占四个字节

52.3、无名位域

  • 位域成员可以没有名称,只要给出数据类型和位宽即可,可以用来隔离空间、调整位置、填充
    在这里插入图片描述

52.4、补充

一个位域存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,则会从下一单元起存放该位域

也可以有意使某位域从下一单元开始

struct bs{
    unsigned a:4;
    unsigned  :4;    /* 空域 */
    unsigned b:4;    /* 从下一单元开始存放 */
    unsigned c:4
}

在这个位域定义中,a 占第一字节的 4 位,后 4 位填 0 表示不使用,b 从第二字节开始,占用 4 位,c 占用 4 位

由于位域不允许跨两个字节
因此位域的长度不能大于一个字节的长度
也就是说不能超过8位二进位
如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠
另外一些编译器可能会把大于一个域的部分存储在下一个字中

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

struct 位域结构名 
{
 
 位域列表
 
};
//其中位域列表的形式为:
类型说明符 位域名: 位域长度 

举例:

struct bs{
    int a:8;
    int b:2;
    int c:6;
}data;

data 为 bs 变量,共占两个字节

其中位域 a 占 8 位,位域 b 占 2 位,位域 c 占 6 位

52.6、位域的使用

位域变量名.位域名
位域变量名->位域名
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;    /* 把位域变量 bit 的地址送给指针变量 pbit */
    pbit->a=0;    /* 用指针方式给位域 a 重新赋值,赋为 0 */
    pbit->b&=3;    /* 使用了复合的位运算符 "&=",相当于:pbit->b=pbit->b&3,位域 b 中原有值为 7,与 3 作按位与运算的结果为 3(111&011=011,十进制值为 3) */
    pbit->c|=1;    /* 使用了复合位运算符"|=",相当于:pbit->c=pbit->c|1,其结果为 15 */
    printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);    /* 用指针方式输出了这三个域的值 */
}

上例程序中定义了位域结构 bs

三个位域为 a、b、c

说明了 bs 类型的变量 bit 和指向 bs 类型的指针变量 pbit。这表示位域也是可以使用指针的

52.7、位域声明

struct
{
  type [member_name] : width ;
};
元素描述
type只能为 int(整型) unsigned int(无符号整型) signed int(有符号整型) 三种类型,决定了如何解释位域的值
member_name位域的名称
width位域中位的数量 宽度必须小于或等于指定类型的位宽度

位域可以存储多于 1 位的数

#include <stdio.h>
#include <string.h>
 
struct
{
  unsigned int age : 3;
} Age;
 
int main( )
{
   Age.age = 4;
   printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
   printf( "Age.age : %d\n", Age.age );
 
   Age.age = 7;
   printf( "Age.age : %d\n", Age.age );
 
   Age.age = 8; // 二进制表示为 1000 有四位,超出
   printf( "Age.age : %d\n", Age.age );
 
   return 0;
}

运行结果:

Sizeof( Age ) : 4
Age.age : 4
Age.age : 7
Age.age : 0

五十三、位操作

53.1、逻辑位运算符

在这里插入图片描述

53.2、按位取反(~)

逻辑位运算符中优先级中最高的是按位取反运算符,它的运算符是一个~符号,作用是将1变成0,将0变成1

53.3、按位与(&)

优先级第二高的是按位与运算符,它的运算符是一个&符号(而逻辑与是两个&符号)

53.4、按位异或(^)

优先级排第三的是按位异或运算符,它的运算符是一个^符号,只有当两个操作数对应的二进制位不同时,它的结果才为1,否则为0

53.5、按位或(|)

逻辑位运算符中优先级最低的是按位或运算符,它的运算符是一个|符号(而逻辑或是两个|符号)

53.6、和赋值号结合

这四个运算符,除了按位取反只有一个操作数之外,其他三个都可以跟赋值号(=)结合到一块,使得代码更加简洁
在这里插入图片描述
在这里插入图片描述

五十四、移位和位操作的应用

54.1、移位运算符

C语言除了提供四种逻辑位运算符之外,还提供了可以将某个变量中所有的二进制位左移或右移的运算符——移位运算符

54.2、左移位运算符

11001010 << 2

在这里插入图片描述

54.3、右移位运算符

11001010 >> 2

在这里插入图片描述

54.4、和赋值号结合

左移、右移运算符也可以和赋值号结合…
在这里插入图片描述
在这里插入图片描述

54.5、一些未定义行为

左移、右移运算符右边的操作数如果是为负数,或者右边的操作数大于左边操作数支持的最大宽度,那么表达式的结果均是属于“未定义行为”。
在这里插入图片描述

54.6、应用

在这里插入图片描述

五十五、打开和关闭文件

55.1、程序执行流程

在这里插入图片描述

55.2、文件是什么

在这里插入图片描述

55.3、文本文件和二进制文件

在这里插入图片描述

55.4、打开和关闭文件

在这里插入图片描述
fopen函数文档
在这里插入图片描述

五十六、读写文件

56.1、读写单个字符

  • 单个字符读
    fgetc和getc
    fgetc
  • 单个字符写
    fputc和putc
    fputc

56.2、读写整个字符串

fgets和fputs
fgets
fputs

56.3、格式化读写文件

fscanf和fprintf
fscanf
fprintf

56.4、二进制读写文件

fread和fwrite
fread
fwrite

56.5、随机读写文件

获取当前读写位置->ftell
在这里插入图片描述
修改读写位置->rewind
在这里插入图片描述
在这里插入图片描述
fseek
fseek

56.6、可移植性问题

在这里插入图片描述

五十七、标准流和错误处理

57.1、标准流

在这里插入图片描述

57.2、重定向

在这里插入图片描述

57.3、错误处理

在这里插入图片描述

五十八、IO缓冲区

58.1、IO缓冲区

在这里插入图片描述
在这里插入图片描述
可以使用setvbuf修改缓冲模式
setvbuf

58.2、fflush

刷新缓冲区,将缓冲区数据立刻存放到目标位置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛应用于软件开发的编程语言,具有简洁、高效、灵活等特点。为了更好地学习和掌握C语言,整理一份完整的笔记是非常有必要的。 首先,C语言的基础知识是理解和掌握该语言的关键。笔记中应包含C语言的基本语法,如变量的声明和定义、数据类型、运算符、控制语句等,这些是编写C程序的基础。 其次,C语言的函数也是非常重要的一部分。函数是C语言中的一种模块化的编程方式,可以提高代码的重用性和可维护性。在笔记中应包含函数的定义和调用、参数传递、函数返回值等内容,以及常用的C库函数的使用。 此外,C语言的数组和指针也是需要重点关注的内容。数组是一种存储多个相同类型数据的方式,而指针则是C语言中与内存地址相关的操作。在笔记中应包含数组的定义和初始化、多维数组的使用、指针的声明和运算等内容。 还有,C语言中的内存管理是需要特别注意的。动态内存分配是C语言的一个重要特性,可以根据需要在运行时分配和释放内存。笔记中应包括动态内存分配的函数,如malloc、free等,以及内存泄漏和内存溢出的问题的解决方法。 最后,C语言的文件操作也是需要掌握的一部分。文件操作是C语言中与磁盘文件进行读写的关键部分,可以实现数据的长久保存和共享。在笔记中应涵盖文件的打开和关闭、读取和写入、文件指针的操作等内容。 综上所述,C语言笔记的完整版应该包含C语言的基础知识、函数、数组和指针、内存管理以及文件操作等内容。通过阅读和整理笔记,可以更好地理解和应用C语言,提高程序编写的效率和质量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值