本文主要是介绍桂林理工大学电子信息877C程序设计专业课复盘,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
程序设计和C语言
- 一个程序由一个或多个源程序文件组成
- 源程序
- 预处理指令
- 函数定义
- 全局声明
- 函数是c程序的主要组成部分
- 程序中要求计算机的操作是由函数中的c语句完成的
- C语言本身不提供输入输出语句,输入和输出操作是由C标准函数库中的函数来实现的
- 编译和运行
- 上机输入和编辑源程序
- 文件用.c作为后缀
- 对程序进行编译,先对程序中的预处理指令进行编译预处理
- 文件用.obj作为后缀
- 编译以源程序为对象
- 进行连接处理
- 文件用.exe作为后缀
- 多个obj以及函数库连接
- 即使只有一个源程序也要进行连接
- 上机输入和编辑源程序
算法
- 程序=算法+数据结构
- 算法特性
- 有穷性
- 确定性
- 有零个或多个输入
- 有一个或多个输出
- 有效性
- 流程图符号
- 结构化程序
- 高内聚低耦合
- 自顶向下
- 逐步细化
- 模块化设计
- 结构化编码
- 高内聚低耦合
选择结构
- if-else
- else总是与它上面的最近的未配对的 if 配对
- switch
- 代码结构
switch(表达式(整型)) {case 常量1 : 语句1;break;case 常量2 : 语句2;break;default:语句3; }
- 可以没有default标号
- 各个case标号出现次序不影响执行结果
- 每一个case常量必须互不相同
- 若各case子句没有break语句,将连续输出
- case子句可以不必用花括号括起来
- 多个case标号可以共用一组执行语句
- 代码结构
循环结构
- for(表达式1;表达式2;表达式3)
- 表达式1:只执行一次
- 表达式2:每次执行循环体前先执行此表达式
- 表达式3:执行完循环体后才执行
- 分号不可省略
- 三个表达式都可省略,默认表达式2为真值,相当于while(1)
- 若表达式2为逗号表达式,有坑!
- 整个逗号表达式的值为最右边的表达式的值
- do-while
- while后面的分号别忘了
- break
- 跳转到循环体的花括号外,也就是提前结束循环,接着执行循环下面的语句
- 表达式3(如:i++)不执行
- 在多层循环中,只跳出一层
- 只能用于循环语句和switch语句中,不可单独使用
- continue
- 跳转到表示循环体结束的右花括号的前面,即提前结束本次循环
- 表达式3(如:i++)执行,然后进行下一次是否执行循环的判定
数据的表现形式
- 常量
- 八进制以数字0开头
- 十六进制以数字0和字母X/x开头
- e或E之前必须有数字,且e或E之后必须为整数
- 12.34e3等价于12.34*10的3次方
- -346.87e-25等价于-346.87*10的-25次方
- 错:e4,12e2.5
- 转义字符
- 八进制:‘\101’,‘\012’
- 十六进制: ‘\x41’
- 常变量
- const int a=3;
- 值不可改变
- 标识符
- 由字母、数字和下划线组成
- 第一个字符必须为字母或下划线
- 使用 $ 符号的标识符可以正常使用,此时与标识符定义冲突,$符号是在C99标准中的一种特殊指定,可以用于标识符。
- 数据类型
- 整型
- 数据长度:sizeof(long long)>=sizeof(long)>=sizeof(int)>=sizeof(short)
- 默认为有符号(signed):signed int a等价于int a
- 只有整形(包括字符型)可以加signed或unsigned修饰符,实型数据不能加
- 整型
- 存储单元中的存储方式
- 原码
- 由10进制直接转换的2进制数字
- 反码
- 符号位不变,原码按位取反
- 补码
- 反码加1
- 整数在内存中存储的方式都是以补码形式存放的
- 正数:原码,反码,补码相同
- 负数:以补码的形式存入(将负数的绝对值写成二进制形式,然后按位取反,再加1)
- 最左边的一位为符号位
- 正数为0
- 负数为1
- 原码
运算符
- 优先级
- 逗号表达式
- 表达式1,表达式2,…,表达式n
- 顺序求出各表达式的值,结果为表达式n的值
- p52
- 两个实数相除的结果是双精度实数
- 5/3的结果为1,舍去小数部分
- %运算符要求整数参与运算
- 除了%以外的运算符的操作数都可以是任何算数类型
- +、-、*、/ 运算的两个数中有一个数为float或double型,结果为double型
- 如果int型与float或double型数据进行运算,先把int型和float型数据转换为double型,然后进行运算,结果是double型
- 关系运算符的值为bool(true或false)
- 强制转换运算符
- float a=3.14;int b;将a转换为整形:b=(int)a;
- a的值并未发生变化,仍然是3.14
- 中间变量(3)在赋值后不复存在
- float a=3.14;int b;将a转换为整形:b=(int)a;
- 逻辑表达式
- 逻辑表达式的值为0或1
- a&&b&&c。只有a为真(非0)时,才需判别b的值
- a||b||c。只要a为真(非0),就不必判断b和c
- 判断闰年
- (能被4整除&&不能被100整除是闰年)||(能被400整除是闰年)
- (year%4 == 0 && year%100!=0 )||year%400==0
- 条件表达式
- (a>b)?a:b
- 如果(a>b)条件为真,则条件表达式的值等于a,否则为b
- (a>b)?a:b
C语句
- goto
- 在结构化程序中基本不用
- 赋值语句
- 赋值运算符的左值应为可被修改的
- 错误的左值:a+b,常量
- 类型转换
- 浮点型数据赋给整型变量时,直接取整,舍弃小数部分
- 整型数据赋给浮点型变量时,数值不变
- 将一个占字节多的整型数据赋给一个占字节少的整型变量或字节变量时,只将其低字节原封不动地送到被赋值的变量
- 赋值运算符的左值应为可被修改的
- 输入输出语句
- %5d:向右对齐
- %-5d:向左对齐
- %g
- 指数>6或者<-4的时候:%g(%G)选择 %e(%E)输出
- %g(%G)在选择%f输出的时候,是不会有多余的0出现的
- scanf
- 记得加&
- scanf的返回值为成功赋值的变量个数
- 用%c时,空格字符和“转义字符”中的字符都做有效数字输入
- 用%s输入多个字符串时,用空格(分隔符)隔开
- 当输入一个浮点型数据时,格式控制部分不可以规定小数点后的位数,错误:scanf(“%4.2f”,&f);
- scanf(“%d\n”,&d);里面加\n会导致程序一直在等待输入,无法结束
- printf
- 如果想输出字符‘%’,则应用两个连续的%%表示
- printf 的返回值为输出的字符个数
- 用%s输出的字符串不包含‘\0’
一维数组
- C语言不允许对数组的大小作动态定义
- 错误:int n;int a[n];
- 下标可以是整型常量或整型表达式
- 初始化
- 在定义数组时对全部数组元素赋予初值
- int a[6]={0,1,2,3,4,5};
- 只给数组中的一部分元素赋值,系统自动给后3个元素赋初值为0(字符数组自动为’\0’,指针型数组自动为NULL)
- int a[6]={0,1,2};
- 数据个数已确定,可以不指定数组长度
- int a[]={0,1,2,3,4,5};
- 在定义数组时对全部数组元素赋予初值
二维数组
- int a[3][4]
- 列指针:int *p1;p1=a[0];行指针:int ( *p2)[4];p2=a;
- a[0]、a[1]、a[2]分别是三个一维数组的数组名,因此a[0](指针常量)代表一维数组a[0]中第0列元素的地址(即&a[0][0])
- a代表二维数组首元素的地址,首元素是由4个整型元素所组成的一维数组,因此a代表的是首行(即序号为0的行)的起始地址,a+1则代表序号为1的行的起始地址
- a[0]+0和*(a+0)+0都是a[0][0]的地址, *(a[0]+0)和 *( *(a+0)+0)或 *( *a+0)都是a[0][0]的值, *(a[i]+j)或 *( *(a+i)+j)是a[i][j]的值
- a[0]是一维数组名,它是一维数组中的起始元素的地址,a是二维数组名,它是二维数组的首行起始地址,二者的纯地址是相同的,但它们的基类型不同,即它们指向的数据的类型不同,前者是整型数据,后者是一维数组
- 在指向行的指针前面加一个*,就转换为指向列的指针,反之,在指向列的指针前面加&,就成为指向行的指针,如:&a[0]== &*a ==a,它指向二维数组的0行
- &a[i]和a[i]的值是一样的,但是基类型不同,&a[i]或a+i指向行,a[i]或*(a+i)指向列
- 初始化
- 分行给数组赋值
- int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
- 所有数据写在一个花括号内
- int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
- 部分赋值,其余元素自动为0
- int a[3][4]={{1},{5},{9}};
- int a[3][4]={{1},{},{9}};
- 全部元素都赋初值,则定义数组时对第1维的长度可以不指定,但第2维的不能省
- int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
- int a[][4]={{1},{},{9}};
- 分行给数组赋值
字符数组
- C系统中,用字符数组存储字符串常量时会自动加一个‘\0’作为结束标志,多占一个字节,最后一个字节‘\0’是系统自动加上的
- 若在定义数组时不进行初始化,那么数组各元素的值是不可预料的,如果初值个数小于数组长度,其余的元素自动为‘\0’
- 初始化
- 初始化列表
- char c[3]={‘a’,‘b’,‘c’};(长度为3)(末尾没有‘\0’)
- char c[10]={‘a’,‘b’,‘c’};(长度为10)(其余元素自动为‘\0’)
- 提供的初值个数和预订的数组长度相同,在定义时可以省略数组长度
- char c[]={‘a’,‘b’,‘c’};
- 使用字符串常量(长度为4)(末尾有‘\0’)
- char c[]={“abc”};
- char c[]=“abc”;
- 初始化列表
- 字符串结束标志是‘\0’(空字符串所占的字节数为1,即只有一个’\0’字符)
- 遇到‘\0’时,把它前面的字符组成一个字符串,不包含‘\0’,即:第十个字符是‘\0’,有效字符为9个
- 字符串常量是按字符数组处理的(在C语言中,只有字符变量,没有字符串变量)
- 字符指针变量和字符数组的比较
- 可以对字符指针变量赋值,但不能对数组名(地址常量,不可被改变)赋值
- 指针变量的值是可以改变的,而字符数组名代表一个固定的值(数组首元素的地址),不能改变
- 字符数组中各元素的值是可以改变的,但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能对它们再赋值)
- 如果指针变量没有指向数组,则无法用p[5]或*(p+5)这样的形式引用数组中的元素,若输出p[5]或 *(p+5),系统将输出指针变量p所指的字符后面5个字节的内容,这样是没有意义的,若字符指针变量p指向字符串常量(C语言中,字符串作为字符数组处理),就可以用指针变量带下标的形式引用所指的字符串中的字符,如:p[5]
- 数组可以在定义时对各元素赋初值,但不能用赋值语句对字符数组中全部元素整体赋值
变量
- 变量和函数的属性
- 数据类型
- 整形、浮点型等
- 数据的存储类别
- 静态存储和动态存储
- 数据类型
- 存储方式
- 静态存储
- 程序运行期间由系统分配固定的存储空间的方式
- 动态存储
- 程序运行期间根据需要进行动态的分配存储空间的方式
- 静态存储
- 静态存储区
- 全局变量
- 动态存储区
- 函数形式参数
- 函数中定义的没有用关键字static声明的变量(自动变量)
- 函数调用时的现场保护和返回地址
- 局部变量
- 函数内部或复合语句内部定义的变量
- 存储类别(作用:指定变量存储的区域)
- 自动变量(auto变量)
- 不写auto则隐含指定为“自动存储类别”,属于动态存储方式
- 若未赋初值,它的值是一个不确定的值
- 静态局部变量(static局部变量)
- 属于静态存储类别,在静态存储区内分配存储单元
- 在编译时赋初值的,且只赋值一次
- 若未赋初值,编译时自动赋初值0(对数值型变量)或空字符‘\0’(对字符变量)
- 寄存器变量(register变量)
- 为提高执行效率,允许将局部变量的值放在CPU中的寄存器
- register int f;
- 存储位置:在CPU的寄存器中
- 自动变量(auto变量)
- 全局变量
- 函数外部定义的变量,也称外部变量
- 存储类别(都是存放在静态存储区的)(作用:变量作用域的扩展问题)
- 在一个文件内扩展外部变量的作用域
- 用关键字extern对该变量作“外部变量声明”,表示把该外部变量的作用域扩展到此位置,如:extern int a;或extern a;
- 将外部变量的作用域扩展到其他文件(如:extern a)
- 在编译时遇到extern时,先在本文件找外部变量的定义,若找不到就在连接时从其他文件中找
- 将外部变量的作用域限制在本文件中(静态外部变量)
- 在定义外部变量时加一个static声明(如:static int a)
- 在一个文件内扩展外部变量的作用域
- 当局部变量和全局变量同名时,函数内全局变量不起作用
函数
- 函数就是功能
- 程序编译时以源程序文件为单位进行编译,而不是以函数为单位进行编译的
- 程序的执行由main起,由main止
- main函数不能被用户调用,main函数是操作系统调用的,所有的函数都是平行的,函数不能嵌套定义,但是可以嵌套调用
- 形参的值发生改变不会改变主调函数的实参的值
- 函数的返回值是通过函数中的return语句获得的
- 一个函数中可以有一个以上的return语句
- 如果函数值的类型和return语句中表达式的值不一致,则以函数类型为准,即函数类型决定返回值的类型
- 函数声明中形参值可以省写
- 数组元素可以作实参,但不能作形参
- 一维形参数组可以不指定大小,因为编译系统把形参数组处理成指针变量
- 二维形参数组可以省略第一维的大小,但不能省略第二维(列数)的大小,否则第二行的起始地址将不一样
- 不同函数中可以使用同名的变量
- 函数指针
- int max(int a,int b);int (*p)(int,int);int c;
- 赋值:p=max;调用:c=(*p)(a,b);
- 函数名代表函数的起始地址
- 一个指针变量可以先后指向同类型的不同函数
- int max(int a,int b);int (*p)(int,int);int c;
- 内部函数(静态函数)
- 首部:static int fun(int a)
- 只能被本文件中其他函数调用
- 外部函数
- 首部:extern int fun(int a)
- 可被其他文件调用
- 若在定义函数时省略extern,则默认为外部函数
- 函数原型能够把函数的作用域扩展到定义该函数的文件之外==(不必使用extern)==
- 字符输入输出函数
- getchar
- 回车、空格这些都是有效字符
- putchar
- getchar
- 字符串函数
- puts(字符数组)
- char str[]=“china\nbeijing”;puts(str);
- 字符串中可以包含转义字符
- 遇到’\0’转换成’\n’,即输出完字符串后换行
- gets(字符数组)
- char str[20];gets(str);输入com时,送给数组的共有4个字符,不是3个字符
- strcat(字符数组1,字符数组2)
- strcat(str1,str2);
- 把字符串2接到字符串1的后面,结果放到字符数组1中
- 返回值为字符数组1的地址
- 连接前两个字符串的后面都有‘\0’,连接时将字符串1后面的‘\0’取消,只在新串中保留‘\0’
- strcat函数会一直在字符串1中往后数,直到指针指向字符串1中的’\0’
- 注:
- 字符串1必须以 ‘\0’ 结尾。
- 字符串1必须可修改。
- 自己无法直接追加自己。
- strcpy(字符数组1,字符串2)
- strcpy(str1,str2);或strcpy(str1,“china”);
- 将字符串2复制到字符数组1中去
- 字符数组1必须写成数组名形式
- 如果在复制前未对str1数组初始化或赋值,则str1各字节中的内容是无法预知的,复制后str1前面的字节为复制的,后面的字节不一定为‘\0’,而是原有(不可预知的)的
- strcmp(字符串1,字符串2)
- strcmp(str1,str2);或strcmp(str1,“china”);或strcmp(“korea”,“china”)
- 从左至右按ASCII码值比较
- 函数返回值:
- 字符串1==字符串2,函数值为0
- 字符串1>字符串2,函数值为正整数(1或ASCII码差值)
- 字符串1<字符串2,函数值为负整数
- strlen(字符数组)
- strlen(str);或strlen(“china”);
- 函数返回值为字符串中的实际长度(不包括‘\0’在内)
- puts(字符数组)
- main函数
- int mian(int argc,char *argv[])
- argc(参数个数)和argv是命令行参数(必须是字符串)
- 第一个形参必须是int型,第二个形参必须是char *型
- 设文件名为file.exe
- 命令行:file china beijing
- argc的值为3;则argv[0]的值是字符串“file”的首地址
- 内存动态分配
- malloc函数(开辟动态存储区)
- 函数原型:void * malloc(unsigned int size);
- malloc(100);
- 作用:在内存的动态存储区中分配一个长度为size的连续空间
- 基类型为void,即不指向任何类型的数据,只提供一个纯地址
- 若内存空间不足,则返回空指针(NULL)
- calloc函数(开辟动态存储区)
- 函数原型:void * calloc(unsigned n,unsigned size);
- p=calloc(50,4);
- 开辟动态数组
- realloc函数(重新分配动态存储区,也就是改变大小)
- 函数原型:void * realloc(void *p,unsigned int size);
- realloc(p,50);
- free函数(释放动态存储区)
- 函数原型:void * free(void *p);
- free( p);
- malloc函数(开辟动态存储区)
指针
- 地址就是指针
- 用来存放另一变量的地址(指针)的变量是指针变量
- 指针变量的值是地址(指针)
- 基类型:int,float等
- 指针指向整形变量时,使指针移动一个位置意味着移动四个字节
- 变量的指针的含义
- 以存储单元编号表示的纯地址(如编号为2000的字节)
- 它指向的存储单元的数据类型(如int,char等)
- 指针类型
- 指向整型数据的指针类型表示为“int *”,读作“指向int的指针”或简称“int指针”
- 不能通过执行调用函数来改变实参指针变量的值,但是可以改变实参指针变量所指变量的值
- 函数的返回值只能有一个,但是使用指针变量作参数,可以得到多个变化了的值
- 数组名(不包括形参数组名)代表数组中首元素(即序号为0的元素)的地址
- 数组名a代表数组首元素的地址,它是一个指针型常量,它的值在程序运行期间是固定不变的,因此a++或让a重新被赋值是无法实现的
- 若指针变量p的初值为&a[0]
- p+i或a+i就是数组元素a[i]的地址
- *(p+i)或 *(a+i)就是数组元素a[i]的值
- 两个地址相加无实际意义
- C编译都是将形参数组名作为指针变量来处理的,形参数组也不是真正要开辟一个数组空间,所以可以不指定形参数组的大小(元素的个数)
- 指向数组元素的指针变量也可以带下标,如p[i],若当前p指向a[3],则p[2]为a[3+2](a[5])
- *p++
- 先引用p的值,实现*p的运算,然后再使p自增1
- *(++p)
- 先使p加1,再取*p
- ++(*p)
- 表示p所指向的元素值加1
- int a[3]={1,2,3};int ( *p)[4];p=&a;//(*p)[2]的值为3
- 形参和实参若是指针类型,则它们的基类型必须一致
- 定义指针变量,要及时把变量的地址赋给它,如果向未指向一个确定的对象的指针变量输入所指向的对象的数据,可能会出现严重后果
- void指针类型(空类型指针)
- “指向空类型”或“不指向确定的类型”的数据
- 无指向的地址所标志的存储单元中是不能存储任何数据的,只有指针转换为有指向的地址,才能存储数据
自建数据类型(struct 、union、enum 、typedef )
- 结构体
- 声明结构体类型:struct Student{int name;};
- 只能对最低级的成员进行赋值或存取以及运算
- 同类的结构体变量可以互相赋值
- 指向结构体对象的指针变量(struct Student *p;)
- (*p).name或p->name
- p++时,p的值的增量是结构体struct Student的长度
- 共用体类型
- 使几个不同的变量共享同一段内存的结构
- union Data{int i;char ch;float f;}a,b,c;
- 共用体变量所占内存长度等于最长成员的长度
- 不能引用共用体变量(如:a,b,c),只能引用共用体变量中的成员(如:a.i)
- 同一时间只能存放其中一个成员
- 初始化只能初始化一个成员
- 共用体变量的地址和它的各成员的地址都是同一地址
- 不能对共用体变量名赋值
- 同类型的共用体变量可以互相赋值(如:b=a)
- 共用体类型可以出现在结构体类型定义中,也可以定义共用体数组;反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员
- 枚举类型(整型数据中的一种)
- 声明:enum Weekday{sun,mon,tue};
- enum Weekday workday;
- enum Weekday是枚举类型,workday是枚举变量,花括号中的sun,mon,tue称为枚举元素或枚举常量
- 枚举变量和其他数值型量不同,它们的值只限于花括号中指定的值(如:workday=mon;)
- 不能对枚举元素赋值,sun的值自动设为0,mon为1,之后顺序加一,则workday=mon相当于workday=1
- 枚举元素可以用来作判断比较
- 用typedef声明新类型名(在编译阶段处理)
- 方法:
- 先按定义变量的方法写出定义体(如:int i;)
- 将变量名换成新类型名(如:将i换成Count)
- 在最前面加typedef(如:typedef int Count)
- 然后可以用新类型名去定义变量
- 不能创造新类型
- 方法:
文件
- 操作系统是以文件为单位对数据进行管理的
- 访问文件时,读写位置会自动后移
- 字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储(占存储空间较多),也可以用二进制形式存储
- 文件尾标志:EOF,值为-1
- 文件标识
- 文件路径
- 文件名主干
- 文件后缀
- 文件分类
- ASCII文件(遇到换行符‘\n’需转换为‘\r’和‘\n’)或文本文件
- 二进制文件(无需转换)或映像文件
- 数据的存储方式
- 文本方式
- 数据以字符方式(ASCII代码)存储到文件中
- 二进制方式
- 数据按在内存的存储状态原封不动地复制到文件
- 文本方式
- 文件的打开方式
- 文本方式:不带b的方式(遇到换行符‘\n’需转换为‘\r’和‘\n’)
- 二进制方式:带b的方式(无需转换)
- exit(0);的作用是关闭所有文件,使程序终止
- 标准流文件(程序运行时自动打开)
- 标准输入流(文件指针变量:stdin,下同)
- 标准输出流(stdout)
- 标准出错输出流(stderr)
- 文件类型指针(文件指针)
- FILE *fp;(指向文件的指针变量)
- FILE是一个结构体类型
- 文件使用方式
- 用w方式打开文件:若不存在文件,则新建一个,若已存在文件,则先删去原有的文件再新建一个
- 若不希望删除原有的文件,则用a方式打开,打开文件时文件读写位置标记移到文件末尾
- 文件函数
函数名 | 调用形式 | 返回值 | 输入输出方式 |
---|---|---|---|
fopen | fp=fopen (“file.txt”,“r”);或fp=fopen (“D:\\CC\\file.txt”,“r”); | 打开成功则返回指向file.txt文件的指针,若打开不成功则返回一个空指针值NULL | |
fclose | fclose(fp); | 关闭成功的返回值为0,关闭不成功的返回值为EOF(-1) | |
fgetc | fgetc(fp) | 读成功的返回值为所读的字符,失败的返回值为EOF(-1) | ASCII方式(文本方式) |
fputc | fputc(ch,fp) | 输出成功的返回值为所输出的字符,失败的返回值为EOF(-1) | ASCII方式(文本方式) |
fgets | fgets(str,n,fp) | 读成功的返回值为地址str,失败的返回值为NULL | ASCII方式(文本方式) |
fputs | fputs(str,fp)或fputs(“china”,fp) | 输出成功的返回值为0,失败的返回值为非0值 | ASCII方式(文本方式) |
feof | feof(fp) | 文件尾标志已被读出则返回值为真(1),未被读出的返回值为假(0) | |
fprintf | fprintf(fp,“%d,%f”,i,f) | ASCII方式(文本方式) | |
fscanf | fscanf(fp,“%d,%f”,&i,&f) | ASCII方式(文本方式) | |
fread | fread(str,4,10,fp)或fread(&stud[1],sizeof(struct Student),1,fp) | 执行成功的返回值为数据项的个数(整数) | 二进制方式 |
fwrite | fwrite(&stud[1],sizeof(struct Student),1,fp) | 执行成功的返回值为数据项的个数(整数) | 二进制方式 |
rewind | rewind(fp) | 无返回值 | |
fseek | fseek(fp,100L,0) | ||
ftell | ftell(fp) | 执行失败的返回值为-1L | |
ferror | ferror(fp) | 执行成功的返回值为0(假),执行失败的返回值为非零值 | |
clearerr | clearerr(fp) |
- fgets函数
- char *fgets(char *str,int n,FILE *fp);
- 从fp文件中读入n-1个字符串最后加一个‘\0’字符
- 读完n-1个字符前遇到换行符‘\n’也作为一个字符读入
- fputs函数
- char *fputs(char *str,FILE *fp);
- 字符串末尾的‘\0’不输出
- rewind函数
- 使文件位置标记指向文件开头,同时feof函数的值会恢复为0(假)
- fseek函数(用于二进制文件)
- 作用:改变文件标记位置
- 起始点
- 0:文件开始位置
- 1:当前位置
- 2:文件末尾位置
- ftell函数
- 作用:测定文件位置标记的当前位置,往往用相对于文件开头的位移量来表示
- clearerr函数
- 作用:使文件出错标志和文件结束标志置为0,使得ferror(fp)的值变为0,以便再进行下一次检测
- 只要出现文件读写出错标志,它就一直保留,直到对同一文件调用clearerr函数或rewind函数,或任何其他一个输入输出函数
- 执行fopen函数时,ferror函数的初始值自动置0
预处理
- 预处理功能
- 宏定义(符号常量)
- 不作语法检查
- define PI 3.1415926
- define S( r) PI*( r)*( r)
- 宏名与带参数的括号之间不应加空格
- 不进行值的传递处理
- 没有“返回值”的概念
- 不存在类型问题
- 末尾无分号
- 不分配存储空间
- 宏替换只占预处理时间
- 预编译后就不存在了
- 文件包含
- include <stdio.h>(标准方式)
- include “stdio.h”
- 条件编译
- #ifdef 标识符
程序段1
#else
程序段1
#endif
- #ifdef 标识符
- 宏定义(符号常量)
位运算
- 参加位运算的对象只能是整型或字符型的数据
- “按位与”运算
- &
- 有0则0
- “按位或”运算
- |
- 有1则1
- “异或”运算
- ^
- 同0异1
- “取反”运算
- ~
- 左移运算
- <<
- 将二进制数左移2位,右补0
- 右移运算
- 符号:>>
- 将二进制数右移2位,左补0
- 位段(位域)
- 赋值:data.a=2;
编程题
- 浮点型变量应定义为double型,格式声明为%lf,不可以用%f格式符输出
- 循环体内赋初值;
- 关注斐波那契数列之类的递归
- 素数或质数:除了1和它本身以外没有其它的因数
- 判断n是否为素数时只需被2–sqrt(n)的整数除即可
- i<=(int)sqrt(n)
- 判断n是否为素数时只需被2–sqrt(n)的整数除即可
- 合数:比1大但不是素数的数
- 完数就是该数恰好等于除自身外的因子之和
- 1和0既不是素数也不是合数
- 一个数的因数包含1和它本身
- 求和(循环)
- 结果输出到文件
- 自编库函数(如pow、strcpy)
- 链表
- 头指针、结点
- 静态链表
- 动态链表
- 创建链表
- 保密,解密
- ASCII码
- 空格:32
- 0:48
- A:65
- a:97
- ASCII码
- 冒泡排序、选择排序
- 常用头文件
- include <stdio.h>或include “stdio.h”
- 结构体FILE的声明
- printf
- scanf
- NULL(0)
- EOF(-1)
- include <math.h>
- sqrt(x):求平方根
- abs(x):求整数的绝对值
- fabs(x):求双精度型的绝对值
- sin(x):求sinx的值
- cos(x):求cosx的值
- exp(x):求e的x次方的值
- log(x):求lnx的值
- log10(x):求log10x的值
- pow(x,y):求x的y次方的值
- include <stdlib.h>
- malloc
- calloc
- realloc
- free
- exit
- include <string.h>
- strcmp:比较
- strlen:长度
- strcat:连接
- strcpy:复制
- include <stdio.h>或include “stdio.h”
- 手写代码注意事项
- 记得加分号
- 检查所用变量的定义是否完整
- 定义变量时就赋初值
- scanf记得&
- 记得fclose(fp);
- 用if-else时关注条件是否完整,是否能得出所要求的结果
- 检查头文件是否包含完整
- 检查函数返回值是否相符
注
- float型能得到6位有效数据
- double型能得到15位有效数据
- 仔细看循环后有没有逗号结尾或者{}
- \t可对齐(左对齐)
#include <stdio.h>
int main()
{int a=123,b=1324,c=456897;int d=123,e=1324,f=456897;printf("%d\t%d\t%d\t\n",a,b,c);printf("%d\t%d\t%d\t\n",c,a,b);return 0;
}
输出结果:
- c程序中的实型常量都作为双精度浮点型常量
- 表达式末尾无分号,语句末尾有分号
- 用赋值语句只能将一个字符赋给一个字符型变量或字符数组元素
- 除数不能为0,错:x%=0
- do-while的{}可以省略,省略后循环体内只能有一条语句
- %、位运算都只能用于整型运算
- while(0);是合法的
- if语句的圆括号内表达式可以为任意表达式
- char
- 无符号的范围为0~255,255+1==0
- 有符号的范围为-128~127,127+1==-128
- 被定义的宏名PI ,在程序中不可以重新定义
- 只能给指针变量赋地址值或NULL
- char b[10]={“hello!”};中的{}可以省略
- sin(25°)的C语言表达式为sin(3.14/180*25)
- strlen函数遇到’\0’(不包括‘\0’)时才停止,若字符串中没有‘\0’则返回的是一个随机值
- printf(“%f”,8/5);的输出结果为0.000000
- 被包含文件的后缀未必是.h,也可以是.hpp、.hxx
- 转义字符\1代表ASCII码为1的字符
- 若定义 int fun(int a); int (*p)(int)=fun; 可以正确调用 fun 函数的为:fun(5); (&fun)(5); (*fun)(5); p(5); (*p)(5);
- 声明但未定义的函数在调用时会在运行时报错
- C程序必须由一个或一个以上的函数组成
- 一行只可出现一个预处理命令行
- for( ; ; );表示无限次循环(死循环)
- 字节对齐
- 结构体当前大小%当前变量自身有效对齐字节数=0,如果无法对齐,则持续填充字节直至对齐
- 结构体的总大小%结构体最大对齐字节数=0,如果无法对齐,则持续填充字节直至对齐
- if(a<=b<=c)逻辑成立,相当于if((a<=b)<=c)
- 形参只能是auto,register类型
- 静态变量(static)、全局变量(extern外部变量)、常量(const)的内存分配和初始化都是在编译阶段完成;而其他变量的内存分配在编译阶段进行,初始化在运行阶段
- c11:\u 加四位十六进制数也可用于标识符,桂工一般用c99
- &&比||高一级,设a++||b- -&&c++;理论上是先算&&再算||, 但是实际上 C 语言有个机制就是当||左边非 0 时不会再计算右边, 即使右边的运算符再高也不会算。同样的如果&&左边为 0 也不会计算右边
- 255的二进制表示为11111111
- 若ch为无符号字符型,则ch- -;后ch在内存中的补码为11111111,表示值为255
- 下面代码的输出结果为97 a 0.000000
#include <stdio.h>
int main()
{union Date{int i;char ch;float f;} date;date.i = 97;printf("%d %c %f", date.i, date.ch, date.f);return 0;
}
- int a =1234;
- printf(“%-08d”,a);输出:1234
- printf(“%08d”,a);输出:00001234
- %\ *和 \ *.*的形式,一般用于整数%和字符串%s的情况下
- 在scanf里只有%*d和%.*d有意义(其他会报错)
- %*d(仅它有意义:忽略掉它本身,并重新匹配),如:scanf(“%*d %d”,&a,&b);输入1234 789后a的值为789
- %.*d(仅它有意义:忽略%.*d的下一个输入,并重新匹配),如:scanf(“%.*d %d %d”,&a,&b,&c);输入1234 89 56后b的值为56
- printf
- %*d、%*f、%*s(意义:肯定会输出全部,根据实际情况补空格),如:int a=123;printf(“a=%*d”,5,a);输出:a=空格空格123
- %.*d(意义:肯定会输出结果,根据实际在前面补0)
- %.*f(意义:指定小数点后面几位,跟%.nf是一样的)
- %.*s(意义:指定截取前面几位数)
- 在scanf里只有%*d和%.*d有意义(其他会报错)
- 若ch为char型变量
- 表达式~ch^ch的值用十六进制表示为:ffffffff(FFFFFFFF)
- 表达式(ch&1)==(ch%2)的值为:1
- 关键字(_bool改为_Bool)
- 易忘
- unsigned、signed、goto、break 、case 、default 、return 、const 、sizeof、typedef、volatile、inline、restrict
- 易混淆
- main、include、define
- 易忘
这篇关于桂林理工大学电子信息877C程序设计专业课复盘的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!