在前面的两节讲的变量及其操作,还有打印操作,很简单就写出按顺序执行的多条语句,但如果不需要按顺序执行语句,或者需要循环执行一条语句,需要用到if、do...while、while、for、switch这些条件语句。
(1)
if(判断条件)语句块
若判断条件为真,则执行语句块,否则不执行。语句块可以是一条语句,也可以是用大括号括起来的一段语句块,如:【if(2>1)printf("老婆,我爱你!");】
【if(1>3){ printf("今天天气不好"); printf("扑街了!"); }】
(2)
if(判断条件1)
{ 语句块1 }
else if(判断条件2)
{ 语句块2 }
else
{ 语句块3 }
这里如果判断条件1成立则执行语句块1,然后就不继续执行下面的else if的判断,也不执行下面的else语句;如果判断条件1不成立,则去执行判断条件2,如果判断条件2成立则执行语句块2,如果判断条件2不成立,则无条件执行语句块3。
如:
if(1>2) printf("老婆生气了!");
else if(1>3) printf("老公生气了!");
else printf("老婆和老公都很开心~~!\n");
(3)
do
{ 语句块 }while(判断条件);
这个控制语句,是先执行语句块,然后再去判断条件,若判断条件成立则又返回去执行语句块,如此循环,知道判断条件为假时候才跳出循环体。
如:
bool temp = false;
do
{
printf("我们结婚吧!\n");
if( ifJieHun() ) {
printf("结婚了吧!\n");
temp = true;
}
}while(!temp);
先执行语句块,然后判断"!temp"是否为真,若为真表示没结婚,又返回去执行语句块,语句块中,如果函数ifJieHun()返回值为真,则结婚了,temp被赋值为true,在接下来的判断条件中"!temp"为假,已结婚,跳出循环。开始新生活~~。
(4)
while(判断条件)
{ 语句块 }
若判断条件为真,则执行语句块,语句块执行完毕后,又再次回到去执行判断条件,若为真,又再次执行语句块。。。直到判断条件为假,才跳出循环,不再执行语句块了。
如:
while(1+2 > 4)
{
printf("骗我\n");
}
首先执行“1+2>4”的判断条件,显然判断条件最终结果是false,所以一次都没有执行打印语句块。
(5)
for(语句1; 语句2; 语句3)
{ 语句块 }
这里for语句有三部分,语句1表示初始执行语句,表示进入循环前,要初始化的工作或其他工作;语句2表示判断条件,若判断条件为真,则继续执行语句块,否则跳出循环;这里语句3是在执行语句块之后才执行的,在这里不管语句块执行了什么语句,除非调用break;跳出for循环,否则在执行语句块之后,必定会执行语句3!当执行完语句3之后,才执行判断语句!
注:for语句中,语句1和语句3可以为空,即什么都不写,但语句2是必须存在程序语句。
如:
for(int index = 0; index < 10; index++)
{
if(index > 8) break;
if(index >6) continue;
printf("ffyyqx");
}
这里for循环,“int index = 0”是语句1,表示用来初始化用于循环累计的index,“index > 10”是语句2,也就是判断语句,若index小于10表示继续执行语句块,“index++”是语句3,用于执行语句块之后要执行的语句;语句块里,除非执行了break;无条件跳出循环语句,continue的作用是跳过下在“continue;”后面所有语句,然后执行语句3“index++”,当执行完语句3之后,才执行判断语句,若index<10为真,继续执行下面的语句块,为假就跳出循环。
(6)switch语句。
switch(检验数值)
{
case 数值1:
{ 语句块1 }
break;
case 数值2:
{ 语句块2 }
break;
......
default:
{ 语句块n }
}
这里的检验数值必须是整数或者能被转换成整数的单个字符,不能是浮点数,不能默认强制转换浮点数为整数,只能是整型变量,或者单个字符变量。
若检验数值和数值1相等,则执行语句块1,然后才执行break;,这里的break;只是跳出switch语句,可以把break放到语句块1里面,若没有break语句,会继续用检验数值和数值2比较,若相等则继续执行语句块2,一直运行到break,或者直到default,这里的default表示默认,若检验数值和数值1/2/3等等这些数值都不匹配,在这个前提下才会默认执行default里面的语句块n。
这里的default和语句块n可以省略,也就是若没有匹配的数值则会跳出switch。
注:这里的数值1、数值2、和数值3...等等这些数值必定不能出现两个相等的。
如:
switch(a)
{
case 1:
printf("1");
break;
case 2:
printf("2");
case 3:
printf("3");
break;
case 4:
case 5: case 6:
printf("4");
}
这里,若a为1则打印1,若a为2,则会打印2,且在打印2之后没有遇到break语句,所以继续执行打印3语句,这里不需要继续判断是否等于3,因为这里打印3语句的执行条件默认是a值为2或者3。若a是4、5或者6,会执行打印4的语句,这里数值之间是或者的意思,不是全部数值都要匹配的与的意思。
另外switch的case后面的数值可以用省略符号“...”表示一个具体的范围空间。
如:
switch(a)
{
case 1 ... 10:
{ 语句块 }
}
这里表示若a的数值处于1到10这个区间,就会执行语句块,其意思和的if语句相同即【if(a>=1 || a<=10) { 语句块 }】
(7)在程序语言中,函数本质上是用你来封装语句块的,主要是把那些程序员看起来是重复性的代码都应该放到函数里,然后在多次使用这些重复性代码时候,只需要调用该函数就可以了,简单有效!
在C语言里,函数名最终会编译成一个内存地址,这个内存地址指向的是一段代码段,当程序执行到函数入口时候,就会通过函数地址跳转到对应的代码段继续执行,而当代码段中执行完毕后,也就是函数执行完毕,又会跳回到原来的函数入口,继续执行下一条语句。
函数原型声明:【返回值类型 函数名(参数列表);】
函数定义:
返回类型 函数名(参数列表)
{ 代码段。。。}
返回值类型:是函数调用完毕之后必须返回该类型的值,除非在函数里调用了exit()退出程序函数。
函数名:等同于变量名,只要不和关键字冲突就可以。若要取得函数的地址,只需要在变量名之前加上取地址符号&就可以了。
参数列表:都是传入函数的参数,表明要执行该函数,必须传入什么样的什么类型的参数,其形式如同定义变量:【int a,char* ptr】定义每个参数,用逗号隔开。这里的参数列表都是形参,表示形式上的参数,只是形式上,但并没有真实的值,也只有在调用这个函数时候,才会传入实参,即实际参数,具有实际的值。
如:【void myfunc(int a,char* ptr){ 语句块 }】定义一个没有返回值(不需要返回值),形参有整型变量a和字符串指针ptr的函数,定义了形参,那么在语句块里就能直接使用形参的变量,但形参的值并不确定,在调用时候或许传入的是1,又或许传入的是2。
在C语言里,程序的启动函数是main函数,程序一启动,必须调用main函数。
(8)返回值和临时变量
在c语言中,函数返回值一般都是返回一个临时变量,如
int myfunc()
{ ...; return 100; }
int myInt = myfunc();
这里myfunc函数返回100赋值给变量myInt,但是这个100不会直接被返回用于myInt的初始化,而是在return 100;的同时,编译器会新建一个临时的int类型变量,然后将100赋值给这个临时变量,之后才赋值给myInt,然后进行函数堆栈的清空,也就是销毁执行函数时候所分配的内存。
注:函数调用,必然是先获得其返回值,然后才会销毁函数堆栈。
(9)可变成参数
参数个数不确定的函数叫变长参数函数,需要使用特殊的方法获取这种函数的形参。
如:
void print(int ge_shu, ...);
第一个参数是后面“...”省略的参数的个数,至于后面省略参数的类型,需要通过函数获得。