顺序结构
选择结构
循环结构
定义:C语言中,由一个分号;隔开的就是一条语句
int a =0;
只有一个分号,也是一个语句,叫空语句
if
switch
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int age = 20;
if (age < 18)
printf("未成年\n");
return 0;
}
20——什么都不输出
18——输出未成年
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int age = 11;
if (age < 18)
printf("未成年\n");
else
printf("成年\n");
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int age = 100;
if (age < 18)
printf("未成年\n");
else if (age >= 18 && age < 28)
printf("青年\n");
else if (age >= 28 && age < 50)
printf("壮年\n");
else if (age >= 50 && age < 90)
printf("老年\n");
else
printf("晚年\n"); //最后这个else可以省略,也可以留着
return 0;
}
如果条件成立,要执行多条语句,就应该使用代码块
#include
int main()
{
if(表达式)
{
语句列表1;
}
else
{
语句列表2;
}
return 0;
}
这里的一对{}就是一个代码块
else和离它最近的未匹配的if进行匹配
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
//这个没有输出haha,因为else与第二个if匹配,由于第一个if表达式的条件为假,所以没有进入下面的语句
对上述进行改进,输出haha,这样就是一个好代码
#include
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
printf("haha\n");
}
else
printf("haha\n");
return 0;
}
或者什么都不输出
#include
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
代码1,代码可读性不是很强
if (condition){
return x;
}
return y;
//条件成立就返回x,不成立就返回y
代码2,更加容易读懂
if(condition)
{
return x;
}
else
{
return y;
}
代码风格
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
int main()
{
int num = 4;
if (num = 5)
{
printf("呵呵\n");
}
return 0;
}
//会输出呵呵,因为此处=给num赋值,而不判断相等,要判断相等应用 ==
将if那里改成if(5 == num)更优,将来判断常量与变量相不相等,应该把常量放到等号左边来判断
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
int main()
{
int i = 1;
while (i <= 100)
{
if (i % 2 == 1) //或者 if (i % 2 != 0)
printf("%d", i); //%d后面如果加上\n就换行
i++;
}
return 0;
}
也可以这样写
#include
int main()
{
int i = 1;
while (i <= 100)
{
printf("%d", i);
i+=2;
}
return 0;
}
//这就是算法,有的时候为了达到一种目的,我们可以有多种算法
不太好的例子
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int day = 0;
scanf("%d,&day");
if (1 == day)
printf("星期1\n");
else if (2 == day)
printf("星期2\n");
else if (3 == day)
printf("星期3\n");
else if (4 == day)
printf("星期4\n");
else if (5 == day)
printf("星期5\n");
else if (6 == day)
printf("星期6\n");
else if (7 == day)
printf("星期7\n");
return 0;
}
优化:当需要判断的选项较多时,使用多个 if 语句会使代码看起来冗长,不易维护。一个更好的方法是使用 switch 语句,可以简化代码并提高可读性。此外,可以添加一个默认情况来处理无法匹配的输入。
switch后面有一个括号,放一个整形表达式,这个整形表达式结果是几,它就从case几进去
switch判断,case作为一个入口进去,而从哪里出去,是由break决定的,break用来跳出switch语句
default:当你想选择的结构都不符合switch语句,后面的情况不再执行,default可有可无,处理非法,可以加上,后面什么都不写
编程好习惯:在每个switch语句中都放入一条default子句是一个好习惯,甚至可以在后面再加一个break
表达式必须是整形常量表达式
switch语句也是一种分支语句,常常用于多分支的情况,case决定入口,break决定出口
switch(整型表达式)
{
语句项
}
//是一些case语句
//如下:
case 整形常量表达式,不能是变量,能是1而不能是n
语句;
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期1\n");
break;
case 2:
printf("星期2\n");
break;
case 3:
printf("星期3\n");
break;
case 4:
printf("星期4\n");
break;
case 5:
printf("星期5\n");
break;
case 6:
printf("星期6\n");
break;
case 7:
printf("星期7\n");
break;
default:
printf("输入错误\n");
}
return 0;
}
while
for
do while
死循环打印hehe
#include
int main()
{
while (1)
printf("hehe\n");
return 0;
}
打印1-10
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int i = 1; //初始化
while (i <= 10) //判断
{
printf("%d ", i);
i++; //调整
}
return 0;
}
在上面printf上面加上
if (i==5)
break;
当执行到i = 5 时,循环就停止
作用:在循环中只要遇到break,就停止后期所有的循环,直接终止循环,所以while中的break是用于永久终止循环的
如果把break换成continue,按住F10进行调试,就陷入了死循环,卡到4就一直循环,当遇到5时就不往后走了,代码就不执行啦,作用结束本次循环continue后面的部分,回到循环条件处
作用:continue是用于终止本次循环的,也就是本次循环中的continue后边的代码不会执行,而是直接跳转到while语句的判断部分,进行下一次循环的入口判断
while表达式 循环语句
函数机制:
getchar()函数实际上是int getchar(void),所以它返回的是ASCII码,所以只要是ASCII码表里有的字符它都能读取出来。在调用getchar()函数时,编译器会依次读取用户键入缓存区的一个字符(注意这里只读取一个字符,如果缓存区有多个字符,那么将会读取上一次被读取字符的下一个字符),如果缓存区没有用户键入的字符,那么编译器会等待用户键入并回车后再执行下一步 (注意键入后的回车键也算一个字符,输出时直接换行)。
作用:接受键盘输入的字符,会把字符返回来,。下面把接收的字符放到ch里面,然后用putchar打印出来
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int ch = getchar();
putchar(ch);
printf("%c\n", ch);
return 0;
}
在while循环中的应用——代码1
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}
return 0;
}
//这里输ctrl+z可以停下来,-1也可以,因为是EOF的缘故,其他的不行
//这里输EOF也不会停止,因为系统看成是E,O,F
//ctrl+c是结束进程,ctrl+z是输入文件终止符
//EOF - end of file ->-1,文件结束标志
//只要输一个ctrl+z,getchar就能获取一个EOF,放到ch里面去
关于getchar() \n读取问题
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
/*int ch = 0;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}*/
int ret = 0;
char password[20] = {0};
printf("请输入密码:>");
scanf("%s", password);
//scanf把123456给拿走了,里面还有一个\n,就让getchar拿走了
//缓冲区还剩余一个‘\n'
//读取一下'n'
getchar(); //加上这个,把\n干掉
printf("请输入(Y/N):>" );
ret = getchar();
if (ret == 'Y')
{
printf("确认成功\n");
}
else
{
printf("放弃确认\n");
}
return 0;
}
while ((ch = getchar()) != '\n')实际应用价值
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
/*int ch = 0;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}*/
int ret = 0;
int ch = 0;
char password[20] = {0};
printf("请输入密码:>");
scanf("%s", password);
//scanf把123456给拿走了,里面还有一个\n,就让getchar拿走了
//缓冲区还剩余一个‘\n'
//读取一下'n'
while ((ch = getchar()) != '\n')
{
;
} 如果不加这个,当输入123456 abcd就会错误
printf("请输入(Y/N):>" );
ret = getchar();
//ret变量用于存储用户输入的字符,getchar函数用于从输入缓冲区中读取一个字符。
if (ret == 'Y')
{
printf("确认成功\n");
}
else
{
printf("放弃确认\n");
}
return 0;
}
chatgpt对上述代码的分析
scanf("%s", password):使用scanf函数读取用户输入的密码,由于%s会读取空格之前的字符,因此如果用户输入的密码中有空格,那么空格后面的内容将被舍弃。
while ((ch = getchar()) != '\n'):使用getchar函数读取输入缓冲区中的换行符,以避免该字符被下一次输入函数读取。
ret = getchar():使用getchar函数读取用户输入的确认信息。
如果输入123456 abcd,如果没有while ((ch = getchar()) != '\n')这段代码,那么程序会将abcd作为确认信息读取,并将其与Y进行比较,最终输出“放弃确认”。加上该代码段可以避免这种错误。
综上所述,这段代码的功能是接受用户输入的密码和确认信息,如果用户确认密码,则输出“确认成功”,否则输出“放弃确认”。
在输入"123456 abcd"时,scanf函数会把"123456"读取到password数组中,但它并不会读取空格或者其他非数字字符。因此,空格字符和"abcd"字符串会留在输入缓冲区中等待下一次输入函数读取。
在调用getchar函数时,它会从输入缓冲区中读取一个字符,包括空格字符和换行符,然后将其作为整数返回。在这个例子中,如果没有while ((ch = getchar()) != '\n')语句,程序会在下一个getchar函数调用时读取缓冲区中的空格字符,导致程序无法正常运行。
因此,为了避免这种情况,我们需要在读取确认信息之前调用一次getchar函数来读取输入缓冲区中的换行符,确保确认信息只包含单个字符,从而可以正常比较。
代码2
#include
int main()
{
while ((ch = getchar()) != EOF)
{
if (ch < '0' || ch >'9'
continue;
putchar(ch);
}
return 0;
}
//只打印字符0-字符9,其他内容不打印
for(表达式1;表达式2,表达式3)
循环语句;
初始化表达式:在循环开始之前执行一次,用于初始化循环控制变量。这个表达式通常用于给循环控制变量赋初始值,例如:int i = 0;。
条件表达式:在每次循环开始之前,判断循环是否继续执行。如果条件为真,则继续循环;如果条件为假,则跳出循环。例如:i < 10。//条件判断部分
更新表达式:在每次循环结束之后执行,用于更新循环控制变量的值。例如:i++,表示每次循环结束后,i 的值增加 1。 //调整部分
打印1-10的数字
#include
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
#include
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
//输出:1 2 3 4
#include
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
//输出:1234678910
不会死循环,此处与while不同,下面对比一下while循环,while会死循环,主要区别在开头
#include
int main()
{
int = 1;
while(i<=10)
{
printf("%d ",i);
i ++;
}
}
不可在for循环体内修改变量,防止for循环失去控制,比如在for循环内加个i =5
建议for语句的循环控制变量的取值采用"前闭后开区间"写法
在判断处最好写成i<10而非i<=9
#include
int main()
{
for(;;)
{
printf("hehe\n");
}
return 0;
}
for循环的初始化,判断,调整都可以省略,如果判断部分被省略,判断条件就是恒为真
如果不是非常熟练,建议不要随便省略
#include
int main()
{
int x,y;
for (x=0,y=0;x<2 && y<5; ++X,y++
{
printf("hehe\n");
}
下列循环要多少次
#include
int main()
{
int i = 0;
int k = 0;
for(i =0,k=0;k=0;i++,k++)
k++;
return 0;
}
//上面那个不是判断语句,而是把0赋值给了k,表达式结果是k的值,k的结果是0,0为假,那个地方就是假,意味着循环 压根就不进去
//因此循环0次
关于为假不被执行
在 C 语言中,条件语句(如 if、while、for 等)的判断都是基于条件表达式的值。如果该值为零,则视为假,否则视为真。
这是因为在 C 语言中,零值被视为“假”,非零值被视为“真”,这种约定俗成的规定被称为“真值测试”。
例如,在条件语句中,如果条件表达式的值为零,则被视为假,执行 else 分支(如果有的话)或跳过整个语句块;如果条件表达式的值为非零值,则被视为真,执行 if 分支(如果有的话)。
在这个问题中,条件表达式 k = 0 的值为 0,因此被视为假,循环体内的语句不会被执行。而如果条件表达式的值为非零值,就会被视为真,循环体内的语句就会被执行。
do
循环语句;
while(表达式);
chatgpt版:
do {
循环体语句;
} while (循环条件);
#include
int main()
{
int i = 1;
do
{
printf("%d", i);
i++;
}
while (i < 10);
return 0;
}
循环至少执行一次,使用场景有限,不经常使用
#include
int main() {
int i = 0;
int n = 0;
int ret = 1;
scanf("%d",&n);
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
printf("ret = %d\n", ret);
return 0;
}
#include
int main() {
int i = 0;
int n = 0;
int ret = 1;
int sum = 0;
for (n = 1; n <=3;n++)
{
ret = ret * n; //提高效率
//n的阶乘
sum = sum + ret;
}
printf("sum=%d\n", sum);
return 0;
}
#include
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
//写一个代码,在arr数组中(有序的)找到7
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i < 0; i < sz; i++)
{
if (k == arr[i])
{
printf("找到了,下标是:%d\n", i);
break;
}
}
if (i == sz)
printf("找不到\n ");
return 0;
}
//输出:找到了
//如果7那里改为17,就找不到
#include
int main()
{
int k = 7;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]); //计算元素个数
int left = 0; //左下标
int right = sz - 1; //右下标
while (left<=right)
{
int mid = (left + right) / 2; //根据下面随时调整
if (arr[mid] > k)
{
right = mid - 1;
}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
printf("找到了,下标是:%d\n", mid);
break;
}
}
if (left > right)
{
printf("找不到\n");
}
return 0;
}
上面int mid = (left + right) / 2;这行代码为什么不能写到while外面
可以将 int mid = (left + right) / 2; 这行代码写到 while 循环的外面,但这样做可能会导致程序的一些问题。因为在循环外面定义的变量 mid 的值只会在循环开始时计算一次,而在循环执行过程中,变量 left 和 right 的值可能会被修改,导致 mid 的值不再是数组中间的位置。这会导致程序无法正确地进行二分查找。
因此,将 int mid = (left + right) / 2; 这行代码放在 while 循环中,可以确保在每次循环开始时都重新计算数组的中间位置,以确保程序能够正确地进行二分查找。
#define _CRT_SECURE_NO_WARNINGS
#include
#include //引strlen等字符串函数
#include //引sleep
#include
#include //引system
#include
int main()
{
char arr1[] = "welcome to bit!!!!!!"; //数组元素个数不给定,用后面字符串去初始化它,字符串要求多少,数组就会开辟多少
char arr2[] = "####################"; //把#换成空格食用效果更佳
int left = 0;
//int right = sizeof(arr1) / sizeof(arr1[0] - 2); //上一个是数组,没有/0,这是个字符串,有,所以减2
int right = strlen(arr1)-1; //下标总是比元素个数少1,strlen遇到/0就停止,所以只需要-1
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
//休息一秒
Sleep(1000); //
//执行系统命令的一个函数 - cls清空屏幕
system("cls"); //
left++;
right--;
}
printf("%s\n", arr2);
return 0;
}
//好玩捏
注意 == 不能用来比较字符串是否相等,应该用strcmp函数
#define _CRT_SECURE_NO_WARNINGS
#include
#include //引strlen等字符串函数
#include //引sleep
#include
#include //引system
#include
int main()
{
int i = 0;
char password[20] = { 0 };
for (i = 0; i < 3; i++)
{
printf("请输入密码:>");
scanf("%s", password); //可以直接将数组名传递给scanf函数,而不需要取地址操作
if (strcmp(password , "123456") ==0 )
// ==不能用来比较两个字符串是否相等,应该使用一个库函数-strcmp,若前大于后,返回大于0的值
{
printf("登录成功\n");
break;
}
else
{
printf("密码错误\n");
//下面更人性化一点
Sleep(500); //
system("cls");//
}
}
if (i == 3)
printf("三次密码均错误,退出程序\n");
}