导图社区 C语言
C语言基础知识点串联思维导图,帮助学习者更好地掌握C语言的编程方法和技巧。适合作为C语言学习的知识和复习资料。
编辑于2026-01-12 17:41:10C语言
第一章:基础知识
1.进制转化
在计算机内部,程序,数据,信息均采用二进制表示
十,二,八,十六进制表示方法及其数字
一定要注意表示范围
2的次幂
二、八、十六进制———十进制
按权展开求和
十进制———二、八、十六进制
十进制、二进制相互转化重要结论
除N倒取余
二进制———八进制
421法
二进制———十六进制
8421法
2.原反补码
整数在计算机内部采用补码的形式表示
原码
八位二进制 符号位+数值位 0为正1为负
反码
正数:原码=反码=补码 负数:原码符号位不变,数值位按位取反
补码
负数:补码=反码+1
真值———见P4页例五,P12页计算题例4 真值:将带符号位的机器数(二进制数)对应的真正数值称为机器数的真值。 —3转换成二进制:10000011 真值=符号位(-负)+0000011()转换成十进制是3 =-3
3.无符号数———关键字unsigned
不能表示负数,只能表示0和正数
4.ASCII码
0~9 48~57 A~Z 65~90 a~z 97~122
大写ASCII+32=小写
ASCII值也是整数可以用%d输出
西文字符在计算机内部输出的是ASCII值
空格ASCII码值为32
5.C语言基础
1.C语言是一种高级语言,高级语言编写的程序叫做源程序 2.由C语言编写的源程序的扩展名为.c 3.C语言的源程序经过编译后生成目标文件(.obj),再经过链接后生成可执行文件(.exe)
1)C语言的可执行程序时候一系列机器指令构成的 2)用C语言编写的源程序不能直接在计算机上运行 3).exe 文件是可执行文件,可以直接在window系统上运行,与安装C语言开发集成环境无关
执行过程:编译和链接
基本结构
高级语言分为面向过程高级语言和面向过程高级语言,C语言是一种面向过程语言,也叫做结构化程序设计语言
C语言三种基本结构:顺序结构,选择结构,循环结构
特点
1)一个C程序是由若干个函数组成,函数是组成C程序的基本单位 2) C程序有且只有一个主函数(main),主函数在程序中的位置可以任意 3)C程序总是由主函数开始执行,并且结束于主函数。 4)每条C语句是以分号结束,一行可以写多条语句,一条语句也可以写成多行。 5)所有代码结尾要写 return 0;
错误
1)语法错误——可以通过编译意味着无语法错误 2)逻辑错误——只能认为发现,俗称bug
调试程序是指对程序进行查错和排错
C语言本身没有输入输出语句,用函数实现输入输出
6.标识符
标识符命名规则
1)由阿拉伯数字、英文字母种下划组组成。 2)开头的不能为数字。 3) 区分大小写(例如sum和SUM在C语言中是两个不同的 4)不能采用C语言中的关键字作为标识符
32个关键字
include不是关键字
关键字均是小写
具体32个关键字
注释
提高可读性
有两种 1) /* */ 2) //———是在一条C语句后添加注释
第二章:数据类型和运算符
1.变量
1)用于保存数据, 2)变量的值可以改变, 3)变量是占用系统内存的———一旦定义变量,系统会为该变量分配内存空间
常量的值无法改变
用print函数输出变量值时要用到格式控制符
2.简单数据类型
整型——整数
十进制整型在计算机内部以补码形式表示
整型进入计算机内部,运行过程 有前提条件假设int占2个字节就有十进制整型——转换成—————十六位二进制补码(看占几个字节) 接着依据题目要求将二进制补码转化为合适的进制,八进制或十六进制
整型常量
C语言是高级语言,能表示的进制以十进制,八进制,十六进制,不能表示二进制 不同进制有不同的格式控制符
C语言中无二进制,计算机内部有二进制
十进制整型(默认)
格式控制符
%d
例如:32
八进制整型
格式控制符
%o(英文字母欧)
表示方法:前导为0(数字0)
注:定义有前导,输出无前导
例如:032
十六进制整型
格式控制符
小写:%x
大写:%X
表示方法:前导为0x或0X (数字0,大小写都可以)
注:定义有前导,输出无前导
例如:0x5ab或者0X5ab
整型变量
int型——常见型
字节
VC环境下占4个字节 TC环境下占2个字节
1字节=八位二进制 2字节=十六位二进制
所占内存不同,表示的整型范围也不相同 占2个字节,所表示的整型范围:—32768~32767(会涉及溢出问题32767+1=32768)
short 型——短整型
占2个字节
long型——长整型
格式控制符%1d
例题:2L——L代表长整型,2L是C语言常量
无符号数unsigned
格式控制符%u
没有符号位,只有数值位
例:unsigned int a; 定义一个无符号整型变量,a不能表示负数
设int 型占2个字节,unsigned int型表示的整数范围:0~65535 (0十六位二进制是16个0,65535十六位二进制是16个1)
详细例题见P18页
实型(符点型)
实型常量
小数形式
必须要有小数点
指数形式
1)由e或E加数字组成,e或E的两边必须要有数字。 eg:2e5 0.5e4 2)e或E的右边必须是整数(可以加+、 -号),不能是小数 eg:0xE2
实型变量
float型
单精度浮点
占4个字节
格式控制符%f
double型
双精度浮点
占8个字节
格式控制符%lf(小写英文字母L)
字符型———英文字母,标点符号,西文字符
西文字符在计算机内部以ASCII形式存储
字符常量
表示方法:用单引号括起来的单个字符
eg:2和'2'不一样,2是整型,'2'是字符, 字符2输出后对应的ASCII值是50
格式控制符:%c——表示字符原型
注意:定义加单引号,输出无单引号
转义字符常量
以”\“开头
C语言中,表示双引号,反斜杠必须使用反义字符
(重点)常见转义字符(8个)
'\n'————换行 '\t'————跳格(不是空格) '\b'————退格 '\\'————表示\ '\''————表示单引号‘ '\"'————表示双引号” '\ddd'————1-3位八进制ASCII码表示的第一个字符 '\xhh'————1-2位十六进制ASCII码表示的第一个字符 ' '————空格(空格也是一个字符) '\+数字'——表示8进制ASCII '\x+数字'——表示16进制ASCII eg:'\101'表示8进制ASCII 101 八进制(101)转化为十进制是:65,65 对应的ASCII码为A,'\101'='A' eg:'\x42'表示十六进制ASCII 42 十六进制(42)转化为十进制是:66,66对应的ASCII码为B,'\x42'='B '
注意:字符串里的字符不加单引号
字符串常量
用双引号括起来 eg:"ABCD"
格式控制符:%s——表示字符串
字符串结束的标志:"\0"
每一个字符串都有结束标志
空字符串“”,也叫空串
考点: 1)求数据或数据类型所占字节数(包括结束标志:\0)——关键字sizeof 2)求字符串长度(不包括结束标志:\0)——函数strlen
函数strlen使用前要导入库包 #include <string.h>
P22页
1个字符占1个字节
函数strlen使用前要导入库包 #include <string.h>
字符串无法做算数运算
'%%'
l两个%%号表示输出一个%
字符变量
表示/定义:char
char占1个字节,表示的范围是-128~127
char型也是整型
格式控制符%c——字符原型
注意:用字符做加减运算的本质是用ASCII做运算
char ch='a' 用字符常量给字符变量赋值
char ch=66 是用ASCII码只给字符变量赋值
字符输入输出
函数
输入getchar
字符输入函数,功能:从键盘上获取一个字符[回车也是一个字符]
格式:字符变量=getchar()
输出putchar
字符输出函数,功能:将字符原型在显示器上显示
格式:putchar(字符)
数据类型混合运算
整型+字符型=整型
整型+实型=实型
实型+字符型=实型
混合运算只要有实型数据类型一定是实型, 数据的值的类型一定是double型
3.运算符
1.算数运算符
+
-
优先级同级
优先级是指结合的先后顺序,不是计算的先后顺序,运算顺序一直是从左到右, 先结合起来不计算,结合完毕后依次从左到右计算
*
/
a/b 1)整型/整型=整型(有小数结果只保留整数部分) 2) 整型/实型=实型(没有也要补小数位eg:6.0/3=2.0
一定要注意 商为0
1/2*a*b 错误 /号左右均是整型,结果也为整型,1/2=0; 改正:1.0/2.0=0.5
%
1)求余运算对象必须是整型,即%左右两边必须是整型 2)求余运算结果的正负必须和%左边的数字保持一致
重要结论
1)判断整数的奇偶 方法①:若n%2==0,n为偶数;(判断两个数是否相等中间用==号) 若n%2==1,n为奇数; 方法②:n & 0x1 ==0,n为偶数;(&按位与,0x1十六进制的1) n & 0x1 ==1,n为奇数; 方法③:2n-1奇数 2n偶数
方法一:P26页,方法二:P215页
2)判断整除 若n%k==0,n能被k整除
能否被整除可以用来判断是否为因子(约数)
3)获取正整数n的各个位数
个位数:n%10 十位数:n/10%10 百位数:n/100%10 千位数:n/1000 个位数+十位数:n%100
可以用来实现倒序输出、求各位数之和
常用第四章的关系运算符, 逻辑运算符结合考
优先级同级
2.赋值运算符
赋值运算符左边不能是 表达式和常量
=
(重点)交换a,b变量值的核心代码 t=a; a=b; b=t;
h还可以用按位异或实现
+=
a+=2———a=a+2
-=
可以用来求最大公约数·——更相减损法
核心: while(a!=b){ if(a>b) a-=b; if(a<b) b-=a; } printf("%d",a}
*=
/=
降位操作:n/=10
也可以用于倒序输出
可以用来判断正整数位数
连续倒序输出 值4312输出为1234 S=S*10+n%10; n/=10
判读一个数是否为回文数
回文数:一个正整数正序输出=倒序输出
方法: 连续倒序输出
%=
加上交换变量值核心代码可以实现求最大公约数——辗转相除法
核心: while(b!=0{ t=a%b; a=b; b=t; } printf("%d",a}
复合赋值运算符
重点例题p28页例14 +=-=*=连用 eg: a=3,执行a+=a-=a*=a a*=a——>a=a*a=9,数值更新a= 3 9 a-=a——>a=a-a=0,数值更新a= 3 9 0 a+=a——>a=a+a=0 结果:a=0 注意:赋值运算符会改变初始变量的值
3.加加、减减运算符
++、--(自加1,自减1)
单目运算符,只有一个运算对象
运算对象必须是变量,不能说常量或表达式
区分在前在后
4种情况: 1)用printf函数输出时 2)与其他运算符混合使用时 3)用于判段真假时 4)作为函数实参时
与=一起也算连用,b=a++,混合运算,区分在前在后
用法
++,--在前时 先+1,在用值
++,--在后时 先用值,用完后在+1
结合性:自右向左
4.逗号运算符
自左向右计算每一个表达式,将最后一个表达式的值作为整个逗号运算表达式的值
重点例题: eg:表达式(a=2,a++,a*2)值为6
逗号运算中,如果++,--出现在中间位置(不是发在最后) ,就不区分++,--在前在后,只+1
重点例题: eg:表达式(a=2,a*2,a++)值为2
出现在最后区分++,--在前在后
重点例题: eg:表达式(a=2,b=a++,a+b)值为5
出现在中间位置,与其他运算符混合运算要区分++,--在前在后
重点例题: eg:表达式a=c++,b++
(a=c++),b++
b++不区分在前在后
5.强制类型转换符
格式:(变量)或(类型名)
只对变量值进行类型转换,不改变变量的值
eg:(int)a (a+b)
第三章:顺序结构
C语言本身没有输入输出语句, 用函数实现输入输出
输出函数printf
将信息输出到显示屏上
该函数所在头文件·:“stdio.h”
格式·:printf(" ")
printff函数双引号里有什么,输出就显示·什么
1.数据的输出
整型数据的输出
格式控制符%md
1)m代表输出数据的总宽度 2)实际宽度>m, 原样输出 实际宽度<m, 输出时需要补空格
m为正,左边补空格
m为负,右边补空格
一个字符占一个宽度,一个空格占一个宽度
实型数据的输出
格式控制符
1. %f
默认保留六位小数
2. %m.nf
1)m代表输出数据的总宽度 2)n代表保留的小数位
正负号、小数点也占一个宽度
保留时小数位要四舍五入
同样m也要补空格
3. %0.nf
作用是保留到n位小数
字符型数据的输出
格式控制符%c
输出字符原型
字符串的输出
使用printf函数输出字符串
1)输出全部字符串数组: eg:char s[3]; printf("%s\n",s); 2)输出部分字符串: eg:char s[5]=“ABCDE”; canf("%s\n",s+2); 键盘上输出内容:CDE
字符串结束标志\0不输出
是输出字符串的起点
字符串输出是只有遇到\0就结束输出 eg:char s[5]=“AB\0CDE”; canf("%s\n",s); 键盘上输出内容:AB
使用puts函数输出字符串
格式: puts(s)
输入函数scanf
作用:从键盘上获取数据输入到指定变量中
该函数所在头文件·:“stdio.h”
固定格式:scanf(" 格式控制符",&n)
$是取地址运算符,对变量进行输入时要加取地址运算符 n是变量
2.数据的输入
整型数据的输入
标准输入
只有格式控制符,格式控制符间没有空格和其他字符 如:scanf("%d%d",&a,%b) eg:int a,b; scanf("%d%d"&a,&b) 键盘上输入格式:2 空格 3或者2空格空格3或者2回车3回车
可以实现连续输入
【指定输入数据的宽度】 eg:输入123456 int a,b; scanf("%2d%3d"&a,&b) a的宽度为2——a=12,b的宽度为3——a=345
非标准输入
输入时与输入格式(双引号里的)保持一致, 1) scanf("%d,%d"&a,&b)————有错误,尽量不使用 eg:int a,b; scanf("%d,%d"&a,&b) 键盘上输入格式:2,3<回车>(也可以表示成<CR>)回车也是一个字符 2) scanf("a=%d,b=%d"&a,&b) eg:int a,b; scanf("a=%d,b=%d"&a,&b) 键盘上输入格式:a=2,b=3<回车>
实型数据的输入
输入实型数据时无法指定小数位数 eg:scanf("%5.2f",$n)是非法语句
可以指定数据宽度
字符型数据的输入
1.回车、空格都属于字符
1) eg:char ch1,ch2; scanf("%c%c"&ch1,&ch2) 键盘上输入格式:AB<回车> 2) eg:char ch1,ch2; scanf("%c,%c"&ch1,&ch2) 键盘上输入格式:A,B<回车>
2.【整型、字符型混合输入】 遇到先输入整数在输入字符的情况时, 整数与字符间不能有空格和回车
字符串的输入
使用scanf函数输入字符串
1)输入单个字符串: eg:char s[3]; scanf("%s",s); 键盘上输入格式:abc<回车> 2)输入多个字符串: eg:char s[3],c[3]; canf("%s,%s",s,c); 键盘上输入格式:abc,bcd<回车>
对字符数组进行输入时,不加取地址运算符$,只写数组名即可 但对字符变量进行输入时要加
%s——字符串格式控制符
scanf无法输入带空格的字符串,遇到空格会截断
输入 ABC空格BCD<回车> 只能输入 ABC 剩下的部分被截断了
使用gets函数输入字符串
gets函数头文件<stdio.h>
gets可以输入带空格的字符串
格式: gets(参数);
参数只能是数组名或者·指针名
一次只能输入1个字符串
gets(s,c)——错误语句
3.空语句
单独的分号表示空语句,含义是什么也不做
4.复合语句
用大括号{}括起来的多条语句
第四章选择结构
1.运算符
6.关系运算符
>、<、<=、>=、==(等于)、!=(不等于)
注意“≧”“≦”是数学符号,不是c语言符号
例题: (c=a==b)||(d=b==a) 赋值运算符=结合性最低,先算a==b, 再将a==b的值赋给c
结合性:自左向右 运算方向:自左向右
作用:比较数值的大小
关系表达式运算规则: 1)表达式为真,值为1 表达式为假,值为0
eg:5>4>3值为? 数学上:5>4>3为真 C语言上:自左向右看,5>4真,值为1, 再次比较1>3假,值为0 最终值为0
7.逻辑运算符
C语言里规定,0代表假,非零数字代表真
运算符
逻辑与 &&(优先级高于逻辑或)
运算特点:有假则为假——0
'0'&&'A'——字符常量'0'对应的ASCII码值为48
双目运算符
逻辑或 ||
运算特点:有真则为真——1
双目运算符,
逻辑非 !
结合性自右向左
运算特点: !假 = 真 !真 = 假
!exp等价于exp==0
exp等价于exp!=0
衍生结论:(“与”也可以说成“且””否“是指逻辑非!) ①“(A与B)的否 ”等价于 “ A的否或B的否” ②“(A或B)的否 ”等价于 “ A的否与B的否” 例题见P66选择题2
逻辑表达式运算规则: 1)表达式为真,值为1 表达式为假,值为0
短路运算
短路是指遇到为假的情况后面表达式无法继续执行
"与"短路
假&&【后面式子】 【后面式子】被短路; 真&&【后面式子】 【后面式子】继续执行
"或"短路
真||【后面式子】 【后面式子】被短路; 假||【后面式子】 【后面式子】继续执行
逻辑与优先级高于逻辑或 所以"与"短路不影响后面"或"的相关
X=Y=Z=-1; 1) ++Y&&++X || ++Z; ( ++Y&&++X) || ++Z; 红色部分:0->假,假&&后面式子++X,++X 被短路 ( ++Y&&++X)整体为假->0 0 || ++Z; 假 ||后面式子++Z,后面式子++Z继续执行,逻辑或有真则为真,Z=0(非零数字为真),所以0 || ++Z结果为真->1 整个式子运行结果为1 X=-1,Y=0,Z=0
见P55页例8
第十三章 位运算
程序中的所有数在计算机内部是以二进制的形式存储的
二进制只有0和1
位运算直接是对 整数在内存中的二进制 进行操作
整数——进入计算机内部——转化为二进制补码 位运算是对这个二进制数进行运算——即只对0和进行运算
十进制整型,字符型数据参与位运算,用它们补码进行运算
八进制,十六进制参与位运算,直接将它们转化从二进制 进行运算即可
运算符
按位与 &
做取地址运算符时是单目运算符
双目运算符
运算特点:有0就是0 1&1=1,1&0=0,0&1=0
与0做按位与运算叫做清零运算
与1做按位与运算叫保持不变
eg:将高四位清零,低四位保持不变
高四位与0做按位与运算, 低四位与1做按位与运算
& 00001111
可以用来判断奇,偶
方法②:n & 0x1 ==0,n为偶数;(&按位与,0x1十六进制的1) n & 0x1 ==1,n为奇数;
按位或 |
双目运算符
运算特点:有1就是1 1|1=1,1|0=1,0|1=1
与1做按位与运算叫置1运算
与0做按位与运算叫做保持不变
按位取反 ~
单目运算符
只有一个操作对象
运算特点:0变1,1变0
清零功能
按位与上自己的取反数 m=m&~m
按位异或 ^
运算特点: 相同为0,不同为1
相同:0^0=0 ,1^1=0 不同:0^1=1 ,1^0=1
将变量清零 char a; a=a^a
与0异或运算结果不变还是0, 与1异或运算结果取反
相同:
不同:
取反功能
与1异或即可
也可以交换两个变量的值
a=a^b; b=b^a; a=a^b;
左移运算符<<
将二进制的各个位数全部左移n位
对与无符号数,左移右边补0,最高位左移后溢出,舍弃
没有负数,只有0和正数
左移n位,扩大了2ⁿ倍
右移运算符>>
将二进制的各个位数全部右移n位
对与无符号数,右移左边补0,低位溢出,舍弃
左移n位,缩小了2ⁿ倍
(超级重点) 逻辑运算符、 关系运算符会涉及 数学公式改C语言表达式
例题: 1> x≧y≧z, 改写:(x>=y)&&(y>=z) 2> x的范围是[1,5] 改写:(x>=1)&&(x<=5) 3> x是一个大于100的奇数 改写:1.(x>100)&&(x%2==1) 2.(x>100)&&(x%2!=0) 3.(x>100)&&(x&0x1==1)——一个& 叫按位与 4>char ch; ①ch为大写英文字母 改写: (ch>='A')&&(ch<='Z') ②ch为小写英文字母 改写: (ch>='a')&&(ch<='z') ③ch不为数字 改写: (ch>='0')&&(ch<='9') 5>整数n能被3整除且个位数为1 改写: (n%3==0)&&(n%10==1)
4,.条件运算符
?:
唯一的三目运算符
结构: 条件?值1:值2
eg:x>y?x:y
结合性:自右向左 运算方向:自左向右
执行过程
条件为真,整个表达式运算结果为值1 条件为假,整个表达式运算结果为值2
经典案例 1) 求绝对值的经典写法 int x=-5,y ; y=x>=0? x : -x; 2)求最值的经典写法 int x,y,max(最大值) ; max=x>y? x : y; 3)表达式在C语言中表示为exp,exp可以是任意一个式子 结论:exp等价于exp!=0 !exp等价于exp==0 eg: x是奇数,!(x%2)等价于x%2==0
2.if语句
if单分支语句
结构: 1)if(条件)单条语句; 2)if(条件){ 语句1;语句2;…………语句n}(这里不用加分号)——是复合语句, 复合语句一定要加大括号
“条件”:if (a++)t=a;这种情况a++用于判断真假, 需要区分++在前还是在后
结构1一定要注意是否有大括号
eg:if(x>y)z=x;x=y;y=z; 前面才是这个if单分支的语句 也可以写成这种3行形式: if(x>y)z=x; x=y; y=z;
执行过程
条件为真执行语句, 条件为假不执行
要执行都执行,要不执行都不执行
eg: 1)if(a=0)t=2; 0在C语言中代表假,即条件为假 2)int a=0; if(a==0)t=2; 0==0为真,执行t=2
if双分支语句——if else
结构: 1)if(条件){ }else { }
一定要注意大括号
执行过程
条件为真执行语句1, 条件为假执行语句2
特点:语句1,语句2二选一,只执行一条
if-else嵌套
配对原则: else与它前面最近的、还没有配对的if 配成一对
if多分支语句——if else
结构: 1)if(条件1) { 语句 ; } else if(条件2) { 语句 ; } else if(条件3) { 语句 ; } else if(条件4) { 语句 ; } …………… else if(条件n) { 语句 ; } else 语句n+1;————这条可有可无
特点:哪个条件成立执行那条语句,都不成立执行最下面那条else语句
条件(a<b<c)极其易错
3.switch语句
结构: 1)switch(表达式exp){ case 常量1:语句 ; case 常量2:语句 ;break; case 常量3:语句 ; …………… case 常量n:语句 ; default :语句 ; }
1)表达式在C语言中表示为exp,exp可以是任意一个表达式 2)case后面的常量必须为整型常量和字符型常量,也能为整型、字符型的常量表达式
①default语句可有可无,且default语句位置任意,习惯上放到最后 ②若default语句在其他位置(不在最后如第一), 执行的时候要执行default语句和它后面的所有case语句
break的作用是终止、结束 1)运行到break时,结束整个switch语句 2)在switch嵌套中,break只结束它所在的那一个switch语句 3)break语句可以用到switch语句,循环语句
注意冒号不要丢
defautl表示其他分支
执行过程
相当易错
1)计算括号里面表达式的值 2)表达式的值等于某一个常量时,就执行对应语句, 并且从当前语句开始向后执行所有语句,default语句也要执行 3)若表达式的值与常量一个都不符合,就执行default及其后面语句
switch嵌套
结构: 1)switch1(表达式){ case 常量1: switch2(表达式){ case 常量1:语句 ; case 常量2:语句 ; } case 常量2:语句 ; }
在语句中进行嵌套
第五章循环结构
循环三要素
超级重要
①初值
②条件
③增量
1.while循环
结构: 1)while(条件)单条语句; 2)while(条件){ 语句1; 语句2; ………… 语句n; }
“条件”:while(a++)t=a;这种情况a++用于判断真假, 需要区分++在前还是在后
语句1;语句2;…………语句n是循环体
while循环的增量在循环体里
执行过程
1)先判断条件,条件为真执行循环语句; 2)执行完语句再次判断条件,条件为真时继续执行循环语句; 3)直到条件为假时结束循环
执行的是整个循环体
特点:先判断条件再执行循环语句,循环语句也可能一次都不执行
无线循环/死循环: 1)条件为假,循环语句一次都不执行 2)条件用于为真,循环语句一直执行 经典死循环:
① while(1314)我爱你——是无限循环 1314是整型常数,非零数字在条件中为真 ②while(0)我爱你;——是死循环
涉及题型:判断死循环 (可能会与溢出问题结合)
eg:假设int占两个字节,判循环是否为死循环  
经典死循环
(重点)while循环结构可以实现的功能: 1)计算阶乘—— 阶乘是指所有≦该数字的 正整数之积(1!=1*1) 2)倒序输出 3)求各位数之和 4)计算输入字符的长度 5)计算奇数相加、偶数相加 6)实现正负混合运算 7)实现分数运算 8)求最大公约数——常考
1)倒序输出  /=10可以降位,可以使四位数变成三位数,三位数变成四位数 2)求各位数之和  3)计算输入字符的长度  4)计算奇数相加、偶数相加 while循环,while循环+if分支 6)实现正负混合运算  8)求最大公约数 方法①:更相减损法 核心:一个while循环嵌套连个if单分支  方法②:辗转相除法 核心:while循环 
while((ch=getchar())!='\n'
用来连续获取一行字符或者一段字符
2.do while循环
结构: 1) do 语句1; while(条件) ; 2)do{ 语句1; 语句2; ………… 语句n; }while(条件) ;
“条件”:while(a++)t=a;这种情况a++用于判断真假, 需要区分++在前还是在后 do while循环条件在后面
语句1;语句2;…………语句n是循环体
注意后面的分号不能丢
执行过程
1)先执行循环语句; 2)执行完语句在判断条件, 条件为真时继续执行循环语句; 3)条件为假时结束循环
循环至少执行一次
2.for循环
结构: for(式子①;式子②;式子③) 语句1; 语句2; ………… 语句n; }
初值
条件
增量
for((i=1;i>5;a++)i+=1; 这种情况a++是式子③,式子③是增量 不需要区分++在前还是在后
注意后面的分号不能丢
式子①②③都可以省略不写
省略式子②相当于条件用为真
执行步骤
超级易错
1)先执行式子①——式子①只执行一次 2)执行式子②判断真假——式子②是条件 条件为真,执行循环体 3)执行循环体再执行式子③ 4)式子③执行完再去执行式子②判断真假 5)直到式子②条件为假,结束循环
优点
可以设置循环次数
对应for循环一定要清楚循环了多少次
(重点)while循环结构可以实现的功能: 1)所有水仙花数 2)判断一个数是否为完数——考过
1)求所有水仙花数——是一个三位数(100≦i<1000),其各个位数的立方和=该数本身 方法1:if-else双分支结构 方法2:for循环+if单分支结构  2)判断一个数是否为完数——考过 基本定义: ①约数:又称因数,a/b,a能被b整除,b就是a的约数 ②真因子:除了自己本身以外的所有约数 ③完数:正整数所有真因子之和==它本身
for循环嵌套彼此不独立可以用来实现行列同时输入
外循环——列
内循环——行
如九九乘法表
3.break语句
break的作用是终止、结束
2)在循环嵌套中,break只结束它所在的那一个循环语句 3)在循环嵌套switch语句 ,若break语句在switch语句中,只结束switch语句 3)在循环嵌套分支语句 ,若break语句在分支语句中,只结束分支语句
4.求质数
绝对重点
一个大于1的整数只能被1和它自己本身整除
只有两个因子(1和本身)
因子:a/b,能整除,b就是a的因子
最小的质数是2
4.continue语句
是循环所独有的语句
结束本次循环继续下一次循环
循环嵌套时,continue只对它所在的循环有效
常考程序填空题
5.循环嵌套
循环嵌套,但独立循环:循环次数=外循环次数*内循环次数
循环嵌套,不独立循环 循环次数=内循环次数
1.九九乘法表 2.三角型结构
只要涉及三角形结构都要用到彼此不独立的循环嵌套
分析循环次数必须会的方法
循环次数
1.设int占2个字节, int x=1; while(x>=1) x++;
循环次数为
int取值范围:-32768~32767 32767+1=-32768
2.设int占2个字节, unsigned int x=1; while(x>0) x++;
循环次数为 65535
int 型占2个字节,unsigned int型表示的整数范围:0~65535 (0十六位二进制是16个0,65535十六位二进制是16个1) 65535+1=0
3.char ch=1; while(ch!=0) ch++;
循环次数为 255
char占1个字节,表示的范围是-128~127
第六章:数组
一维数组
1:一维数组的定义
1.格式: 数据类型 数据名 【常量表达式/常量】
1)表达式在C语言中表示为exp,exp可以是任意一个表达式 2)定义数组时后面的常量必须为整型常量和字符型常量,也能为整型、字符型的常量表达式, 不能为空
"【】"里的是元素个数,也是数组长度,还是数组下标
数组下标从0开始,a【0】叫首元素、a【5】叫尾元素
引用数组下标时数组元素下标可以为变量
定义数组时不可以为变量
数组也要定义数组类型,能定义为整型,字符型,实型
eg:int a【5】
eg:double b【3】
eg:int a【n】 ×
不能为变量只能为整型,字符型常量或常量表达式
sizeof(x)
求数组x的字节数
2:一维数组的初始化
不能连续整体赋值
int a【5】,a【5】={1,2,3,4,5} ×
int a【5】={1,2,3,4,5} √
数组元素个数只能少,不能多
int a【5】={1,2,3,4,5} √
int a【5】={1,2,3,4,5,6} ×
未被初始化的数组元素默认为零
计算数组所占字节数要看是否指明数组长度
指明长度
int a【5】={1,2,3} 实际: 数组实际长度5 所占字节数:sizeof=5*2=10
未指明长度
int a【 】={1,2,3} 实际: 数组实际长度3 所占字节数:sizeof=3*2=6
3.数组元素的遍历
使用循环来顺序输出,输入数组
注意循环输出数组,循环初值从0开始,因为数组下标从01开始
攻擂法求最值
最大值max或最小值mix为擂主
将首元素赋值给擂主
使用循环依次与擂主比较
大于擂主——更换新擂主 (小于擂主——擂主不变,继续比较————代码中不需要写出来)
4.循环移动
循环右移
单个for循环
将下标小的赋值给下标大的 a【i+1】=a【i】;
循环左移
单个for循环
将下标大的赋值给下标小的 a【i-1】=a【i】;
7:一维数组的逆置
逆置:交换数组中数据元素
不是倒序输出
定义数组两个下标,i和j
i是首元素下标,j是尾元素下标
初值:i是首元素下标,j是尾元素下标 条件:i<j 增量:i++,j-- 循环体: { t=a【i】; a【i】=a【j】; a【j】=t; }
最后要遍历输出
原理: 交换更改首元素和尾元素中内容 交换更改下标为2的元素和下标为倒二的元素
8:查找数组元素
1:折半查找法
前提:数组元素是有序的
从大到小或从小到大
定义3个下标,并初始化 首元素下标p=0; 尾元素下标q=9; 中间元素下标m=0
2:顺序查找法
顺序循环查找即可
9:进制转换
1:十进制转二进制,八进制,十六进制
除N倒取余法
定义数组——用于保存余数
将余数保存到数组中a[i]=num/n,同时用num/=2获取新的被除数
10:数组输出斐波那契数列前n项
斐波那契数列:从第三项开始,每一项都等于前两项之和
1 1 2 3 5 8 13 21 34 ......
重点
1.数组首元素a【0】不存储数据
2.数组a【1】、a【2】都保存数据 1
从数组a【3】开始加
11:冒泡排序法
考试绝对重点
对数组中元素进行排序,升序或降序
用到彼此不独立的循环嵌套
!!!循环嵌套标准写法
核心: 外循环是循环次数; 外循环一次,内循环里数组元素从首元素开始依次与其余元素比较
二维数组
1:二维数组的定义+引用
1.格式: 数据类型 数据名 【常量表达式/常量】 【常量表达式/常量】
注意事项同一维数组元素
行、列
int a【3】【4】 该数组是3行4列, 有3*4=12个元素
二维数组时按行存储
二维数组引用时同样,行、列下标从0开始
要注意引用是行列的范围
0~i-1
2:二维数组的初始化
初始化行在前,列在后
同样只能少,不能多,少的补0
易错:!!! 二维数组初始化时行下标可以省略, 列下标不可以省略
行、列下标从0开始
整行初始化
若有缺少数据补0即可
只能少,不能多
二维数组的第一维大小
指行的个数
二维数据加减法
最好画图,见例题:
3:二维数组元素的遍历
1:二维数组的遍历核心代码
彼此独立的循环嵌套
外循环:行 内循环:列
行、列下标从0开始
2:结合攻擂法求最值
3:求平均值
average
注意除法的性质
4:主对角线元素(特点)
主对角线上元素行,列相同
单个for循环·
a[i][i]
5:副对角线元素(特点)
副对角线元素行、列下标和为2
同样单个for循环·
a[i][2-i]
6:下三角元素(特点)
同类型结构: 1.输出* 2.九九乘法表
循环嵌套,彼此不独立
7:上三角元素
4:二维数组的转置
指行、列互换
循环嵌套,彼此独立
b[j][i]=a[i][j]
5:杨辉三角
三角形
1.主对角线上元素都为1 2.第0列上的元素都为1
原本的杨辉三角有点复杂,用二维数组转化为下三角元素表达,比较好理解
第七章函数
1)一个c程序由一个主函数main和若干个其他函数构成 2)由主函数调用其他函数,其他函数之间可以相互调用 3)有且只有一个主函数 4)主函数是C程序开始的起点,也是终点
1.函数
函数的定义分两部分
1.函数首部
函数值类型看函数首部
格式: 数据类型 函数名(形式参数)
注意后面没有分号
没有写函数数据类型,默认int型
fun(int a){ }
2.函数体
形参
有形参的函数 也叫做有参函数
1)函数各个形参之间用逗号隔开 2)每一个形参要有数据类型 3)形参必须是变量
形参不能是常量和表达式
无参函数
没有形参的函数也叫做无参函数
函数首部固定为:
也可以写成void fun (void)
2.函数调用
函数被调用一定会返回,但不一定有返回值
函数可以嵌套调用,不可以嵌套定义
值传递: 不改变主函数中定义的变量的值
1.有返回值的函数调用
一般用来完成一些计算
一个函数只会有一个返回值
涉及参数的传递,参数传递方式有两种 ①值传递————简单变量做实参时是值传递 ②地址传递————可以改变主函数定义变量的值
函数调用结束一定会回到被调用前的位置
函数实参与形参是一一对应的
返回值/函数值类型不看形参,也不看实参,看函数首部
例题:计算圆的面积
例题:求最大值
2.没有返回值的函数调用
一般用来完成一定功能
与有返回值的函数调用有三点不同
1.定义函数类型用void型 2.无返回语句return或者写return;——不能加任何值 3.调用语句:fun(a,b)不能写成:c=fun(a,b)——此时,不要钱=求返回函数值
也可以说void型代表函数没有返回值
函数调用方式
函数语句调用
eg: 1.free();
函数表达式调用
eg: 2.ch=getchar(); 3.printf("%d",sum(a,b);
函数参数调用
eg: 1.x=sum(a,b); 2.x=sum(sum(a,b),max(c,d));
3.形参个数
形参与实参是一一对应的关系
eg:k=fun(fun(a,b),recl,a)——实参有3个,所有形参也有3个
如果实参,形参类型不一致,以形参为主
实参与形参各自占用独立的存储空间
函数形参只在函数的调用期间分配内存
3.函数声明
指定义函数首部
格式: 函数首部;
声明就是函数首部+分号
通常情况下,函数定义在前,调用在后
若调用在前,定义在后要加上函数声明
4.函数递归调用
在一个函数内部之间或间接调用该函数称为递归函数
可以说是函数自己调用自己的过程
主要考:直接递归
不会提高执行效率
递归类似于循环,也可以有结束条件
也可以没有
1:有返回值的递归调用
重点例题
1:递归调用求阶乘
2:递归调用法求斐波那契数列
难题——2:没有返回值的递归调用
特点:倒着输出和找到结束条件
第八章变量
1.变量的作用域
指变量的有效范围
2.分类
1)从变量的作用域角度划分
变量可以分为
局部变量
在函数内部或者复合语句内部定义的变量
只在函数内部或者复合语句内部有效
复合语句·——复合语句内部 函数内部——函数内部
注意
在main主函数内部定义的变量也是局部变量, 只在main内部有效
不同函数定义的局部变量可以同名, 但只在各自函数内部有效
形式参数也是局部变量
全局变量
在函数之外定义的变量叫全局变量
有效范围:从定义变量的位置到本源文件结束
注意
全局变量未被赋值,初始值为0
全局变量与局部变量同名时,局部变量优先,此时全局变量被屏蔽
2)从变量的存在时间(即生存期)角度划分
变量可以分为
静态存储方式 (静态变量)
在程序运行期间由系统分配的固定的存储空间
静态存储区: 全局变量 静态局部变量(static)
全局变量都是静态存储
全局变量和静态变量的初始化是在编译阶段进行的
静态局部变量的作用域为它所在的局部,生存期为整个程序运行期间
静态变量的生存期是整个程序运行期间——直到程序运行结束才释放空间
在编译时赋值,程序运行期间不释放空间
未被赋值的,默认的初值为0
动态存储方式(动态变量)
在程序运行期间根据需要进行动态分配存储空间
动态存储区: 函数形参 自动变量(auto)
局部变量可以是静态存储也可以是动态存储
形参的存储单元是动态分配的
动态变量的生存期是函数调用运行期间
在函数调用是分配存储空间,函数结束释放空间
未被赋值的,默认的初值为随机数
3.变量的存储类别
在C语言中每一个变量和函数都有两个属性数据类型和存储类型
完整的定义变量格式: 存储类别 数据类型 (变量名)
存储类别简称存储类
存储类种类(3种)
1.auto
生存期在函数调用期间
自动型(动态)
默认的存储类,可以省略不写
也可以说隐含存储类别是auto
2.static
静态型
static的用法(考试读程序写代码题)
函数调用后局部变量不消失,它所占用空间不释放, 下一次调用时该变量已经有值,就是上一次调用结束的那个值
这时候应该指定局部变量为“静态局部变量”,用关键字static进行声明
eg: static int s=2;
s作用域是在它所在函数内有效
注意
1.静态变量只在第一次调用函数时初始化
2.函数调用结束时静态变量不释放,其值要延续到下一次函数调用时使用
在一个C程序内部,若要定义一个只允许本源程序使用的局部变量,则该变量需要定义的存储类别为static型
如果要限定变量的作用域仅在当前稳文件有效,应使用关键字static
3.register
寄存器型
4.extern
外部型
第九章指针
指针就是地址,地址就是指针
相当于门牌号
1.定义指针变量
指针变量:指用于存放变量地址的变量
格式: 数据类型 * 指针变量名字 ;
* 号表示该变量是一个指针变量 int a; ——a是一个整型变量; int *a;——a是一个指针变量;
void * p——表示该指针变量是空
空指针
空指针定义后不能引用——即使用
int p=NULL
指针所占字节数
VC环境下指针占2个字节 TC环境下指针占4个字节
指针所占字节数与数据类型无关只与VC、TC有关
2.指针变量赋值
将变量的地址赋值给指针
用取地址运算符 &
优先级:正数第二, 结合性自右向左
作用:获取变量的地址
赋值格式: 1)int a, *p=&a; 2)int a, *p; p=&a;
注意是将&a赋值给p,不是赋值给*p
注意——易错 1.赋值是=左右两边数据类型要一致 int a; char *ch; ch= &a; ×
3.指针变量引用
访问变量的方式有两种
1.直接访问
2.间接访问
指针运算符/间接运算符/取内容运算符
*
优先级:正数第二, 结合性自右向左
作用:获取指针所指向的对象的内容
经典案例对照组:交换指针变量(P148页)
4.指针的指针(二级指针)
用于保存指针变量的地址
**p
5.指针与一维数组
本质是:内存中连续的存储单元
一维数组的名字代表它的首元素地址
数组的名字是一个指针常量,不能做运算,如a[3],a++——是非法语句
一维数组名字也是一个指针常量,a[2],a也是一个指针
如数组a 首元素地址a[0]
一维数组元素的表示方法
1.直接访问
数组:a[i]
是a[i]的地址
2.间接访问
数组:*[a+i]
&a[1]+2等价于a[3]
表示一维数组元素
指向一维数组元素的指针
见重点例题P150页例4
a+i代表a[i]的地址 或者 a+i——>a[i]
p=a+2————指向a[2]这个元素
p=a————指向首元素a[0]
对于单个变量,使用 & 来获取地址;对于数组,数组名本身就是一个指针,不需要使用 &。因此,不能将两者都写成 p = &a;
指针与指针之间可以相互赋值,不需要取地址运算符
注意在程旭中p=a+2代表p=a[2]
1.指针输出数组每一个元素
2.指针与“++”运算结合案例——P148页例五
*p++
与其他运算符混合使用,先取指针内容,再区分++在前在后
*p(++)
*++p
与其他运算符混合使用,先区分++在前在后,再取指针内容
*(++p)
++*p
与其他运算符混合使用,先取指针内容,再区分++在前在后
++(*p)
*p+=1
(*p)+=1=p[0]+1=p[0][1]————相当于p[1]
3.位置差
指向同一个数组的两个指针可以做差,叫做位置差
就是相差q-p个元素
设指针p,和q指向同一个一维数组
p==q——表示p和q在同一位置
p<q——表示p指向的位置在q前面
p>q——表示p指向的位置在q后面
1.指针输出一维数组的某个元素案例
2.指针实现一维数组的逆置案例
定义两指针,首指针和尾指针,条件p<q, 循环核心交换变量值的代码
6.指针二维数组
同样二维数组的名字代表它的首行地址
同样数组的名字是一个指针常量,不能做运算,如a[3][4],a++——是非法语句
a指向第0行而不是其中某个元素
也叫行指针
1.指针中二维数组元素的表示方法(3种)
二维数组名字也是一个指针,是指针常量,是行指针 a[2][3],a也是一个指针
①a[i][j]——行下标+列下标 ②*(*(a+i)+j) ③*(a[i]+j)
一维数组中说过a+i——就是a[i]
2.指针中二维数组元素地址的表示方法(3种)
①&a[i][j]代表a[i][j]的地址 ②a[i]+j代表a[i][j]的地址 a[i]+j————>a[i][j] ③*(a+i)+j代表a[i][j]的地址 *(a+i)+j————>a[i][j]
总结:
eg: 1)**a=*(*a[0]+0)=a[0][0] 2)*(*a+1)=*(*(a+0)+1)=a[0][1]
7.像访问一维数组那样访问二维数组
按行存储,上一行结尾和下一行头是连着的
8.指针数组
本质为数组
该数组的每一个元素都是指针变量
用于存储地址
格式: 数据类型 *数组名[常量表达式];
eg:int *b[5];
b是指针数组,该数组有5个元素,每一个元素都是int型的指针变量
int *p[5],a[5]; p=a ×——p是数组名不能参与运算; *p=a[0] ×——*p代表p[0] p=&a[0] ×这里p是数组名不能参与运算 p[0]=&a[0] √
9.数组指针
本质为指针
该指针指向一维数组
格式: 数据类型 (*指针名)[常量表达式];
小括号不要丢
eg:int (*b)[5];
b是数组指针,指向一个int型一维数组,该数组有5个元素
int *p[5],a[5]; p=a ×——p是数组名不能参与运算; *p=a[0] ×——*p代表p[0] p=&a[0] ×这里p是数组名不能参与运算 p[0]=&a[0] √
数组指针是指行指针
int z[2][3]; int (*p)[5]; p=a;
为什么可以相互赋值? 因为z是二维数组名,是指针,还是一个行指针, p是数组指针,本质是指针,也是一个行指针, 而指针变量之间可以相互赋值
10.地址传递重点
1.通过指针更改主函数变量值
实参传递的是地址,对应的形参是一个指针变量,负责接收这个地址
地址传递————可以改变主函数定义变量的值
地址传递要加&运算符
eg:fun(a,b,&c,&d) a,b 是值传递 c,d是地址传递
负责接收c,d的是指针p,q, 函数中p,q值改变,c,d值同步更改
t=*x,*x=*y,*y=t; t=x,x=y,y=t; 一定要注意有没有取内容运算符*, 没有交换的是地址,有交换的是内容
数组名作函数实参
绝对重点
数组名作函数实参,传递的是该数组的首地址
不需要+取地址运算符
eg: int d[5]; fun(d,5)
数组与函数挂钩,有两个基本形参,int a[ ],int n;
a[ ]——是指针 n——是数组元素个数
12.指针函数
一个函数可以返回整数值,字符值,实型值,结构体型等数据,也可以返回指针型数据
返回地址的函数叫做指针函数
地址就是指针
格式: 数据类型 * 函数名(参数列表){ ............................... }
13.地址指针
本质是指针
指向一个函数
格式: 数据类型 (* 函数名)(参数列表){ ............................... }
第十章字符串
字符串保存到系统内存中是以转义字符“\0”结尾的
字符串结束的标志:"\0"
\0占1个字节的存储空间
\0数值上相当于0
\0——转义字符——数值上相当于整型0 0———字符型——ASCII——数值上相当于48
给字符数组初始化
C语言中不可以整体赋值,但可以整体初始化
用字符对数组进行初始化
char c[4]={'A','B','C','D'}
加单引号''的是字符常量
下标是几就有几个元素
每一个字符串都有结束标志
用字符串对数组进行初始化
char c[6]={''ABCDE''}或者 char c[6]=''ABCDE''也是可以的即花括号可以省略
加双引号'' ''的是字符串
下标是n就有(n-1)个元素,剩下一个元素是转义字符\0
char c[6]; c=''ABCDE''
是整体赋值,是错误的
每一个字符串都有结束标志\0
这两种初始化实际上是一样的, 只不过一个有转义字符,一个没有
重点例题
char c[5]={'A','B','C','D'}问数组c保存的是字符串吗?
是字符串 C语言中未被初始化的数据默认为0, 整型数值0在数值上相当于转义字符\0 即:因为转义字符\0是字符串结束的标志,所以是字符串
char c[2][10]={''China'',"TianJin"}
1)求数据或数据类型所占字节数(包括结束标志:\0)——关键字sizeof
指向字符串的指针
char *p="abcd";
指针数组中,指针变量p指向的是字符串的首字母地址
注意字符串也是常量,也是无法更改的
eg:char *p="abcd"; *p+=1; 不合法,指针p取内容是字符串,abcd是字符串常量,常量是无法进行更改的
eg:char p[5]="abcd"; printf("%c",*p++); 不合法, 1)abcd是数组,数组里存取的是变量,变量是可以进行更改的——这是合法的 2)*p++等价于*(p++),P是数组名,数组名是常量,常量是无法进行更改的,不能进行运算——这一句是不合法的
eg:char *p="abcd"; printf("%c",*p++); 合法 p是指针变量,可以做运算,指针加1,指向下一个元素
eg:char p[]="abcd"; *p+=1; 合法, P是数组名,*p是取数组元素内容,对数组元素内容+1
*p++
*(p++)
遍历输出字符串
字符串格式控制符——%s——可以整个输出字符串 遍历输出是指一个一个输出字符,不能用%s,用%c可以单个输出字符
1.循环输出字符串条件 s[i]!='\0'
固定模版
2.指针遍历字符串
也用到了循环,固定模版
字符串的逆置
使用指针实现
用到了两个指针的位置差 交换变量值核心代码
字符串函数
所在头文件<string.h>
1)字符串长度函数strlen
注意,求字符串昌都不包括最后的\0
求所占字节数和元素个数包括\0
遇到字符串中间的\0时就结束统计
只考虑实际的
遇到\xxx(八进制),\x11(十六进制)长度为1,不用转换成十进制看有几个数字
字符串长度不等于数组长度
数组长度=数组中下标
2)字符串复制函数strcpy
格式: strcpr(s,c)
将字符串c复制到字符串S中
本质:将将字符串c的每一个字符复制到字符串S中,包括\0
可以指定复制起点
eg: 1)strcpr(s+2,c) 2)strcpr(s+2,c+3)
3)字符串连接函数stract
格式: stract(s,c)
将字符串s和c连接到一起
4)字符串比较函数strcmp
有返回值
格式: strcmp(s,c)
比较字符串S和C的大小
字符串S 等于字符串C
函数返回值为0
字符串S 大于 字符串C
函数返回值为正数
字符串S 小于 字符串C
函数返回值为负数
比较方法
逐个字符比较,比较ASCII码大小
只有有一个分出大小即可,剩下字符无需比较
一般用来判断两个字符串是否相等
比较字符串不能用关系连接符
“ABC”==“ABC”是非法语句
第十一章编译预处理
预处理指在编译之前处理
C语言的预处理功能(3种)
1>宏定义
2>文件包含
3>条件编译
预处理命令以#开头
每行只能写一条预处理命令
预处理命令不是C语句,结尾不需要加分号
1)宏定义
宏定义包括
①不带参数的宏
②带参数的宏
使用宏的好处
实现只要改一个就可以全改
①不带参数的宏
格式 #define 宏名 替换文本
eg; #define N 10————预处理命令 int a[N];——————C语句,结尾加分号
预处理命令不是C语句,结尾不需要加分号
等价于int a[10]
在编译之前,将用替换文本替换掉宏名
宏替换是在编译前进行的,不是在程序运行中
注意·!!!
1.宏名一般采用大写,没有规定必须大写
2.宏 替换 只做替换,不做计算,不做表示式求解
eg; #define N 2+5———— 2+5是替换文本,不能计算
3.宏定义可以嵌套——即宏嵌套
可以使用 #undef终止宏的作用域
5.不要随意给替换文本加括号
替换文本本身有括号就加,没有不加
eg; 1. #define N 2+5————没有括号 计算N*N 2+5*2+5=2+10+5=17 2. #define N (2+5)————有括号 计算N*N (2+5)*(2+5)=7*7=49
一定要先替换,后计算
宏嵌套
eg; #define N 3+1 #define M N+1
注意,不能计算
!!!!
先替换 3+1=N N+1=3+1+1=M=5
②带参数的宏
格式 #define 宏名(参数列表) 替换文本
eg; #define F(a) a*a 表达式F(2)+F(5)的值·为 先替换后计算 替换:F(2)=a*a ,参数a=2,所以2*2
预处理命令不是C语句,结尾不需要加分号
2eg: MAX(x) x*(x-1) a=1,b=2 MAX(1+a+b);
x=1+a+b 1+a+b*(1+a+b-1)
3eg: MAX(x,y,z) x+y+z a=1,b=2,c=3 MAX(a+b,b+c,c+a);
x=a+b y=b+c c=a+c a+b*b+c*a+c
2)文件包含
指一个文件包含另一个文件的内容
格式 #include <文件名>或者#include "文件名"
这两种都可以但是有区别
#include <文件名>
指仅仅在头文件目录中查找文件
在系统目录中查找文件
#include "文件名"
指先在当前文件目录下查找,再在头文件目录中查找文件
先在用户目录下查找,再系统目录中查找文件
常见库函数及其头文件
3>条件编译
有3种基本形式
了解即可
第十二章结构体
关键字typedef
作用:给现有数据类型取别名
整型,实型,浮点型,结构体型
不是定义新的数据类型
格式 dypedef 数据类型 别名;
分号不要丢
eg: typedef int IN; IN a; IN a;等价于int a;
eg: typedef char * IN;——char * 是字符指针,给char * 取别名 IN a; IN a;等价于int a;
结构体是由 一批 数据类型相同或不同的 数据 组合而成的 结构类型
这一批数据成为结构体的成员
结构体类型不是有系统设定的,是由程序设计者自己按需求定义的
结构体也是一种数据类型,类似整型,实型,浮点型,即结构体型,简称结构体
结构体类型说明
即说明 结构体类型
格式 struct 标识符——就是名字{ 成员列表 };
花括号,分号不要丢
每一个成员都要有自己的数据类型
标识符可以省略
eg: struct dat{ int year; char hour; };
结构体类型说明不占用内存
结构体变量
结构体变量占用内存
定义结构体变量
子主题
先说明 结构体类型,在定义结构体变量
定义结构体变量
struct 结构体说明标识符 变量名
这两个是整体
结构体说明放在头文件下面,主函数上面,结构体定义放在主函数里面
可以以简略定义,简略定义可以都放在放在头文件下面,主函数上面
同样可以对结构体取别名
取别名格式 dypedef 数据类型 别名;
分号不要丢
也可以用结构体别名定义结构体变量
只需添加语句: GXF guofang,*p;即可
结构体变量所占字节数=各个成员所占字节数之和
成员类型
int型——VC环境下,占4个字节 TC环境下,占2个字节 short型——占2个字节 float型——占4个字节 double型——占8个字节 char型——一个字符占1个字节
char a;————占1个字节 char a[20];————一个字符占一个字节,数组指明实际长度20, 所占字节数 sizeof=1*20=20
指针型——VC环境下指针占4个字节 TC环境下指针占2个字节
指针所占字节数与数据类型无关只与VC、TC有关
计算数组所占字节数要看是否指明数组长度
指明长度
int a【5】={1,2,3} 实际: 数组实际长度5 所占字节数:sizeof=5*2=10
未指明长度
int a【 】={1,2,3} 实际: 数组实际长度3 所占字节数:sizeof=3*2=6
结构体变量为
单个变量
VC环境下eg:guofang
单个变量guofang所占字节sizeof=4+4=8
数组变量
字节数=数组长度*结构体变量所占字节数
结构体数组变量x所占字节数sizeof=(4+4)*5=40
结构体初始化
按顺序对成员初始化
结构体变量为数组时
有n个成员,数组里每一个元素都有n个成员
有2个成员,每一个元素都有2个成员,初始化了3个元素·
注意!所有成员用逗号隔开,21,160.0;是错误的
结构体成员的引用
格式 1)结构体变量名 . 成员名 2)(*结构体指针名). 成员名 3)结构体指针名 —>成员名
成员运算符 .
指向运算符—>
结构体所独有的
eg:
指针
成员中有数组时,可以采用strcpy函数赋值, 但不可以对数组进行整体赋值,可以整体初始化
不可以FF.x="FF",这是对数组整体赋值 int x[5]={"FF"}这是对数组整体初始化
第十四章文件
程序与数据的交互是以 流 的形式进行的
C语言的文件处理功能 依据 系统是否设置 “缓冲区”分为两种
1.设置缓冲区
使用标准 I/O函数时,系统会自动设置缓冲区
I/O函数包含在头文件stdio.h中
2.不设置缓冲区
文件分类
1.文本文件
文本文件是以字符编码的方式进行保存
2.二进制文件
文件使用顺序
打开文件,读写文件,最后关闭文件
C语言文件操作
先定义文件指针,再打开文件,最后关闭文件
文件指针 : FILE * 文件名;
函数
打开文件函数fopen
头文件#include <stdio.h>
格式 FILE * 文件名; ————定义文件指针 文件名=fopen(文件名(含路径),使用方式);
文件使用方式
文件三大主体
1.只读“r”
使用前提:文件必须存在
为输入打开一个文件
2.只写"w"
为输出打开一个文件
文件不存在时,相当于新建文件
文件存在且有内容时,新内容会覆盖原有内容
3.追加"a"
向文本文件尾添加数据
不会覆盖原有内容,在尾部补充
读写“r+”
类似改写
会部分覆盖
原有GOOD 输入ABC 最后文件:ABCD
为读写打开一个文件
读写“w+”
为读写打开一个x新建文件
读写“a+”
向文本文件尾添加数据(可读可写)
二进制文件三大主体
1.只读“rb”
2.只写"wb"
3.追加"ab"
读写“rb+”
为读写打开一个文件
读写“wb+”
为读写打开一个x新建文件
读写“ab+”
向文本文件尾添加数据(可读可写)
eg: FILE * gf; gf=fopen("D:\GF\Downloads\《C语言》周测","r");
路径是反斜杠,还加双引号
MAC系统是正斜杠/ windows系统两个反斜杠等于一个正斜杠
文件打开失败,函数返回NULL
打开失败原因
1.文件被损坏
2.找不到文件
关闭文件函数fclose
格式: fclose(文件指针);
分号不要丢
eg: FILE * gf; gf=fopen("D:\\GF\\Downloads\\《C语言》周测","r"); ——打开文件 ………… fclose(gf);——关闭文件
文件函数
一个字符
fputc
将一个字符写到文件中
格式: fputc(字符,文件指针);
c是字符的意思
字符常量要加单引号
eg: fputc('A',gf);
字符常量要加单引号
fgetc
从文件中读取一个字符
格式: 字符变量=fgetc(字符,文件指针);
字符常量要加单引号
可以实现从文件中连续读取字符
核心代码
EOF为文件结束符,其值为-1;
ch!=EOF可以替换成!feof(gf)
feof
是C语言库函数,头文件#include <stdio.h>
功能:是检测流上的文件结束符
文件结束,返回非0值 文件未结束——或者发生错误,返回0
字符串
fputs
向文件中写入一个字符串
格式: fputs(字符串,文件指针);
s是字符的意思
字符串要加双引号, 如果是数组就不用加,只写数组名即可
eg; FILE * gf; char s[50]; gf=fopen("D:\\GF\\Downloads\\《C语言》周测","w"); ——打开文件 scanf("%s",s); fputs(s,gf); fclose(gf);——关闭文件
fgets
从文件中读取一个字符串
格式: fgets(字符数组,n , 文件指针);
n是字符串字符个数,包括\0
其他函数
格式化输出函数fprintf
输出内容写入文件中
格式: fprintf(文件指针,格式化字符串,输出列表);
用法同printf
字符串要加双引号, 如果是数组就不用加,只写数组名即可
格式化输出函数fscanf
从文件中获取
格式: fscanf(文件指针,格式化字符串,输出列表);
用法同scanf
函数rewind
作用:使位置指针重新回到开头
相当于于回到顶部
rewind(文件指针)
浮动主题
编写程序注意事项 1)连续定义多个变量,变量之间用逗号隔开 2)c语句后加分号 3)初始化不能连等(int a=b=2),赋值可以连等(a=b=2 ) 4)涉及到数学公式一定要注意运算符和优先级结合性,还要结合实际情况 eg:C=5/9(F-32)改写成C语言公式:C=5.0/9*(F-32) 5)数学中5!表示计算阶乘,5!=5*4*3*2*1——可以用循环计算阶乘 6)一元二次方程的根与判别式 △ 有关 ,△=b²-4ac(数学写法)
7)注意循环结构中是否有每次循环都要初始化的值
格式控制符 %d 代表十进制整型——P7 %1d 代表long整型 %o(英文字母欧) 代表八进制整型 %x或%X 代表十六进制整型 %u 代表无符号数 %f 代表float型 %lf 代表double型 %c 代表字符原型
指针是循环、数组、函数、变量的综合