C语言程序设计教程(第二版)黄迪明
- C语言的特点:
①兼具高级、汇编语言的优点;②结构化程序设计语言;③数据类型丰富;④运算符丰富;⑤具有预处理功能;⑥可移植性好。 - HGY中的new point:
①浮点数强转整数,直接丢弃后面,但是规格化时,注意四舍五入;
②使用getchar()先去吸收一个换行符!
③&& 比 || 高,& 比 | 高;
④if-else,while 循环判断语句都是单个语句!
⑤区分大小写,name 和NaMe不同
⑥scanf里面不要添加 说明字符和换行符,因为字符串读取需要匹配类型符号,(scanf(“Input a number:%d”),必须在输入端输入Input a number:10,所以增加工作量),double的格式为 %lf,但是可用%f输出,printf从右向左执行,强制转换 。
⑦else没有括号时就近匹配,break跳出其所在的循环结构,continue忽略后面的语句立即转去控制表达式,goto语句只能从内层到外层。
⑧字符数组逐个元素初始化,数组长度等于[表达式]值或 隐式初始化个数;使用字符串初始化时,数组长度为字符长度+1,末尾一定要有 ' \0 '
⑨指针初始化,*point = data[i]没有对指针进行初始化,试图直接使用指针!
⑩typedef定义函数,等价于 自定义别名,typedef int INTEGER;
- 关键字、保留字、标识符的区别:
标识符:满足字母、数字、下划线且首字符不是数字的字符串,分为用户自定义的和系统已经预定义的。
关键字(保留字):是指系统预先定义的具有特殊含义的标识符,这部分被系统保留,不允许编程者重新命名。
- 优先级口诀:
单目>双目>三目>赋值>逗号运算;双目中:算术>关系>逻辑;移位操作>关系>位运算;
圆括号最高,逗号最低;只有运算赋值符(=,+=,>>=,&=),单目运算符(!,~,-,*,sizeof),三目运算符(? :)是从右到左的,其他全部都是从左到右
- 强制类型转化规则,出现场合?
char< short< unsigned short< int<unsigned int < long <float < double
显示强转;函数调用;双目运算符;函数返回值;赋值运算符;
强转只是中间暂时的,不影响变量原定义的类型;
- 输入输出:
控制台:getchar(),putchar() ;gets(),puts(); printf(),scanf();
文件:getc(),putc() ; fgets(),fputs();fprintf(),fscanf();fread(),fwrite();
- 宏定义:
#define 标识符名 字符串 (没有分号)
#undef 标识符名
不带参数的: #define TRUE 1 简单的字符串替换
带参数的: #define MAX(a,b) a>b?a:b 根据具体实参,用表达式替换掉标识符,宏展开时将参数原样代入,不可以先计算值再代入# define MUL(x,y) x*y s = MUL(3,2) = 3*2 =6; s = MUL(2+1,3+2) = 2+1*3+2 =7; 原因:宏展开时本质上是直接展开
优点:执行速度快,在预处理阶段展开,减少了允许时的开销;
缺点:使用过多导致代码长度长,一旦被定义将被该文件可见
全国计算机等级考试-二级(高教版)
- 结构化程序: 顺序、分支、循环
- C语言文件:.c、.obj、.exe
- 标识符:关键字(禁止)、预定义标识符(合法但是最好避免,IO标识符)、用户标识符
- 赋值表达式左边不能是表达式或者常量,如x++ = x+1,编译错误
- 合法常量常见规则说明:
①数值常量分为整型、实型
②整型只用有效数字且不带小数点,可以用必须0开头的八进制(不能超过7),可以用0x/0X开头的十六进制(不能超过F/f),可以用十进制(数字间不允许出现空格和其他字符),int 和 long :默认存储为int,强转long末尾加L/l。(019非法八进制,0L合法长整型)但是默认输出时没有前导0/前导0X,%X表示字符大写输出(可以格式化%#o,%#x分别前导输出)
③实型可以用必须带小数点表示(0. ,.123,123.0 ,即允许小数点前后无数字),可以用指数表示(12.343e2,0.12323e2,.2E0,e/E前一定要有数字且指数部分是整数),规范化:指e/E前面的数字中小数点前面只有1位非零数字(2.34e4,3.09999E1),float和double:默认存储类型为double,强转float必须末尾加F/f,强转long doube 末尾加L/l。 -
语句是指由{ }括起来的全部,并以 ; 结束,所以复合语句仍为一条语句;表达式是指不以 ; 结束的表达式(可能存在多个逗号,逗号运算符)
- 格式化输出:%md,靠右占m格,%-md,靠左占m格,%0md,靠右补0,%+0md靠右以+号开头补0;
- *p[ ] :括号优先级高[ ],本质上为数组,各个元素为指针;
(*p)[] :()优先级更高,本质为指针,指向一个数组;二维数组中的行指针
判断注意点:数组名不能++、--;左右类型要相同;指针不能当成数组用; - 字符数组本身不要求最后必须是’\0‘,但是你使用的是字符数组存储一个字符串时,必须数组末尾以'\0'结束。
数组加'\0'规则:已指定数组长度,以单字符赋初值。初值个数<=长度-1 由系统自动加 '\0',也可人为加;当初值个数 = 长度,则不能作为字符串使用,只能作为字符数组。
若未指定长度,以单字符赋初值,必须加'\0'
若指定长度/未指定,以字符串常量赋初值,系统自动加'\0',此时长度必须满足 字符数量+1
- 当给指针型的字符串数组元素重新赋字符串时,输入字符个数不能超过原字符串中字符个数,因为利用的时源字符串的无名存储空间。如:char *p ={"aa","b"}; for (i=0;i<2;i++)gets(ps[i]);输入的字符个数不能超过原字符串的长度
- 字符串输入输出:使用scanf的%c 或者 getchar() 时,必须末尾追加'\0'; 使用scanf的%s时会导致空格、换行、Tab都被作为'\0'结束符,所以不能得到真正的字符串。 使用gets() 以换行符作为结束符,puts()以第一个'\0'作为结束
- main函数的参数:
main(int argc ,char **argv)或main(int argc, char *argv[]) 分别表示从命令行接收的参数个数、参数字符串数组。参数类型和顺序固定
如:输入:test.c 23 18 则argc =3,argv[0] ="test.c”,argv[1] ="23",argv[2] ="18".注意argv[0]必须是当前可执行文件的文件名
- 全局变量默认为extern, 显式声明为static时限制其只能在本编译单元使用。
局部变量默认为auto,还可以是extern,register,存储方式不同
形参默认为auto,不能为register
函数默认为extern,显式声明为static。
静态类:static、extern为固定存储单元,系统在编译时默认初值0.
- 编译预处理命令行不属于C语句,因为以(#) 开头,不以(;)结束。
一条有效的预处理命令必须单独占据一行
宏命令的处理是在预编译阶段,即:字符串替换 - 动态存储分配:在使用malloc/calloc/free函数时,头文件为<stdlib.h>
在申请存储单元时:最好使用sizeof( )计算,避免因为操作系统不同导致所占字节数不同
malloc/calloc函数的返回值为无类型指针(void *),所以根据实际情况,强制进行类型转换。
- 文件指针FILE ,包含在头文件<stdio.h> ,所以要写出预编译命令行
- C语言的数据文件分为文本文件和二进制文件:
文本文件:文本文件可以直接在终端显示,输入/输出速度较慢
二进制文件:在内存和磁盘中都是二进制形式,不能在终端显示,输入/输出速度较快,
- C语言对文件的存取方式分为顺序存取和直接存取:
顺序文件:输入/输出都是从文件头开始,如fseek(SEEK_SET)
直接存取:指定对文件的某个字节进行读/写,如fseek(SEEK_CUR)
- 文件的指针:
读/写位置指针:读/写完一个字节数据后,便移动到下一个字节
打开文件:文件的指针指向第一个字节之前,即文件的开头;
运行C程序时,系统自动代开三个文件,分别是标准输入设备文件、标准输出设备文件、标准出错信息文件;
分别为指针stdin,sdtout,stderr,都在<stdio.h>中定义。
FILE* fp; fp =fopen("test.txt","w");注意转义字符和(" "),失败返回NULL
文件结束函数feof(): 返回值为0/1
- 文本文件的输入输出库函数:
fputc(ch,fp);将ch字符放入fp所指的文件中;成功返回ch,失败返回EOF=-1;
fgetc(fp);从fp所指文件返回一个字符ch,成功返回ch,失败返回EOF=-1;(EOF,NULL都是预定义的符号常量,但是在二进制文件中-1可能为数据,所以二进制文件中用feof(fp)来判断是否结束!)
fgets(str,n,fp)从文件中获得一个长度为n-1的字符串(包括'\0'结束符)放入str中;成功返回首地址
fputs(str,fp);将str放入fp中,字符串末尾的'\0'不输出,所以连续使用fputs()将导致字符串首尾相接。成功返回0,失败返回EOF;
fscanf(stdin,"%d%d",&a,&b); stdin为标准输入文件的文件指针
fprintf(sdtout,"%d%d\n",a,b);stdout为标准输出文件的文件指针
- 二进制文件的输入输出库函数:
fread(buffer,size,count,fp):从fp中获取count个大小为size的数据放入buffer中
fwrite(buffer,size,count,fp):将buffer中count个大小为size的数据放入fp中
- 文件定位函数:
rewind(fp):将文件指向文件头部,从头获得/从头重新写文件,原始数据不存在
fseek(fp,offset,origin):对于二进制文件,origin用标识符 SEEK_SET(0)、SEET_CUR(1)、SEEK_END(2)分别表示文件开头、当前位置、文件结尾。offset的类型为长整型,强制类型为L,单位为字节数。例如:fseek(fp,-5L*sizeof(double),2);
对于文本文件,offset必须是0,即fseek(fp,0L,SEEK_SET);