一、开关语句
switch(数据) { case v1: 语句1; break; case v2: 语句2; break; case v3: 语句3; break; ... default: 语句; break; }
1、switch小括号中的数据可以是变量或表达式,但结果必须是整数型,case后面的数据必须是整数型常量。
#include <stdio.h>
int main(int argc,const char* argv[])
{
float num = 2;
int v1,v2,v3,v4;
switch(num)
{
case v1: printf("v1\n");
case v2: printf("v2\n");
case v3: printf("v3\n");
case v4: printf("v4\n");
}
}
/*
switch.c:7:9: error: switch quantity not an integer switch(num)
switch.c:9:3: error: case label does not reduce to an integer constant case v1: printf("v1\n");
*/
2、把switch小括号中的数据与case后的数据进行对比,如果相等则打开执行开关。
3、当执行开关处于打开状态时,case后面的语句就会被执行,如果执行开关不关闭,之后case、default后面的语句也会被执行。
4、break语句可以关闭执行开关,如果每个case后都break语句,就形成了多分支结构。
5、default无论写在任何位置,都是等所有的case没有匹配成功后,才打开执行开开关,就相当于多分支if语句最后的else,可以有也可以没有。
6、switch与if else语句相比只是代码更简洁,能使用switch语句解决的问题,if else也可以解决,所以在实际工作中有的程序员只使用if else 语句。
#include <stdio.h>
int main(int argc,const char* argv[])
{
int num = 1;
switch(num)
{
case 1:
printf("v1\n");
break;
case 2:
printf("v2\n");
break;
case 3:
printf("v3\n");
break;
case 4:
printf("v4\n");
break;
default:
printf("other\n");
}
}
gnu编译器的专用语法:
switch(整型数据) { case start1 ... end1: 语句1; break; case start2 ... end2: 语句2; break; case start3 ... end3: 语句3; break; }
二、for循环语句
通过反复执行一段代码,达到解决问题的目的,这种语句结构叫循环。
for是一种非常灵活的循环,一般都使用一个变量来引导它的执行过程,这个变量被称为循环变量,早期使用index作为循环变量名,然后逐渐演变成i,如果有多个循环也可以使用j、k、l。
for([1]; [2]; [3]) { [4]; } 1、为for循环做一些准备工作,定义循环变量、给循环变量赋初值(C89的语法标准下不能定义变量,C99之后的语法标准才可以),在此处定义的变量和出了for循环就不能再使用。 2、判断循环条件,条件为真执行4,条件为假结束for循环,如果没有语句,则默认为真 4、被反复执行的代码也叫循环体 3、改变循环条件,循环变量自加或自减1,防止变成死循环 循环流程: 1 2 4 3 2 4 3 2 4 3 ... 2 // C89语法标准 int main(int argc,const char* argv[]) { int i; for(i=0; i<10; i++) { printf("%d\n",i); } } // C99语法标准才支持,ubuntu16.04安装的gcc默认支持c99语法标准 int main(int argc,const char* argv[]) { for(int i=0; i<10; i++) { // 这种方式定义的循环变量i,出了for循环的大括号就不能再使用了 printf("%d\n",i); } // 编译报错 printf("%d\n",i); }
for循环的不同写法:
for(;;) // 死循环 { ... } int i=0; for(; i<10; i++) { ... } int i=0; for(; i<10;) { ... i++; } for(int i=0; i<10; i++,...); 注意:如果循环条件无论改什么样,循环体都只执行一次,就有可能是for的末尾多了个分号。
三、while循环语句
while(循环条件) { // 循环体 }
执行流程:先检查循环条件,为真则执行循环体,为假则结束while循环。 如果for循环语句忽略模块1和模块3功能与while一模一样,它相当于for循环的精简版本,for适合解决循环次数明确的问题,while适合解决只知道循环条件,但不确定具体的循环次数的问题。
四、do while循环语句
do { // 循环体 }while(循环条件);
执行流程:先执行循环体,再判断循环条件,当条件为真时继续执行循环体,当条件为假时结束循环,无论条件真假,循环体至少执行一次。
注意:在 do while 循环体中定义的变量,不能在小括号中使用,类似for循环中定义的循环变量,出了大括号也不能使用。
循环嵌套:
循环语句中包含循环语句,外层循环执行一次,内层循环执行一遍。
for(int i=0; i<10; i++) { for(int j=0; j<10; j++) { printf("*"); } printf("%d\n",i); }
四、跳转语句
break跳转语句:
break 语句有两种用法: 用法1:在 switch 语句中可以关闭执行开关。 用法2:在循环语句中,它可以跳出一层循环,也是结束死循环的一种方式,一般用它来提前结束循环,提高程序的执行效率。
#include <stdio.h>
int main()
{
int i = 0;
for(;;)
{
if(i>=10)
break;
printf("%d\n",i++);
}
}
#include <stdio.h>
#include <math.h>
int main(int argc,const char* argv[])
{
int num, i;
printf("请输入一个整数:");
scanf("%d",&num);
for(i=2; i<=sqrt(num); i++)
{
if(0 == num%i)
break;
}
if(i >sqrt(num))
printf("是素数!\n");
else
printf("不是素数!\n");
return 0;
}
continue语句:
只能在循环语句中使用,停止本次循环体的执行,直接进行下一次循环,一般用于改善大括号的嵌套层数。
#include <stdio.h>
int main()
{
for(int i=0; i<10; i++)
{
if(i%2)
continue;
printf("%d\n",i++);
}
}
goto语句:
goto 语句可以跳转到函数内的任意位置,由于它过度灵活、自由可能会破坏已经设计好的分支、循环语句,因此一般公司都禁止使用,新的编程语句中已经取消该关键字。
goto非常适合在驱动程序中处理异常、释放资源,所以C语言中从语法设计上就非常适合控制硬件。 在函数内通过定义标签确定代码位置。
#include <stdio.h>
int main()
{
int i = 0;
goto line3; // 跳转到某个位置标签
// 定义位置标签
line1:
printf("1\n");
line2:
printf("2\n");
line3:
printf("3\n");
line4:
printf("4\n");
line5:
printf("5\n");
}
return语句:
return 语句可以跳出函数,并返回一个数据给函数的调用者。
#include <stdio.h>
int main()
{
for(int i=0; i<10; i++)
{
if(5 == i)
return 0;
printf("%d\n",i);
}
printf("over!\n");
}
五、数组
什么是数组:
数组就是变量的集合,是一种批量定义变量的方式。
如何定义数组:
类型 数组名[数量]; int arr[8]; 就相当于定义了8个变量 int b1,b2,b3,b4,b5,b6,b7,b8;
访问数组中的变量:
数组名[下标]; 下标就是变量的编号,下标的范围:0 , 数量-1
遍历数组:
与for循环配合,使用循环变量作为数组的下标。
int arr[8]; for(int i=0; i<8; i++) { printf("%d ",arr[i]); }
数组的初始化:
数组元素的默认值与普通变量一样,是随机的,如果需要对数组初始化可以使用以下语法。 类型 数组名[数量] = {v1,v2,v3,...};
1、如果初始化数据不够,编译器会自动补0。 2、如果初始化数据过多,编译器会提示警告并丢弃多余数据。 3、对数组进行初始化时,数组的数量可以省略,编译器会自动统计数据的数量设置给数组。 4、初始化语法只能在定义数组时使用,这也是唯一一次能对数组批量访问的机会,数组定义完成后就只能单个访问。
int arr[] = {1,3,1,2,1,3,2,5,3,5,2,3,6,3}; size_t len = sizeof(arr)/sizeof(arr[0]); for(int i=0; i<len; i++) { printf("%d ",arr[i]); }
数组越界:
使用非法的下标访问数组的行为叫数组越界。
C语言中当数组越界访问时编译器不会报错,因为可以使用变量作为数组的下标,编译器无法检测到数组越界的(程序不运行变量的值无法确定)所以就不再检查数组的下标是否合法,这样做的好处就是代码的编译、运行速度快。
数据越界的后果:
1、运气好的情况下,会一切正常。
2、段错误,操作系统发现程序非法访问内存,它就会把程序杀死。
3、脏数据,数组越界访问到其它数组、变量的内存位置,破坏了其它数组、变量的数据。