1. if-else语句
1.1 基本语法
if (表达式)
语句1
else
语句2
表达式成立(为真),则语句执行;表达式不成立(为假),则语句不执行。
缺省情况下,if
语句只能控制一条语句,如果要让 if
语句控制多条语句,需要使用 {}
将代码括起来,else
同理。
1.2嵌套if-else语句
- else嵌套
- if 嵌套
1.3悬空else问题
如果有多个if
和else
,可以记住这样一条规则,else
总是跟最接近的if匹配。看看以下代码的输出会是什么。
#include<stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
这个属于严谨不好的代码书写习惯,正确书写方法应该是:
#include<stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
2.关系操作符
几点说明:
-
关系表达式通常返回0或1,表示假和真。因此通常用于
if
和while
结构 -
注意相等运算符
==
和赋值运算符=
不能乱用。 -
多个关系运算符不宜连用
#include<stdio.h> int main() { int age = 0; scanf("%d",&age); if(18<=age<=36) printf("青年\n"); return 0; }
从左到右两两进行比较发现 if
语句中的表达式为真,没有达到预想效果。正确写法应该是:
if(age>=18 && age<=36 )
3.条件操作符
exp1 ? exp2 : exp3
exp1
为真,exp2
计算,计算的结果是整个表达式的结果;exp1
为假,exp3
计算,计算的结果是整个表达式的结果;- C语言中唯一一个三目操作符。
//使用条件操作符实现两个数中较大值
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d",&a,&b);
int m = (a>b ? a : b);
printf("%d",m);
return 0 ;
}
4.逻辑操作符:&&,||,!
!
逻辑非。
&&
逻辑与。
||
逻辑或。
//闰年的判断
#include<stdio.h>
int main()
{
int year = 0;
printf("please enter year:");
scanf("%d", & year);
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
printf("%d is leap year", year);
else
printf("%d isn't leap year",year);
return 0;
}
逻辑运算的短路
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
// 0
// a = 1,走到第一个表达式的时候就已经短路了。
printf("a = %d\nb = %d\nc = %d\nd = %d", a, b, c, d);
return 0;
}
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ || ++b || d++;
// 0 3 不执行,被短路
// a = 1 b = 3
printf("a = %d\nb = %d\nc = %d\nd = %d", a, b, c, d);
return 0;
}
5. switch语句
switch
语句是一种特殊形式的 if……else
结构,用于判断条件有多个结果的情况。它把多重的 else if
改成更易用,可读性更好的形式。
switch (expression)
{
case value1:statement
case value2 : statement
default:statement
}
根据表达式 expression
不同的值,执行相应的 case
分支。如果找不到对应的值,就执行 default
分支。
注意:
-
switch
后的expression
必须是整型表达式 -
case
后的值,必须是整型常量表达式,且case
和后边的数字必须有空格.
需要说明的是字符也属于整型表达式
#include<stdio.h> int main() { char ch = 'w'; scanf("%c", &ch); switch (ch) { case 'a': printf("0"); break; case 'b': printf("1"); break; } return 0; }
case 后面的值不可以使用变量!
-
每一个
case
语句中的代码执行完成后,需要加上break
才能跳出这个switch
语句,不然就会一直往下执行,case
相当于是入口。一定一定要记住 -
switch
语句中case
和default
没有顺序要求。
//输入一个1~7的数字,打印对应的是星期几
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1 :
printf("今天是星期:%d", day);
break;
case 2:
printf("今天是星期:%d", day);
break;
case 3:
printf("今天是星期:%d", day);
break;
case 4:
printf("今天是星期:%d", day);
break;
case 5:
printf("今天是星期:%d", day);
break;
case 6:
printf("今天是星期:%d", day);
break;
case 7:
printf("今天是星期:%d", day);
break;
default:
printf("wrong", day);
}
return 0;
}
6. While语句
//basic syntax
while(表达式)
语句
//示例-在屏幕上打印1~10的值
#include<stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
printf("%d ",i);
i++;
}
return 0;
}
//练习-输入一个正整数,逆序打印这个整数的每一位
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d",&n);
while (n)
{
printf("%d ", n % 10);
n = n / 10;
}
return 0;
}
7. for循环
//basic syntax
for(expression1;expression2;expression3)
statement;
表达式1:用于循环变量的初始化
表达式2:用于循环结束条件的判断
表达式3:用于循环变量的调整
//示例
#include<stdio.h>
int main()
{
for(i = 1;i<=10;i++)
printf("%d ",i);
return 0;
}
//练习——计算1~100之间3 的倍数之和
#include<stdio.h>
int main()
{
int sum = 0;
for(int i = 1;i<=100;i++)
if (i % 3 == 0)
{
sum = sum + i;
}
printf("%d", sum);
return 0;
}
#include<stdio.h>
int main()
{
int sum = 0;
for(int i = 3;i<=100;i+=3)
if (i % 3 == 0)
{
sum += i;
}
printf("%d", sum);
return 0;
}
while
和 for
循环对比
8. do-while循环
//basic syntax
do
语句;
while(表达式);//不要漏掉“;”
do-while
循环是先直接进入循环体,执行循环语句,再执行 while
后的判断表达式,表达式为真进行下一次,否则不再进行循环。
do-while
循环体至少执行一次!
//example
#include<stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ",i);
i++;
}
while(i<=10);
return 0;
}
//exercise
#include<stdio.h>
int main()
{
int num = 0;
int bit = 0;
scanf("%d", &num);
do
{
num = num / 10;
bit++;
}
while (num);
printf("%d", bit);
return 0;
上例中当输入0时,依然会输出1(我们认为任何一个正整数至少是一位数),但是while循环无法做到。????
9. break 与 continue 语句
break
的作⽤是⽤于永久的终⽌循环,只要 break
被执⾏,直接就会跳出循环,继续往后执⾏。
continue
的作⽤是跳过本次循环 continue
后边的代码,在 for
循环和 while
循环中有所差异的。
9.1 while 循环中的break和continue
//example
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;//程序进入死循环
printf("%d ", i);
i++;
}
return 0;
}
//如果更改i++的位置,则会改变输出
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
i++;
if (i == 5)
continue;//最终输出为2 3 4 6 7 8 9 10 11
printf("%d ", i);
}
return 0;
}
如果循环的调整是在 continue
后边的话,可能会造成死循环。
9.2 for循环中的break 和 continue
#include<stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
在 for
循环中 continue
的作⽤是跳过本次循环中 continue
后的代码,直接去到循环的调整部分。未来当某个条件发⽣的时候,本次循环⽆需再执⾏后续某些操作的时候,就可以使⽤continue
来实现。
对比
9.3 do while循环中的break 和 continue
基本与while的情况是一样的。
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
continue;//与while 一样会出现死循环
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
SUMMARY!!!:while
循环和 do-while
循环continue
都是跳过continue
后面的语句,跳到循环的判断部分。而for
循环中则是跳到for
循环的调整部分。
10.循环的嵌套
//找出100-200之间的素数
#include<stdio.h>
int main()
{
int i = 100;
for (i = 100; i <= 200; i++)
{
int s = 0;//这个语句要是放在最前面貌似会出问题,why?
for (int j = 1; j <= i; j++)
{
if (i % j == 0)
s = s + 1;
}
if (s == 2)
printf("%d ", i);
}
return 0;
}
回应上面出现的问题,如果int s = 2
语句放在所有for循环的前面,会导致每次j循环结束后,s没有重新赋值,所以无法实现打印所有素数的效果。
11. goto语句
C语⾔提供了⼀种⾮常特别的语法,就是 goto
语句和跳转标号, goto
语句可以实现在同⼀个函数内跳转到设置好的标号处。
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next:
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
goto
语句如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以我们的建议是能不⽤尽量不去使⽤;但是 goto
语句也不是⼀⽆是处,在多层循环的代码中,如果想快速跳出使⽤ goto
就⾮常的⽅便了。
for(...)
{
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
}
error:
本来 for
循环想提前退出得使⽤ break
,⼀个 break
只能跳出⼀层 for
循环,如果3层循环嵌套就得使⽤3个 break
才能跳出循环,所以在这种情况下我们使⽤ goto
语句就会更加的快捷。
分支循环注意点
-
不要轻易省略循环初值、循环条件判断、循环变量调整
#include<stdio.h> int main() { int i = 0; int j = 0; for(i = 0;i<5;i++) { for(j =0;j<5;j++) { printf("hehe\n"); } } return 0; }
很容易可以知道上面一段代码打印hehe的数量为25,但是如果把上述代码更改为:
#include<stdio.h> int main() { int i = 0; int j = 0; for(;i<5;i++) { for(;j<5;j++) { printf("hehe\n"); } } return 0; }
这段代码打印几个
hehe
呢,答案是5个!,因为在i=0
这一次循环中,j通过自增变成了5,但是等下一次i=1
时,j的值没有改变,依然是5,所以以后的每一次都无法进入第二层循环。
#else.猜数字游戏
##else. 1 知识补充-随机数生成
1.1 rand函数
//basic syntax
int rand(void);
生成随机数范围:0~RAND_MAX
头文件:stdlib.h
#include<stdio.h>
#include<stdio.h>
int main()
{
printf("%d\n",rand());
printf("%d\n",rand());
printf("%d\n",rand());
printf("%d\n",rand());
printf("%d\n",rand());
return 0;
}
运行上述代码,会发现每次产生的随机数竟然都是一样的!?
如果再深⼊了解⼀下,我们就不难发现,其实rand函数⽣成的随机数是伪随机的,伪随机数不是真正的随机数,是通过某种算法⽣成的随机数。真正的随机数的是⽆法预测下⼀个值是多少的。⽽**rand函数是对⼀个叫“种⼦”的基准值进⾏运算⽣成的随机数。**之所以前⾯每次运⾏程序产⽣的随机数序列是⼀样的,那是因为rand函数⽣成随机数的默认种⼦是1。如果要⽣成不同的随机数,就要让种⼦是变化的。
1.2 srand
函数
C语⾔中⼜提供了⼀个函数叫 srand
,⽤来初始化随机数的⽣成器的
//basic syntax
void srand(unsigned int seed)
程序中在调⽤ rand 函数之前先调⽤ srand 函数,通过 srand 函数的参数seed来设置rand函数⽣成随机数的时候的种⼦,只要种⼦在变化,每次⽣成的随机数序列也就变化起来了。
1.3 time 函数
在程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的。
//basic syntax
time_t time(time_t*timer)
-
time 函数会返回当前的⽇历时间,其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的差值,单位是秒。这个概念叫做时间戳。
时间戳:Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
-
返回的类型是**
time_t
**类型的,time_t 类型本质上其实就是32位或者64位的整型类型。 -
time函数的参数 timer 如果是⾮NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带回去。
-
如果 timer 是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。
头文件:time.h
#include<stdio.h>
#include<stdio.h>
int main()
{
srand((unsigned int)time(NULL));
int r = rand();
printf("%d\n",rand());
printf("%d\n",rand());
printf("%d\n",rand());
printf("%d\n",rand());
printf("%d\n",rand());
return 0;
}
1.4 设置随机数的范围
rand() %100;//生成0~99
rand()%100 + 1;//生成1~100
100 + rand()%(200-100+1)//生成100~200
//basic syntax
a + rand()%(b-a+1)//生成a~b的随机数
else .2 猜数字游戏实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
printf("*************************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*************************\n");
}
void game()
{
int randnumber = rand() % 100 + 1;
int guessnumber = 0;
int count = 5;
while (count)
{
printf("Please Enter The Number You Guess:");
scanf("%d", &guessnumber);
if (guessnumber < randnumber)
{
printf("The Number You Guess Is Too Small!\n");
}
else if (guessnumber > randnumber)
{
printf("The Number You Guess Is Too Big!\n");
}
else
{
printf("The Right Answer is %d ,You guess sucessfully!\n",guessnumber);
break;
}
count--;
}
if (count == 0)
{
printf("Unfortunately You Fail,The right Answer Is %d\n",randnumber);
}
}
int main()
{
int choice = 0;
int again = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("please choose:");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("Welcome To GuessNumber Game\n");
game();
printf("Do You Want To Try It Again?\n");
printf("Yes ,Please Enter 1\n");
printf("No ,Please Enter 0\n");
scanf("%d", &again);
if (again)
choice = 1;
else
choice = 0;
break;
case 0:
printf("Exit The Game\n");
break;
default:
printf("Wrong,We will go back to the menu for you\n");
break;
}
} while (choice);
return 0;
}