C - Language | Syntax


#运算符

  1. 赋值运算符
  2. 算术运算符
  3. 自增减运算符
  4. 关系运算符
  5. 逻辑运算符
  6. 顺序求值运算符
  7. 位逻辑运算符
  8. 复合赋值运算符
  9. 条件运算符
  10. 地址运算符
  11. 指针运算符
=					赋值运算符
+					正值运算符
-					负值运算符
*					乘法运算符
/					除法运算符
%					取模运算符
+					加法运算符
-					减法运算符
++					自增运算符
--					自减运算符
==					等于关系运算符
>					大于关系运算符
>=					大于等于关系运算符
<					小于关系运算符
<=					小于等于关系运算符
!=					不等于关系运算符
!					逻辑非运算符/逻辑取反关系运算符(单目)
&&					逻辑与运算符
||					逻辑或运算符
,					顺序求值运算符
&					位逻辑与运算符
|					位逻辑或运算符
^					位逻辑异或运算符
~					位逻辑取反运算符(单目)
[+-8/&^|<<>>]=		 复合赋值运算符
? :					条件运算符(三目)
&					地址运算符(单目)
*					指针运算符(单目)

C语言中有2个" 单目运算符 "、5个" 双目运算符 "、1个" 三目运算符 "," 单目运算符 "需要一个操作数(运算对象)进行运算," 双目运算符 "需要两个操作数(运算对象)进行运算(运算符左右各有一操作数(运算对象),左值和右值)," 三目运算符 "需要三个操作数(运算对象)进行运算

赋值运算符

赋值运算符的作用就是将一个数据赋给一个变量,属于" 双目运算符 "

由赋值运算符将一个变量和一个表达式连接起来构成的式子为" 赋值表达式 "

赋值表达式也可以将一个常量赋值给一个变量

a(左值)=9(右值);

在赋值表达式中,赋值运算符的左边是" 左值 ",右边是" 右值 ",不是所有的表达式都可以作为左值

//常量只可以作为右值

声明变量时,直接为其赋值,称为变量赋初值(变量初始化)

算术运算符

算术运算符包括:2个" 单目运算符 "(" 正值运算符 "、" 负值运算符 "),5个" 双目运算符 "(" 乘法 "、" 除法 "、" 取模 "、" 加法 "、" 减法 ")

+			正值运算符					单目正
-			负值运算符					单目负
*			乘法运算符					乘法					左结合性
/			除法运算符					除法					左结合性
%			取模运算符(求余运算符)		取模(求余)			 左结合性
+			加法运算符					加法					右结合性
-			减法运算符					减法					右结合性

//" + "、" - "运算符,单目时代表正负,双目时代表加减

自增减运算符

自增运算符" ++ "对变量/常量进行自增1操作,自减运算符" -- "对变量/常量进行自减1操作

++					自增运算符
--					自减运算符

关系运算符

关系运算也可称为比较运算,是逻辑运算的一种

关系运算符有6种,包括:大于运算符" > "、大于等于运算符" >= "、小于运算符" < "、小于等于运算符" <= "、等于运算符" == "、不等于运算符" != "

>					大于
>=					大于等于
<					小于
<=					小于等于
==					等于
!=					不等于

逻辑运算符

逻辑运算符根据表达式的真与假的属性,来返回真值或假值

//C语言中,如果表达式的值非零,那么其值为真

逻辑运算符有3种,包括逻辑与" && "、逻辑或" || "、单目逻辑非" ! "

&&					逻辑与(双目)
||					逻辑或(双目)
!					逻辑非(单目 | 取反)

顺序求值运算符

顺序求值运算符又称" 逗号运算符 ",负责将顺序求值运算符两侧的表达式连接起来

通常可以用顺序求值运算符(逗号" , ")将多个表达式分隔开,被分隔的表达式会被分别计算,最后所有表达式的值,则是单独最后一个表达式的值

a,b,c,d,e;					/*最终值是e*/

位逻辑运算符

位逻辑运算符能实现位的" 设置 "、" 清零 "、" 取反 "和" 取补 "操作(利用位运算可以实现许多汇编语言才能实现的功能)

位逻辑运算符包括双目运算符" 位逻辑与 "、" 位逻辑或 "、" 位逻辑异或 ",以及单目运算符" 位逻辑取反 "

位逻辑运算符只能用于整型表达式

&					位逻辑与					/*双目转换成二进制后,按位进行位逻辑与运算,两者皆为真值(1)时,则结果为真*/
|					位逻辑或					/*双目转换成二进制后,按位进行位逻辑或运算,两者只要有一位为真值(1)时,则结果为真*/
^					位逻辑异或					/*双目转换成二进制后,按位进行位逻辑异或运算,两者值不同时,则结果为真(1)*/
~					位逻辑取反(单目)			/*双目转换成二进制后,按位进行位逻辑取反运算,每位上,若真(1)则假(0),若假(0)责真(1)*/
清零用位逻辑与运算符
取反用位逻辑异或运算符
两值交换用异或(第三值为公钥)

复合赋值运算符

复合赋值运算符可以使代码更简洁

value=value+3;
value+=3;					/*通过复合赋值运算符,可以将" value=value+3; "的代表精简成" value+=3; "*/

条件运算符

条件运算符" ? : "是C语言中唯一的三目运算符(由左向右结合)

条件表达式?若条件结果为真所需运行表达式:若条件结果为假所需运行表达式
result=(a<b)?1:0;

地址运算符

" & "地址运算符用来取变量的" 地址 "

" 地址运算符 "为" 单目运算符 "

" 地址运算符 "又称" 取址运算符 "

&变量标识符;
&a;

" 取址运算符 "返回操作数的" 地址 "

指针运算符

" * "为" 指针运算符 "(单目运算符)

" * "指针运算符用来返回指定" 地址 "内的变量的值(又被称为取值运算符)

调用" 指针运算符 ",属于" 间接访问 "

*变量标识符(指针变量);
*a;					/*取出" a "地址中的变量值*/
int *p1,*p2,a;
int b[5];
b[4]=5;
p1=&a;
p2=b;					/*也可以写成" p2=&b[0] "*/
printf("%d\n%d\n%d",*p1,*p2,*(p2+4));

表达式

表达式由" 操作符 "和" 操作数组 "构成

表达式是由常量、变量、函数、运算符和括号组合在一起,并且符合C语言语法规则的式子

int a,b,c;					/*属于表达式*/

逗号" , "既可以作为分隔符又可以用在表达式中,逗号" , "可以将多个独立的表达式连结在一起

for(i=0,j=100;i<j;i++,j--)					/*使用逗号将表达式进行分隔*/

表达式本身只返回结果值不进行任何操作,如果对结果值不进行操作,则返回值不起任何作用(忽略返回值)

表达式在两种情况下会产生作用," 在赋值语句右侧 "、" 处在函数的参数中 "

每个表达式,都有一个值,与之相对应的数据类型,表达式隐含的数据类型,取决于组成表达式的变量和常量的类型,是表达式经过计算后所得到结果的值和类型

表达式求值按运算符的" 优先级 "和" 结合性 "规定的先后顺序进行计算

赋值表达式

由" 赋值运算符 "将一个变量和一个表达式连接起来构成的式子为" 赋值表达式 "

c=a+b+9;					/*赋值表达式*/

在赋值表达式中,赋值运算符的左边是" 左值 ",右边是" 右值 ",不是所有的表达式都可以作为左值

//常量只可以作为右值

算术表达式

算术表达式,是在表达式中使用算术运算符的表达式

//两个整数相除,结果会把小数部分舍去

Num=(3+5)/Rate;
Hei=Top-Botto+1;
Area=Hei * Wid;

自增减表达式

自增减运算符可以放在变量/常量的前面或后面,在前面的为前缀,在后面的为后缀。前缀与后缀对变量/常量的处理顺序不同

++i					/*先自增1,然后再使用i*/
--i					/*先自减1,然后再使用i*/
i++					/*先使用i,然后再自增1*/
i--					/*先使用i,然后再自减1*/

关系表达式

关系运算符是对两个表达式的值进行比较,返回的结果是 "真值 "或者" 假值 "," 真值 "为1(非零值)," 假值 "为0

//" 非零值 "等同于" 真值 "

0==0;			/*返回真值1*/
0>1;			/*返回假值0*/
0<2;			/*返回真值1*/

//关系表达式主要用来构造" 条件表达式 "

逻辑表达式

使用逻辑运算符可以将多个关系表达式的结果合并在一起进行判断(逻辑表达式)

表达式 逻辑运算符 表达式
c=a&&b;					/*a与b都为真时,结果为真*/
c=a||b;					/*a或者b有一个是真时,结果为真*/
a=!b;					/*取反,b为真时,a为假;b为假时,a为真*/
a=!!value

//逻辑表达式采用的是" 短路求值 "的方式,即当" a&&b "时,只有" a "为真时,才会去进一步判断" b "是否为真;当" a||b "时,如果" a "不为真时,才会去进一步判断" b "

顺序求值表达式

在使用时,根据所有运算符不同,运算顺序也不同,可以通过被括号包裹,提高优先级

value=1+2,2+3,3+4;					/*" value "的最终值是3,因为赋值运算符优先级大于顺序求值运算符*/
value=(1+2,2+3,3+4);					/*" value "的最终值是7*/

位逻辑表达式

位逻辑一般被用来作为开关标志,较低层次的硬件设备驱动程序,需要对输入、输出设备进行位操作

11001100 & 10101010;					/*将" 11001100 "的1、3、5、7位设置为" 1 "*/
10011011 ^ 10101010;					/*使用位逻辑异或运算符将" 10011011 "的1、3、5、7位进行取反*/

复合赋值运算符表达式

复合赋值运算符相较于赋值运算符的区别在于,代码简洁,编译效率高

num=num+3;					/*使用赋值运算符和算术运算符共同组成的表达式,将会使" num "变量计算2次(被调用两次)*/
num+=3;					/*使用复合赋值运算符的表达式,只计算1次" num "变量(被调用1次),精简了代码,提高了编译效率*/

条件运算符表达式

if(a>b){max=a;}else{max=b;}
max=(a>b)?a:b;					/*可以用条件运算符将" if(a>b){max=a;}else{max=b;} "简化为" max=(a>b)?a:b "*/

语句

当一条语句或数据声明结束后,尾部必须以分号" ; "结束,语法的一部分,不可缺少(并非所有语句结尾都加分号" ; ")

语句的执行顺序由运算符的优先级和表达式的结合性共同决定

运算符 解释 结合性方向 操作数(运算对象个数) 优先级
() 圆括号(函数等) 自左向右 描述符 1
[] 数组、下标 自左向右 描述符 1
-> 指向结构体成员 自左向右 描述符 1
. 结构成员访问 自左向右 描述符 1
! 逻辑非运算符(逻辑取反) 自右向左 单目 2
~ 位逻辑取反运算符(按位取反) 自右向左 单目 2
++ 自增运算符 自右向左 单目 2
-- 自减运算符 自右向左 单目 2
+ 正号 自右向左 单目 2
- 负号 自右向左 单目 2
***** 指针运算符 自右向左 单目 2
& 地址运算符 自右向左 单目 2
(类型) 类型转换 自右向左 单目 2
Sizeof 求大小 自右向左 单目 2
* 算术乘运算符 自左向右 双目 3
/ 算术除运算符 自左向右 双目 3
% 算术模运算符 自左向右 双目 3
+ 算术加运算符 自左向右 双目 4
- 算术减运算符 自左向右 双目 4
>> 左移 自左向右 双目 5
<< 右移 自左向右 双目 5
> 关系大于运算符 自左向右 双目 6
>= 关系大于等于运算符 自左向右 双目 6
< 关系小于运算符 自左向右 双目 6
<= 关系小于等于运算符 自左向右 双目 6
== 关系等于运算符 自左向右 双目 7
!= 关系不等于运算符 自左向右 双目 7
& 位逻辑与运算符 自左向右 双目 8
^ 位逻辑异或运算符 自左向右 双目 9
| 位逻辑或运算符 自左向右 双目 10
&& 逻辑与运算符 自左向右 双目 11
|| 逻辑或运算符 自左向右 双目 12
? : 条件运算符 自右向左 三目 13
= 赋值运算符 自右向左 双目 14
+= 复合赋值加赋值运算符 自右向左 双目 14
-= 复合赋值减赋值运算符 自右向左 双目 14
*= 复合赋值乘赋值运算符 自右向左 双目 14
/= 复合赋值除运算符 自右向左 双目 14
&= 复合赋值按位与赋值运算符 自右向左 双目 14
^= 复合赋值按位异或赋值运算符 自右向左 双目 14
|= 复合赋值按位或赋值运算符 自右向左 双目 14
<<= 复合赋值左移赋值运算符 自右向左 双目 14
>>= 复合赋值右移赋值运算符 自右向左 双目 14
, 顺序求值运算符 自左向右 双目 15

//所有的单目运算符和所有涉及赋值的运算符的结合性,都是自右向左结合

//优先级最高的是" 描述符 ",其次是" 单目运算符 ";优先等级第二低的是" 赋值类运算符 ",优先等级最低的是" 顺序求值运算符 "

优先级

描述符 > 单目运算符 > 算术运算符(乘除模>加减) > 移位类运算符 > 关系运算符(大小于>等不等于) > 位逻辑与运算符 > 位逻辑异或运算符 > 位逻辑或运算符 > 逻辑与运算符 > 逻辑或运算符 > 条件运算符 > 赋值类运算符 > 顺序求值运算符

优先级描述的是表达式中运算符的优先执行顺序

优先级最高的是" 描述符 ",其次是" 单目运算符 ";优先等级第二低的是" 赋值类运算符 ",优先等级最低的是" 顺序求值运算符 "

乘法(" * ")、除法(" / ")、取模(" % ")的优先级大于加法(" + ")和减法(" - "),计算机会先进行优先级大的计算

(a+b)*c;					/*使用括号包裹,提高优先级*/

关系运算符优先级大于算术优先级,如果要先赋值或运算,需要用括号包裹

(a=b)==a;

单目逻辑非运算符" ! "优先级大于双目逻辑与运算符" && "和双目逻辑或运算符" || "

c=a&&b||!e;					/*c=((a&&b)||(!e))	(优先级自左向右)*/

算术运算符优先级大于复合赋值运算符

a+=3-3					/*a+=3-3*/

结合性

结合性是描述表达式整体的计算方向

当运算符优先级相同时,运算符自左向右进行结合

a+b-e+d;					/*a+b-e+d = ((a+b)-e)+d*/

复合赋值运算符的结合性与一般相反,是自右向左进行结合

11+=11*=11/=11-4;					/*11+=11*=11/=11-4 = (11+=(11*=(11/=(11-4)))) */

条件运算符的结合性是自左向右

result=(a<b)?1:0;					/*result=(a<b)?1:0 = (result)=((a<b)?1:0)*/

所有的单目运算符和所有涉及赋值的运算符的结合性,都是自右向左结合

流程

一个程序的结构(流程),包括:" 顺序结构 "、" 选择结构 "、" 循环结构 "。

程序结构的实现需要各种为流程服务的特殊语句,包括:" 条件语句 "、" 循环语句 "、" 转移语句 "等

条件语句

判断语句(if)

" if "判断语句是一种条件语句,可以根据不同的条件,判断是否进行操作

if判断语句分为3种形式,包括:" 单条件单分支if语句 "、" 单条件双分支if语句 "、" 多条件多分支if语句 "

//if语句后面不需要分号" ; "结尾,在使用时只需要给被花括号" {} "包裹的表达式使用分号" ; "结尾就可以了

单条件单分支if语句的语义为:如果满足什么条件,则执行什么语句(表达式)

if(条件){如果真值表达式;}					/*单条件单分支if语句*/
if(a==1){printf("biboli");}					/*如果" a "的值为1,则格式化打印输出" biboli "字符串*/

单条件双分支if语句(if...else语句),单条件双分支语句在真值执行某些语句(表达式)外,还能在为假值时令外执行一条语句(表达式)

单条件单分支if语句的语义为:如果满足什么条件,就执行什么语句(表达式),如果不满足之前的条件,就执行什么语句(表达式)

if(条件){如果真值表达式;}					/*单条件双分支if语句*/
else{如果假值表达式}
if(a!=b){printf("xxx");}
else{a+=1;}

多条件多分支if语句(else...if语句),可以实现对一系列互斥条件进行选择判断

if(条件){如果真值表达式;}					/*单条件双分支if语句*/
else if(条件){如果if假值,else if真值表达式;}}
else if(条件){如果上个else if假值,此else if真值表达式;}}
else if(条件){如果上个else if假值,此else if真值表达式;}}
else{如果if和所有else if都是假值时执行的表达式}
if(a==b){printf("a=b");}
else if(a==c){printf("a=c");}
else if(a==d){printf("a=d");}
else if(a==e){printf("a=e");}
else{printf("a!=b|c|d|e");}

嵌套if判断语句

if语句中,可以继续嵌套if语句

if(a==b){
	if(a==c){
		if(a==d){printf("a=b=c=d");}
		else{printf("a=b=c");}
	}
	else if(a==d){
		if(a==e){printf("a=b=d=e");}
		else{printf("a=b=d");}
	}
	else{printf("a=b");}
}

开关语句(switch)

switch语句被称为" 多分支选择语句 "、" 分支语句 ",是条件语句的一种,同时也属于复合语句

" switch "多分支选择语句的功能是计算" switch "括号里面表达式的值,并且逐个与" case "括号内常量表达式的值比较,当" switch "表达式的值与某一个" case "常量表达式的值相等时,则程序执行对应" case "后面的语句块

若对应执行的” case "语句中,没有" break "语句,则顺序执行下一个" case "语句,并且不进行比较,直到遇到" break "语句或该switch语句执行完毕

关键字

构成switch多分支选择语句的关键字,包括:" swtich "、" case "、" default "、" break "4个

  • switch
  • case
  • break
  • default
switch(条件){
case 情况:执行操作;
case 情况:
		执行操作;
		break;
default:
		默认情况语句;
}

多路开关模式

因为在执行第一次符合" case "条件的相应语句后,会将后面所有语句都输出;因此,可以设计多路开关的switch语句(类似于else...if)

switch(条件){
case 情况:
		执行操作;
		break;
case 情况:
		执行操作;
		break;
case 情况:
		执行操作;
		break;
default:
		执行操作;
		break;
}									/*" case "关键字后面的常量是一种" 标号 "*/

循环语句

除了一般顺序执行的结构语句,循环语句则是解决问题的主要方法,既可以减少代码量,还可以精确满足条件

循环语句支持嵌套不同或相同的语句,即一个循环体内又包含另一个完整的循环结构,称为" 循环嵌套 "

同时内嵌的循环中还可以嵌套循环,为" 多层嵌套 "、" 多层循环 "

当型循环语句(while)

" while "语句是用来实现" 当型 "循环的循环语句,即先判断条件的真假,再决定是否执行循环中的语句

当判断为真并执行一遍循环后,再次进行条件判断,若判断结果依旧为真,再次重复循环,不断判断循环循环判断,直到条件为假时(0),再退出循环

while(条件表达式){语句;}

死循环与空循环

while(1){printf("死循环");}					/*死循环*/
while(iSum+=1,i--;){;}					/*空循环*/

当假型循环语句(do while)

" do while "语句是先执行一次循环体语句中的内容,然后再判断表达式的值,若表达式的值为真,则继续循环重新执行循环体语句;以此往复,直到表达式的判断为假,此时循环结束

" do while "型语句类似于直到型语句,区别在于," do while "语句是直到假值时,退出循环,并非真值

" do while "语句可以用来" 无论是否判断,都至少执行一次 "的场景

do{循环语句;}
while(表达式);
do{
i++;
}
while(i<=100);

注意,在" do while "当假型循环语句中," while "部分只有判断,不能有循环体部分" {} "

直接循环语句(for)

" for "循环语句不仅可以用于循环次数确定的情况,还可以用于循环次数不确定的情况,用法灵活

" for "语句包含3个用分号" ; "隔开的表达式,这3个表达式可以是任意形式的表达式

语法要求,若在循环体内需要多条语句,则需要使用大括号将多条语句包括在一起,形成一条( 复合语句 )

for(表达式1;表达式2;表达式3){循环体;}

C语言for循环流程图

" for "循环包含有3个表达式,以及一个循环体代码块

表达式1主要是用来完成变量的初始化,通常是赋值表达式,且用来控制循环的变量,即表达式1被称为" 循环变量赋初值 "(初始循环开关)

初始循环开关的变量一定要先声明,或在for循环语句中连带声明(for(int x;x<0;x++))

表达式2主要用来判断真假值,真值循环,假值退出,每过一次循环,同时再进行一次判断,继续真值循环,假值退出

表达式3主要用来修改变量的值,从而使循环逐渐接近结束条件,每执行一次循环体,就会执行表达式3,对表达式1的变量进行修改

循环体代码可以是多条语句组成的复合语句,但要被大括号" {} "包裹

for(循环变量初始化;判断表达式;变值表达式){循环体;}
for(int i=1;i<=11;i++){
printf("The test number is :%d",i);
}

省略表达式

在for循环中,不必将3个表达式部分一起使用,可以对表达式进行单个、多个甚至是全部的忽略

for(;x<=5;i++)
{
printf("%d",x);
x++;
}					/*忽略循环变量赋初值表达式,并且变值其他变量,需要提前给所操作的变量进行赋值,并在循环体中另设置终止退出条件(x++)*/
for(int x=1;;x++){printf("%d,x");}					/*忽略判断表达式,永久循环,不做判断,当作永真,若要推出,需要在循环体中另设置终止退出条件*/
for(int x=1;x<=5;){
printf("%d",x);
x++;
}					/*忽略变值表达式,永真,若要退出,需要在循环体中另设置终止退出条件*/
for(;x<=5;){printf("%d",x);}	/*忽略包括,循环变量赋初值、变值表达式两个表达式,需要提前给所操作的变量进行赋值,并在循环体中另设置终止退出条件*/
for(;;){printf("test!");}			/*忽略全部表达式,永真无限循环,需要提前给所操作的变量进行赋值,根据需要并在循环体中另设置终止退出条件*/

逗号顺序求值

for循环中,表达式的内容可以是与循环变量赋初值的变量或逻辑无关;并且在" 循环变量赋初值表达式 "位和" 变值表达式 "位,可以用顺序求值符逗号" , "进行多条表达式的计算

for(a=1,b=2,c=3;i<=5;i++,a++,b++,c++){printf("%d%d%d",a,b,c);}

终止与继续

如果要强行终止循环,可以使用" break "关键字终止并跳出循环(for循环break与switch...case分支结构中的break作用不同)

break;

//break关键字只能用于循环语句和" switch "语句

如果需要返回头部继续执行,而不是跳出循环,就需要" countinue "关键字

continue;

continue关键字的作用是结束本次循环,跳过当前次循环体未执行的部分,并接着执行下一次的循环

//" continue "关键字与" break "关键字的区别是" continue "关键字只退出当前循环,并且继续下一次的循环操作,而" break "关键字是结束整个循环过程,不再判断执行循环的条件是否成立

跳转语句(goto)

" goto "语句为" 无条件跳转语句 ",可以使程序立即跳转到函数内部的任意一条可执行语句

" goto "关键字后要带上" 语句标号 ",该语句标号是同一个函数内某条语句的标号

标号可以在同一函数内,任意一条可执行语句的前面,并且以一个冒号" : "作为后缀

通常条件," goto "与条件语句配合使用,可以用来实现条件的转移,构成循环体或跳出循环体等功能

goto 语句标号;					/*语句标号需要在同一空间内给出*/

goto语句可以向前跳转、向后跳转、跳入循环、跳出循环

a=1;
goto nb;
c=3;
nb:if(1=1){b=2;}

//为防止程序结构化混乱,一般不建议使用" goto "无条件跳转语句

函数

函数是C语言程序的基本单位,函数内部是可执行代码

通过对函数模块的调用,可以实现相应的功能,被调用的函数可以是系统提供的" 库函数 "(标准函数),也可以是用户编写的自定义函数

C语言的程序,实现功能都是由各式各样的函数完成的,所以C语言也称" 函数语言 "

函数中不能嵌套另一个函数(包括主函数内),所有函数都是平行且互相独立的,函数间可相互调用,被调用的函数被称为" 下层函数 "(但主函数" main "不能被调用)

函数可选有参数和返回值

函数声明

一个函数在使用前,必须要进行声明

函数声明是让编译器知道函数的" 函数返回值类型 "、" 函数标识符 "、" 形式参数 "等信息

函数由" 函数头 "、" 函数体 "两部分构成

函数声明的格式由" 函数返回值类型 "、" 函数标识符 "、" 中括号 "、" 形式参数列表 "、" 分号 "5部分组成

函数返回值类型 函数标识符(形式参数列表);
int numberfunction(number1,number2,number3);

函数声明的语句最后要以分号" ; "结尾

函数声明的意义在于告诉编译器,函数将在后面进行定义

函数定义

函数定义是让编译器知道函数的功能(形式参数的类型)

若直接函数定义,则函数定义包括了函数的声明(可以只声明不定义)

定义与声明的区别在于,定义创建了对象,并给对象分配内存,而声明没有为对象分配内存

int numberfunction(int number1,int number2,int number3)
{
	函数体
}

函数头

函数头是函数声明的第一行,包括:" 返回值类型(函数类型) "、" 函数标识符(函数名) "以及" 形式参数列表(参数表) "三部分

返回值类型 函数标识符(形式参数列表)

" 返回值类型 "(函数类型)是任意一种数据类型

" 函数标识符 "(函数名)在程序中,必须是唯一的,并且要遵守标识符命名规则(只能使用" 数字 "、" 字母 "、" 下划线 ",并且开头只能是" 字母 "或" 下划线 ")

" 形式参数列表 "(参数表)简称为" 形参 ",是被括号" () "包裹的部分;形式参数列表中可以没有变量,也可以有多个变量(变量之间用顺序求值运算符" , "拼接),当进行函数调用的时候,实际参数将被复制到这些变量中

无形式参数,被称为" 无参函数 "(无参函数,一般不需要写返回类型)

一般有参数的形式情况," 主调函数 "与" 下层函数 "之间由数据传递关系

函数参数的作用时传递数据给函数使用,函数利用接受的数据进行具体的操作处理

函数参数分为:" 形式参数 "、" 实际参数 "

形式参数

" 形式参数 "又称" 形参 "

" 形式参数 "是形式上存在的参数(定义函数时的" 形式参数列表 "),在函数调用之前,传递给函数的值将被复制到这些形式参数中

实际参数

" 实际参数 "又称" 实参 "

" 实际参数 " 是实际存在的参数;即真正调用函数时," 函数标识符 "后面括号中的参数,为" 实际参数 "(调用函数时的" 形式参数列表 ")

" 实际参数 "是语句计算的结果,并且被复制给函数的" 形式参数 "

" 实际参数 "不管是什么类似都必须有确切的值,并且" 实际参数 "和" 形式参数 "的" 类型 "、" 数量 "、" 书写顺序 "等都要保持一致

函数体

函数体在函数头下边,是被大括号" {} "包裹的部分,包括:" 声明部分 "、" 语句部分 "以及" 返回语句 "三部分(函数体必须被花括号" {} "包裹,必须要有" 返回语句 ")

函数体包括局部变量的声明和函数的可执行代码

" 声明部分 "包括" 函数声明 "、" 变量声明 "、" 变量定义 "

" 返回语句 "用来返回实现的结果

{
声明部分
语句部分
返回语句
}

函数体中可以声明和定义变量,然后执行操作

void main()
{
char a;
a="biboli";
printf("Hello %s!\n",a);
}

当函数内所有语句都执行完,运算到结束符号" } "时,函数返回

返回语句

返回语句可以立即从所在函数中退出(从" 下层函数 "返回到调用函数),并返回值,将函数返回值赋给调用的表达式中

有些函数没有返回值(void空类型)

return(表达式);					/*括号可省略(retrun  表达式;)*/
return(0);
return 0;					/*" return(0) "返回空,通常用于主函数(main)*/

在一个函数内,可以有多个返回语句,每个返回值都有一个值,并且也只能有一条返回语句能被执行(遇到即退出下层函数并返回函数值到调用表达式)

if(a)
{
	if(a==0):puts("a=0");return 0;
	if(a==1):puts("a=1");return 1;
	if(a==2):puts("a=2");return 2;
	if(a==3):puts("a=3");return 3;
	puts("a!=0");
	return 4;
}

如果" 函数返回值类型 "和" return "语句中表达式得到的值类型不同,则进行自动类型转换,并最终以" 函数返回值类型 "为准(" 函数返回值类型决定函数直接返回值 ")

无参函数

" 无参函数 "也就是没有参数的函数

返回值类型 函数标识符()
{
函数体
}
void nuoopfu()
{
printf("biboli");
}

空函数

空函数是什么都不做的函数,没有实际作用,存在的意义是给未编好的函数占位置,以后再用编号的函数取代

返回值类型 函数标识符()
{}
void nullfunc(){} 

数组实参函数

数组作为实际参数时,只传递数组的地址,而不是将整个数个数组赋值到函数中(数组作为实际参数时,指向该数组第一个元素的指针就会被传递到函数中)

float farray(_farray[]);					/*声明并定义数组函数*/

调用函数

使用函数的过程就是调用函数的过程

有三种情况会调用函数,包括:" 函数语句调用 "、" 函数表达式调用 "、" 函数参数调用 "

如果自定义函数在主函数" main "前面,就不需要引入" 头文件 "后再进行声明

如果自定义函数在主函数" main "后面,就需要在引用" 头文件 "的时候(进入主函数前)提前进行声明

" 函数语句调用 "又称" 函数调用语句 "是调用函数的三种方法之一

函数标识符(实际参数列表);
func(string);

" 函数表达式调用 "是指带有实参的函数在表达式中参与运算被调用,是调用函数的三种方法之一

函数出现在表达式中,这时函数必须带有确切的" 函数返回值 ",使这个" 函数返回值 "参与表达式运算

result = NUM*inputnum(3,5);

" 函数参数调用 "是指一个实参函数嵌套在另一个函数中当作" 实际参数 "参与运算被调用,是调用函数的三种方法之一

result = _num(count,inputnum(3,5));

嵌套调用

C语言不能嵌套函数,但允许在函数中调用其他函数(嵌套调用)

char func1(char char_array[])
{
	return printf("hello %s",char_array);
}
void func2()
{
	char char_array[]={'x','\0'};
	func1(char_array);
}

定义形参后,另一函数内依旧需要再次声明其类型

递归调用

" 递归调用 "又称" 自调用函数 "

C语言的函数都支持递归,每个函数都可以直接或间接的调用自己(" 直接调用 "是指函数直接调用自己本身)

" 递归调用 "之所以能实现,是因为函数的每个执行过程在栈中都有自己的" 形参 "和" 局部变量 "的副本,这些副本和该函数的其他执行过程不发生关系;这种副本机制使大多数程序设计语言实现子程序结构的基础,也使得递归成为可能

如果某个" 下层函数 "调用了另一个" 下层函数 ",同时" 下层函数 "调用的" 下层函数 "又反过来调用了调用它的" 下层函数 ",那么这段关系中第二次调用就被称为" 调用函数的递归 ";这种递归的调用关系,发生在上一层调用未结束时

递归调用函数能正常的工作原理为:" 下层函数 "在栈中较低的位置有它独立的一组参数和自变量,原先的参数和变量不受任何的影响

内部函数

" 内部函数 "又称" 静态函数 "

C语言中,往往把一个函数,或多个函数保存为一个文件,这个文件称为" 源文件 "

当由多个" 源文件 "组成一个" 源程序 "时,一个" 源文件 "中的函数可以指定不被其他" 源文件 "调用

只能被函数本身所在" 源文件 "调用的函数为" 内部函数 "(能被其他" 源文件 "调用的函数,为" 外部函数 ")

不同的" 源文件 "中,可以有相同名字的" 静态函数 ",这些同名函数互不干扰

定义" 静态函数 "时,要在" 返回值类型 "和" 函数标识符 "前面加上关键字" static "

static 返回值类型 函数标识符(形式参数列表);
static char charstring(char _value);					/*声明及定义函数时,前面加上" static "关键字,定义或声明的函数为" 静态函数(内部函数) "

" 静态函数(内部函数) "的好处是,多个编写者进行编程时,不用担心相互之间的函数标识符重名冲突

外部函数

" 外部函数 "又称" 动态函数 "

能被其他" 源文件 "调用的函数为" 外部函数 "(只能被函数本身所在" 源文件 "调用的函数,为" 内部函数 ")

定义" 外部函数(动态函数) "时,要在" 返回值类型 "和" 函数标识符 "前面加上关键字" extern "(如果不指明关键字,C语言默认将函数定位" 外部函数(动态函数) ")

extern 返回值类型 函数标识符(形式参数列表);
extern int _num(int _value);					/*声明及定义函数时,前面加上" extern "关键字,定义或声明的函数为" 外部函数(动态函数) "
int _num(int _value);					/*不加关键字,默认为外部函数(动态函数)*/

主函数

一个C语言程序必须且至少拥有一个主函数 main(),也可以包含一个主函数main()和若干个其他函数

主函数main()可以在程序的任何位置,但必须要存在

每个C语言程序的入口和出口都位于主函数" main "中;但并不是所有的内容都放在主函数" main "中,为了方便规划、组织、调试、编写,会将程序划分若干个程序模块,每个程序模块完成一部分功能(可分工,提高编程效率)

主函数可以调用其他函数(其他函数也可相互调用),但是主函数" main "是不能被其他函数调用的

主函数" main "中不能嵌套其他函数

" main "函数的返回值为整型,并可以有2个参数,2个参数分别是" 整数 "和指向字符数组的" 指针 ";" main "函数可以不带任何参数

运行程序时,有时需要将必要的参数传递给主函数" main "

主函数" main "的参数包括:整型变量" argc "、字符数组" argv[] "两项,用来接受" 命令行实际参数 ",是只有主函数" main "才能有的参数

main(int argc,char* argv[])

argc参数

" argc "参数用来保存" 命令行参数 "(实参)的个数,为整型变量;并且" argc "参数的值 至少是1(程序名就是第一个实参)

#argv参数

" argv "参数是指向" 字符指针数组 "的指针,在" 字符指针数组 "中每一个元素都指向" 命令行实参 "

" 命令行实参 "都是字符串,任何数字都要由程序转化为适当格式

main(int argc,char** argv)					/*argv是指向" 字符指针数组 "的指针,即主函数main可以写成这样*/

库函数

C语言编译器会内置函数,这种函数被称为" 库函数 "或" 标准函数 ",库函数无需声明可直接使用,只需要声明所对应的" 头文件(函数库) "

若要使用已经存在的函数,则需要声明包含其所对应的" 函数库 "

#include<函数库>

库函数从功能的角度出发可分为:" 输入输出函数 "、" 数学函数 "、" 时间转换和操作函数 "、" 字符屏幕和图形功能函数 "、" 字符串函数 "、" 目录路径函数 "、" 动态地址函数 "、" 接口函数 "、" 内存函数 "、" 过程控制函数 "、" 其他函数 "共11类

输入输出函数					用于完成输入/输出功能
数学函数					用于数学计算
时间转换和操作函数			用于日期、时间转换操作
字符屏幕和图形功能函数			用于字符屏幕管理和各种图形绘制功能
字符串函数					用于字符串操作和处理
目录路径函数					用于文件目录和路径操作
动态地址函数					用于从自由内存区中分配所需的地址空间
接口函数					用于与操作系统最内层连接
内存函数					用于内存管理、读取等操作
过程控制函数					用于控制程序执行、终止等
其他函数					不能简单归属某一类的函数

注释

/* */表示注释部分

预处理命令

宏定义命令

完整的C语言程序

posted @ 2021-05-11 16:26  biboli  阅读(99)  评论(0编辑  收藏  举报