一、选择语句
当要进行一个选择并且会产生分支时使用。或者说在多种情况中,只会有其中一种或几种情况发生时,也使用选择语句
有if和switch两种
if语句:
if(a == 2)
printf("1:打印\n");
if(a >= 1) //当()内的表达式为真时就执行if后的一条语句
printf("2:打印\n"); //为假就不执行,跳过
if(a) //为非0里也会执行
printf("3:打印\n");
if(0) //当为0时就不执行
printf("4:打印\n");
1. 并且if默认情况下只会执行下面的一条语句,除非加上{ },就会执行代码块里的全部语句
int a =2 ;
if(a == 1)
printf("知道a的值了\n");
printf("a的值是1\n");
if(a >= 1)
{
printf("知道a的值了\n");
printf("a的值大于1\n");
}
这两种情况是完全不同的,如果有多条代码在该分支里,一定要加上大括号{ }
2.if有多种形式
//可以是单if形式
if()
{
}
//也有if...else...形式
if()
{
}
esle
{
}
//if...else if... else...
if()
{}
else if()
{}
else
总之,有多少种分支情况,就可以有多少种if..else...
3.一些小注意
else只会与它最相近的if进行匹配,而不是按照对齐的if来匹配
int a = 3;
int b = 5;
if(a >= 2)
if(b >= 2)
a++;
else
b++: //这个else和哪个if匹配呢?
明显是与第二个if匹配的,所以语法上没问题,但逻辑上有问题了
还有就是if内表达式的判断
if(score < 60)
printf("不及格\n”);
if(score < 70)
printf("合格\n”);
if(score < 80)
printf("良好\n”);
if(score < 100)
printf("优秀\n”); //如果输入的成绩是95呢?
虽然是最简单的逻辑问题,但还是要小心在设置判断条件的时候不能让各种条件重叠了
switch语句:
在形式上比if语句更加直观,分支的逻辑更好
形式:
switch() //()内是表达式,表示分支的情况
{
case 0: //表示情况0
语句项;
break;
case 1: //表示情况1
语句项;
break;
case 2: //表示情况2
语句项;
break;
}
1.()只能是整型常量表达式,不能是浮点型
2.break语句是一定要配有的,配合break才能完成选择语句。不然会把选中情况后面的全部情况都执行一遍
int num = 2;
switch(num)
{
case 0:
printf("%d\n",num);
case 1:
printf("%d\n",num);
case 2:
printf("%d\n",num); //选中情况2后,执行完了,不会执行case 3
case 3:
printf("%d\n",num); //就会打印两行2
}
3.case 表达的情况选择不用是按照顺序来,可以随机。但不建议
4.default子句
表示所有的case中都没有选中的情况,既错误。为了防止出现漏洞后加上一个break;也可以加上提醒
int num = 4;
switch(num)
{
case 0:
printf("%d\n",num);
break;
case 1:
printf("%d\n",num);
break;
case 2:
printf("%d\n",num);
break;
case 3:
printf("%d\n",num);
break;
default:
printf("输入错误\n"); //这样就能防止num=4时没有任何显示了
break;
}
5.switch内也可以嵌套switch,语句项和break也不是必有项,按照自己的需要来写。只要能实现所需功能即可
二、循环语句
实现重复进行的操作,比较给一个很长的数组赋值,程序要一直运行
while循环
while() //只要()内的表达式为真,为非零表达式就会执行内部语句
{
}
1.若()内是1,那就是死循环,会一直执行,除非有break语句
while(1)
{
printf("嘿嘿\n"); //会一直打印嘿嘿
}
while(1)
{
int count = 0;
printf("嘿嘿\n");
count++:
if(count >= 100) //当打印了100个嘿嘿时,
break; //就会跳出while循环
}
for循环
for(表达式1;表达式2;表达式2)
{
语句项
}
表达式1是初始化,整个循环里只会执行一次;
表达式2是判断条件,每次重新循环时都会判断一次,判断条件成立里就循环;
表达式3 是增量条件,每次循环结束后都会执行一次;
1.表达式1最好要有,可能会出错
#include "stdio.h"
void main()
{
int j = 0;
int i = 0;
for(;i < 10; i++)
{
for(; j < 10; j++)
{
printf("123\n"); //这样打印多少个123?
}
}
}
只会打印10个123。因为当第二个for循环结束一次了,第二次进入时,j还是10,没有赋初值
2.没有表达式2就是死循环
#include "stdio.h"
void main()
{
int j = 0;
int i = 0;
for(i = 0;; i++)
{
printf("123\n"); //没有判断条件就为真,一直执行
}
}
3.表达式3可以放在语句项里但可能造成一些错误
4.一道坑人的题目
#include "stdio.h"
void main()
{
int i = 0;
int k = 0;
for(i =0,k=0; k=0; i++,k++) //循环几次?
k++;
}
0次
do while循环
do
{
语句项
}while(判断条件);
1.是先执行语句再进行判断的一种循环,与while插类似的
2.特点是do while至少会执行一次
break和continue与goto语句
break:是跳出当前的整个循环,只能跳出一个
continue:跳出当前次循环,不是会继续后面的循环
goto语句:跳转到指定的地方去。容易让顺序错乱,一般不用。但可以用于尝试嵌套里跳出多个嵌套使用
三、新学的一些库函数
putchar();
输出一个字符,参数是一个字符,或者一个字符变量;返回量是int类型
#include "stdio.h"
void main()
{
char a = 'A';
putchar(a);
} //屏幕上会出现一个 A
getchar();
从键盘上读取一个字符,返回它的asc码值;如果读取错误,返回EOF=end of flie,本质是-1
与scanf()不同,不会忽略回车,getchar也会读取,ctrl+z就是错误读取
Getchar() 和scanf()不是直接读取键盘的值,而是读键盘缓冲区的值,输入的值放在了键盘缓冲区,当有回车时,scanf读取,且不会读取回车\n,空格也不会读取并且停止读取,但getchar会。
#include "stdio.h"
void main()
{
char a; //写入一个字符,就会再显示相同的一个字符
a = getchar();
putchar(a);
}
读取一行:
#include "stdio.h"
void main()
{
char arr[20]={ 0 };
int i = 0;
char ch;
for(i = 0; i < 20 && (ch=getchar()) != EOF && ch != '\n'; i++)
arr[i] = ch;
arr[i] = '\0'; //给数组一个结束符
printf("%s\n",arr);
}
strcmp();
数组比较函数
返回整型,参数有两个,都 是char 类型的
当两个字符进行对比的时候,如果相等,就返回0;
比大小,比的是每个字符的ASCII码值,
#include "stdio.h"
#include "string.h"
void main()
{
char arr[20] = { 0 };
scanf("%s",arr); //由这得知,数组名也是地址,不用&
if(strcmp(arr,"hello")==0) //如果输入的是 hello
printf("对比成功\n"); //strcmp返回的就是0
else
printf("对比失败\n");
}
system();
执行系统命令
返回值好像也不用吧?参数是字符类型数据,就是命令
#include "stdio.h"
#include "stdlib.h"
void main()
{
printf("测试test\n");
system("cls"); //变化的很快
printf("再测试\n");
}
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
void main()
{
char input[20] = { 0 };
system("shutdown -s -t 60"); //系统命令窗口指令,设置定时关机
again:
printf("请注意,你的电脑将在一分钟内关机,除非输入:猪,将取消关机\n");
scanf("%s",input);
if (strcmp(input, "猪") == 0)
{
system("shutdown -a");
printf("关机取消");
}
else
goto again; //可以跳到again并且再执行后面的语句,平时很少用到
}
四、一点点思路
二分查找法:
在众多数据中找到一个所需的数据(在有序数组中),可以从头开始遍历,但是耗时太长。
则可以从中间找,再对比中间值与所需数据的大小,再来确定在哪个范围找。小了就往右找,大了就往左找。
#include "stdio.h"
//在一个有序数组中,找到一个数字x,并返回其下标
void main()
{
int v[] = { 1,2,3,4,5,6,7,8,9,10 };
int x = 12;
int i = 0;
int left = 0; //左右下标
int right = sizeof(v) / sizeof(v[0]); //用sizeof(v[0])获得一个数组元素的长度,再用总长度除以一个元素长度
while (left <= right)
{
int mid = (left + right) / 2;
if (v[mid] < x)
left = mid + 1; //数组元素的左下标向右移一个
else if (v[mid] > x)
right = mid - 1; //数组元素的右下标向左移一个
else
{
printf("找到了,下标是:%d\n", mid);
break; //这个break是要有的,不然程序会一直重复找到了
}
}
if (left > right)
printf("找不到");
}
辗转相除法:
(找两数最大公约数)
既两个数取余%,得到的不是0,那就将第二个数给第一个数,将余给第二个数,再取余下,直到余为0
#define _CRT_SECURE_NO_WARNINGS 1
#include "stdio.h"
void main()
{
int a, b;
int t;
scanf("%d %d", &a, &b);
while (a % b)
{
t = a % b;
a = b;
b = t;
}
printf("最大公约数是:%d\n", t);
}
其实我也没太懂,应该是从数学中过来的