作者:hyb;单位:中北大学卓创实验室电控组
分类:
一、数据类型、运算符、表达式
二、语句
三、循环
四、分支与跳转
五、变量与函数
六、指针
7、编译预处理指令
一、数据类型:
int/long int/unsigned int/unsignd long int:4Byte
short int:2Byte
char/unsigned char:1Byte
float:4Byte
double:8Byte
注:在VC++系统中:现在基本整型int和无符号基本整型unsigned int都已经改成了4Byte!,而VC++不使用short int,所以所有整型数据都是4个字节
注:VC++系统中还有无符号字符型:
unsigned char(1Byte)
这里附上ASCII码表、优先级表和运算符表:
表达式=运算符+数据+其他
运算符具体的用法限于篇幅这里就不展开了
这是我自己整理的,可能有错误,大家理解哈
二、语句
1、if语句
if()语句(选择结构化程序的一种),它可以看作是N-S流程图中的选择结构,()内为任意确定的值/关系表达式/逻辑表达式/关系逻辑混合表达式,最终输出逻辑量1或0
若为1,则执行if内{},若为0则要么不执行,要么执行else内{}
‼️
if语句中:
可以不加{}但只能接一个语句
如果要接多个语句,那么必须加{}
注意⚠️
else不能跟(),else()是错的‼️
但是else if()是对的,进行二次选择语句‼️可以一直嵌套下去‼️
if()语句实际应用:
1、判断是否能构成三角形
2、求两数最大值
3、将两个数从大到小排列
2、if语句嵌套
if语句的两种高端玩法:
1、if语句中嵌套n次if语句
2、二次if选择……n次if选择
(即if……else if……elseif……else)
if语句本质:选择+判断
if语句使用时最好加号括号
(以免出错‼️)
if语句可以嵌套在if的{}语句内
if也可以嵌套在else{}语句内
else匹配原则:‼️
3、stitch语句 :
1、switch是依次往后匹配‼️
直到default截止‼️
2、case和常量表达式之间有一个空格
3、switch()里面可以是表达式或变量,但必须是整型或字符型
4、每一个case结尾要加上break;
5、如果没有break,从一个位置开始会一直向后执行,直到遇见break;或者全部执行完
6、default顺序任意
7、swtich也可以嵌套
8、switch语句可以没有default
9、break语句只能用于循环和switch语句,但不是一定需要的
三、循环:
1、while循环:
当型循环for语句、while语句类似于N-S流程图
while语句括号的最终目的是输出逻辑量来进行判断:
1(逻辑真)则执行循环体语句
0(逻辑假)则跳出循环
如果没有给循环变量赋初值,那么系统会随机给它赋一个值
for循环括号内必须包括变量赋初值、条件、变化3个东西。
但while循环括号内可以只有一个东西,因为目的就是为了输出逻辑量,然后初值可以放外面,变化也可以放{}内
i++;和i=i+1;和i+=1;一样的变化
改成不同的人数(优化程序):
选用2或3
常量三种表示方法:1、直接用2、宏定义3、定义变量后赋值
while循环进去了除非输出0或者强行break;不然一直在循环内
2、do-while循环
3、for循环
四、break语句和continue语句 :
五、变量与函数:
一、变量三要素:
1、属性:存储属性和操作属性
2、作用域:局部变量和全局变量
3、生存期:动态/静态存储变量
变量的分类:
1、auto型的局部变量如果是定义在被调函数中的且不是指针变量,那么在被调函数执行完后就会被释放掉‼️
2、形式参数本质上是动态局部变量,如果它不是非指针类型变量,那么执行完被调函数后形式参数也会被释放,而主调函数参数不会改变‼️
3、不同函数中允许定义同名变量,但占不同的内存单元‼️
4、复合语句中也允许定义局部变量,但只在复合语句中生效‼️
5、全局变量和局部变量同名时,局部变量优先‼️(指的是在局部变量所在函数内从定义局部变量开始往下到该函数结束局部变量优先)
6、局部变量只在该函数内从定义开始到结束为止生效,全局变量从定义位置开始到整个程序结束都生效
7、只有局部自动变量和形式参数才可以定义为寄存器变量。因为寄存器变量属于动态存储方式。凡需要采用静态存储方式的量不能定义为寄存器变量。
四种存储类别‼️:
auto(自动):
1、是局部变量默认的存储类别,通常省略,存储在动态存储区中
2、调用被调函数时,系统给局部变量自动分配存储空间,函数调用结束时局部变量被释放
register(寄存器):‼️
1、使用频繁的数据定义成寄存器存储变量
2、存储在寄存器中,存取速度快,效率高,且不属于动态存储区和静态存储区(即时即用,快速高效)
extern(外部):‼️
1、在源程序文件中拓展全局变量的作用域
2、在多文件程序中拓展全局变量的作用范围
static(静态):232
目的:‼️
1、一般是用于被调函数的局部变量,为了不让这个变量在被调函数执行完后被释放掉,从而定义成静态局部变量,可以保留下来
2、也可以用于全局变量前,变成静态全局变量,使得这个全局变量只能在这个源文件中使用,不能在其他文件中使用了,否则编译会报错
使用:
1、存储在静态存储区,在整个程序运行期间都不释放内存空间
2、分配存储空间时赋初值,仅赋一次。若未赋值自动赋0
3、存在但仅限于本函数
缺点:(最好不好多用)
1、存储效率:静态局部变量长期占用静态存储区
2、降低程序的可读性:当调用次数多时往往弄不清静态局部变量的当前值是什么
形式参数:是动态局部变量,调用结束后会被释放(除非是指针类型)
二、被调函数五要素:
1、定义2、参数3、返回值(类型)4、声明5、调用
3、返回值3种方案:
return 表达式;
return (表达式);
return;用于void无返回值的类型
4、声明:
库函数声明:全局
自定义函数声明:局部声明/全局声明方法:类型+名称(…);
两种情况可以不声明函数:‼️
1被调函数定义在主调函数前
2被调函数返回值为int或char型
5、调用:
分类:普通/嵌套/递归调用
函数调用有三种方式:‼️
无返回值:直接调用语句
意义:节约空间、简洁、清晰
有返回值:作为表达式分量、作为另一个被调函数的实际参数
意义:得到返回值
无实际参数或有实际参数(常量、变量、表达式、另一个函数调用的返回值)‼️
实际参数执行顺序:从右向左‼️
区分:(++c,c)和(c,++c)
函数调用的执行机制:
移交主动权、单向参数传递、一一对应
参数转移:将实参的值赋值给形参
难点:1、如果参数不是指针类型时,函数调用不改变实参的值,此时交换函数无法实现。2、然而变量起作用范围只限于本函数(局部变量),如果是全局变量就没这个问题
‼️所以在被调用完后形式参数会被释放掉,实际参数值不变。
总结:当形参和实参不是指针类型时,在该函数运行时,形参和实参是不同的变量,他们在内存中位于不同的位置,形参将实参的内容复制一份,实参是一个值,修改的是形参的地址。在该函数运行结束的时候形参被释放,而实参内容不会改变。
交换变量怎么办:
1、删掉被调函数,直接把内容放在主函数里不就好了
2、去掉被调函数的参数,变成无返回值无参数的函数,就起到打包的作用。把需要交换的两个变量定义成全局变量,把a、b换成x、y即可
3、利用指针
注意事项:
1、定义或调用函数时()不能省略
2、不加类型说明的函数自动按整形处理‼️
3、类型转换:当函数类型和return语句中的值的类型不一样时,以函数类型为准‼️
4、无值函数可以加return;或者省略return语句‼️
5、声明有参数的函数时括号内只需要类型就可以了,不一定需要形式参数的名称‼️
例如:
6、全局声明作用范围:从声明位置开始,到程序结束为止。外部声明最好放在程序开始的地方。‼️
7、一般被调函数有返回值就有参数,无返回值就无参数。一有一无的很少。例如:被调printf()函数:无返回值,有参数,意义就是输出。‼️
8、主函数也叫做主调函数,主函数可以在一个C程序的前、中、后任意位置,但只有一个main函数,且程序从main()开始,由主函数结束
9、当形参和实参不是指针类型时,在该函数运行时,形参和实参是不同的变量,他们在内存中位于不同的位置,形参将实参的内容复制一份,在该函数运行结束的时候形参被释放,而实参内容不会改变。而如果函数的参数是指针类型变量,在调用该函数的过程中,传给函数的是实参的地址,在函数体内部使用的也是实参的地址,即使用的就是实参本身。所以在函数体内部可以改变实参的值。
六、指针大总结:
指针变量的用处:‼️
1、间接访问来使用其他变量
用处:
函数实参和形参间转换
其他地方间接访问使用变量
实例:局部变量无法实现交换函数(当然全局可以),通过指针间接访问其他变量
2、间接访问来调用其他函数
用处:
函数实参和形参间转换
其他地方间接访问调用函数
根据三步走原则学习
分类:
1、函数指针变量
2、指向函数的函数指针变量
(或指向函数的指针变量)
3、指向变量的指针变量
4、返回值为指针变量的函数
区分:
函数的指针=函数名=起始地址=首地址
变量的指针=变量的地址
基础回顾:
单位转换‼️
1KB=1024B,1Kb=1024b,1B=8b
(T、G、M、K、B/b)
先复习数制和位、字节知识
位bit:二进制的0或1,组成内存的最小单位
字节Byte:连续的8位二进制数,作为数据存储的最小单元
字:连续的两个字节
双字:连续的两个字
四字:连续的两个双字
特别注意:8/16进制转化为2进制,每1个数换算成3/4位二进制数
内存=存储单元之和
一、存储区介绍:
1、存储区对应一个地址(编号),这个地址是16进制表示的整数
‼️但具体多少位看有几个数字,每个数字兑换为4位二进制。例如寄存器是8个数字,就是32位二进制
2、每个存储区里面包含1个或多个存储单元,每个存储单元是连续的8位二进制(1个字节)
二、为什么要存:
3、定义变量在编译后会给它找一个存储区去存放,给变量赋值就是将数据存储在内存单元中
三、怎么存:
4、数据占存储单元的个数是由其类型决定的,例如字符型占1个字节,那就占一个存储单元
5、数据存储一般都是以二进制补码的形式存储的
6、存储从低地址开始,之后逐渐升高(相对高低)如图:
IMG_9126.heic
四、注意事项:
7、注意区分内存储器和寄存器‼️:
内存储器编号4个数字
内存储器地址叫内存地址(编号)
寄存器编号8个数字
寄存器地址叫寄存器地址(编号)
8、这里默认基本整形变量占2字节
五、直接访问和利用指针间接访问变量:
六、指向变量的指针变量总结
注:也要存储在内存中‼️
指针:指针就是地址,只是更形象,可以指向一个地方
指针变量(通常也称为指针):
三个方面:
1、它的值用于存放另一个变量的地址(指针),其值为&变量
2、它指向了另一个变量
3、指针变量要赋值,指针变量可以直接初始化,也可以先定义后赋值,但不要加*符号。
如果是其他变量(非指针变量):
1、必须用&变量给指针赋值
2、且变量类型要与其基类型一致
3、赋值完后就指向了变量,并存好了值=地址
如果是指针变量相互赋值:
1、右边的不用加&
2、基类型要相同‼️
3、这个指针变量必须先指向一个其他变量
4、赋值完后指向(另一个指针所指向的变量),并存好了值=地址
4、零指针 指向NULL‼️
例:int *p=NULL;
七、&和*运算符:
&(取址运算符):
优先级2,右结合,单目
即可作用于一般变量,也可作用于指针变量(求指针变量的编号/地址)
*(间接访问运算符):
优先级2,右结合,单目
只作用于指针变量
*指针:间接访问指针变量所指向的变量(存内容/取内容)
‼ (必须要先给指针变量赋值)
(这和定义指针变量时的*含义不同,不要混淆)
八、利用指针来间接访问使用变量:
三步走:
1、定义变量和指针变量
(可以一起定义)
2、建立指向关系图并给指针变量赋值
3、利用指针间接访问使用所指变量
存:可以先不赋值;取:必须先赋值
实际参数有两种形式,就是对用了给指针变量赋值的对象的两个形式(其他变量地址/另一个指针)
7.4指向函数的指针和返回指针值的函数
实参和行参的转换可以有三种:值传递、地址传递、函数传递
地址传递和函数传递本质上都是用的指针
1、函数为存放在内存中的程序代码
2、函数所占内存的首地址=入口地址=函数的指针=函数名‼️
3、函数声明的作用就是明确被调函数执行时的入口地址
右边括号内若没有东西,说明这个指针变量指向没有参数的函数‼️
区分开函数指针变量和指向函数的指针变量
函数指针变量3方面:
1、里面存的值就是函数名=首地址=入口地址
2、用来指向函数
3、给函数指针变量赋值,可以直接初始化,也可以先定义后初始化(不要加括号和*,直接p形式)
第一种:用函数名给函数指针变量赋值
1、返回值类型和参数类型要一致,2、让指针指向函数,并存好指针的值=函数名=入口地址=首地址
第二种:用指向函数的指针变量给函数指针变量赋值
1、返回值类型和参数类型要一致
2、右边不要加括号和*,直接p形式
3、让指针指向另一个指针所指向的函数,并存好指针的值=函数名=入口地址=首地址
三步走:
1、定义好函数和函数指针变量
(可以一起定义)
2、构建指向关系图并给指针赋值
3、用间接访问来调用所指函数
七、编译预处理指令: