C语言笔记-4

C语言是结构化的程序语言

顺序结构

选择结构//

循环结构//

什么是语句?

一个分号隔开就是一个语句。


分支语言

选择结构

 if else

1.单分支,当表达式为1时,执行if内的语句,反之则跳过。

(注意,这里的1是C语言中为真的意思,当表达式里判断为真,则为1,反之为0,如果表达式是数字,0为0,非零默认为1)

if(表达式)

        语句;

 2.双分支,如果为1执行语句1,反之执行语句2。

if(表达式)

        语句1;

else

        语句2;

 3.多分支,n次判断,最后以else结尾,表示除了上述所有情况的其他情况。

if(表达式1)

        语句1;

else if(表达式2)

        语句2;

……

else if(表达式n)

        语句n;

else

        语句n+1;

//注意,当代码块中,如果语句只有一行,可以直接写下,如果有多行,需要在左右写上大括号{}

 一个{}就是一个代码块。

#include<stdio.h>

int main()
{
	int a = 0;
	scanf("%d", &a);
	if (a < 50)
		printf("第一种:a<50\n");
	if (a < 50)
		printf("第二种:a<50\n");
	else
		printf("第二种:a>=50\n");

	if (a < 50)
		printf("第三种:a<50\n");
	else if (a == 50)
		printf("第三种:a=50\n");
	else
		printf("第三种:a>50\n");
	return 0;
}

逻辑或、与、非

||        &&        !        双目运算符,或与非,可以用于多个判断语句

#include<stdio.h>

int main()
{
	int a = 0;
	scanf("%d", &a);
	if (a < 100 && a>50)
	{
		printf("a在100到50之间\n");
		printf("a的值为真");
	}

	else if (a > 0 || a < 0)
		printf("a的值为真");
	else if (!a)
		printf("a的值为假");

	return 0;
}

 悬空else(if else中的else匹配问题)

#include<stdio.h>

int main()
{
	int a = 20;
	if (a < 19)
		if (a > 0)
			printf("a>0");
	else
			printf("a>=19");

	return 0;
}

这里的else 优先匹配最近的if

//小技巧

在表达式中,如果判断是否等于,格式如下

if( a == 1)

在这里,有可能会出现写漏的情况,

if( a = 1 ) 

这种写法编译器并不会报错,因为这里a被赋值1,表达式直接为真。

所以为了保证不会写错写漏,我们可以用以下格式

 if(1 == a)

这里和if(a == 1)效果一样,==双目运算符判断符号两边的值并返回0或者1。所以这不会报错。


switch 

分支语句,主要用于多分支场景

switch(整型表达式)//表达式必须是整型

{        

        case 整型常量表达式;//必须是常量

                语句;

       ……

}

#include<stdio.h>

int main()
{
	int a = 0;
	scanf("%d", &a);
	switch (a)
	{
	case 1:
	{
		printf("星期一");
	}
	case 2:
	{
		printf("星期二");
	}
	case 3:
		printf("星期三");
		break;//如果不适用语句块,则需要break手动跳出
	case 4:
		printf("星期四");//否则就会继续执行下一行代码。
	case 5:
	{
		printf("星期五");
	}
	default://除了上述情况的其他所有情况
		printf("\n没有这一天");
		break;
	}
	return 0;
}

通过case的特性,我们能够判断某值到某值,然后执行语句。

#include<stdio.h>

int main()
{
	int a = 0;
	scanf("%d", &a);

	switch (a)
	{
	case 1:
	case 2:
	case 3:
	case 4:
		printf("\n工作日");
		//当你输入1到4之间的值时,他会从你这个值进入,然后顺序到4并执行语句
		break;
	case 5:
	case 6:
	case 7:
		printf("\n休息日");
		break;
	default://除了上述情况的其他所有情况
		printf("\n没有这一天");
		break;
	}
	return 0;
}

循环语句

while

while(表达式)

        循环语句;

#include<stdio.h>

int main()
{

	int a = 0;
	int i = 0;
	scanf("%d", &a);
	while (i <= a)
	{
		printf("%d\n", i);
		i++;
	}
	return 0;
}

break

永久终止循环

#include<stdio.h>

int main()
{

	int a = 0;
	int b = 0;
	int i = 0;
	scanf("%d%d", &a, &b);
	while (i <= a)
	{
		printf("%d\n", i);

		if (b == i)
		{
			break;//永久终止循环
		}
		i++;
	}
	return 0;
}

continue

跳过本次循环

#include<stdio.h>

int main()
{

	int a = 0;
	int b = 0;
	int i = 0;
	scanf("%d%d", &a, &b);
	while (i < a)
	{

		i++;//continue下,i++要在continue前,否则i++被跳过,值不变,会形成死循环
		if (b == i)
		{
			continue;//跳过本次循环
		}
		printf("%d\n", i);
	}
	return 0;
}

 getchar()、putchar函数

#include<stdio.h>
int main()
{
	char a;
	while ((a = getchar()) != EOF)//这里翻译为,输入一个字符,如果这个字符没错就执行循环语句
	{
		putchar(a);
		if ('#' == a)
			break;
	}
	return 0;
}

 注意,getchar是读取缓冲区的字符,所以如果缓冲区有多个字符,getchar也只会一个一个读取。

而且,getchar也会读取回车键

 类似于getchar和scanf之类的读取函数,他们读取并不是直接读取键盘,而是找缓冲区。

键盘输入的字符都会存在缓冲区再由程序读取。

#include<stdio.h>
int main()
{
	printf("请输入密码:");
	char password[30];
	scanf("%s", password);//数组的数组名就是它的地址。
	printf("\n请确认密码:%s(Y/N?):", password);
	char n = getchar();//获取\n
	int b = getchar();
	if (b == 'Y')
	{
		printf("\n已确认!");
	}

	return 0;
}

上述代码中,n的值就是被获取的\n 

 如果没有这条回收回车符,则b会直接获取缓冲区的回车符。

 因为b是整型,所以这里'\n'被强制转换成整型。

因为scanf函数一次只读取到空格就结束:

所以当我输入的密码有空格,一个getchar只能清理一个字符。 

所以我们需要另一个方法来清理缓存。

int emp;
	while ((emp = getchar()) != '\n')
	{
		;//什么都不执行,但上述表达式里执行了getchar,获取了缓冲区的字符。
	}

 通过getchar循环到回车符,每一次循环就使用一次getchar获取缓存区字符来达到清理缓存区的目的。

for

基本语法:

for(表达式1;表达式1;表达式1)

        循环语句;

表达式1:初始化

表达式2:判断

表达式3:调整

#include<stdio.h>
int main()
{
	int a = 10;
	for (int i = 0; i <= a; i++)
	{
		printf("%d\t", i);
	}
	return 0;
}

执行流程:表达式1->表达式2->判断是否->是(循环语句)-表达式3-表达式2->

                                                                    ->否(结束循环) 

for的break和continue

break效果一致,continue里,不同于while循环跳过了i++,for循环的i++不会被跳过。 

 循环体内不建议改变控制变量

do while

格式;

do{

循环语句;

}whlie(表达式);

 和while与for循环不同,do while是 先执行一次循环语句,再执行判断。、

计算

输入一个数字,计算从0开始到这个值得阶乘和。

#include<stdio.h>
int main()
{
	//int a = 0;
	//scanf("%d", &a);
	//int i;
	//int j;
	//int k = 0, u = 1;
	//for (i = 1; i <= a; i++)
	//{
	//	u = 1;
	//	for (j = 1; j <= i; j++)
	//	{
	//		u *= j;
	//	}
	//	k += u;
	//}
	int n;//另一种方法
	scanf("%d", &n);
	int a = 1;
	int k = 0;
	for (int i = 0; i < n; i++)
	{
		a *= i + 1;
		k += a;
	}

	printf("%d", k);

	return 0;
}

算法不同,时间复杂度也各不相同。  

 算法:二分法

当我们要在数组中查找某个值时,传统方法是遍历整个数组来查找,但如果数组过大,这种方法的时间复杂度也很大,所以有一种方法能减少其时间复杂度:二分法

二分法顾名思义,我们通过循环,每次循环取左右两侧的中间下标并进行对比,如果值大于中间下标的值,则将二分范围改为右侧,反之同理。

#include<stdio.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int n = 11;
	int sz = sizeof(arr) / sizeof(arr[0]);//元素的个数
	//sizeof(arr)是整个数组的大小,sizeof(arr[0])是数组中单个下标所占的大小

	//初始化
	int left = 0;
	int right = sz - 1;//找的是最右侧的下标


	while (left <= right)
		//每次循环,左右两侧下标逐渐靠拢
		//当其交叉而过时,说明要找的数值不在数组中
	{
		//一次二分查找
		int mid = (left + right) / 2;//取中间值,因为是int类型,所以小数位会被省略
		if (arr[mid] < n)
		{
			left = mid + 1;
			//查找的值下标在中间下标的右侧且不等于mid,所以左侧下标向右移动到mid的右一位
		}
		else if (arr[mid] > n)
		{
			right = mid - 1;//同理
		}
		else
		{
			printf("\n位置在arr[%d] = %d", mid, arr[mid]);
			break;
		}

	}
	if (right < left)
	{
		printf("没找到");
	}
	return 0;
}

Sleep(1000),让程序暂停一段时间,单位毫秒,这里暂停了1s

system("cls");用于清空当前控制台屏幕。 

都需要包含windows.h头文件:#include<windows,h>

strlen()函数,判断字符串长度

strcmp(a,b)对比字符串a和b,

a大于b则返回值大于0,a小于b则返回值小于0,a等于b则返回值等于0

都要包含<string.h>头文件

goto语句

格式

goto 位置;

 

位置:

        后续代码;

        ……

#include<stdio.h>
#include<string.h>
#include<Windows.h>
void mue()
{
	printf("#########################\n");
	printf("##########菜单###########\n");
	printf("#########1.NULL##########\n");
	printf("#########2.NULL##########\n");
	printf("#########3.退出##########\n");
	printf("#########################\n");
	int n;
	scanf("%d", &n);
	inter(n);
}
int inter(int n)
{
	switch (n)
	{
	case 1:
		break;
	case 2:
		break;
	case 3:
		return 0;
	default:
		printf("输入错误,请重新选择");
		Sleep(2000);
		system("cls");
		mue();
		break;
	}
}
int main()
{
	char password[10] = { 0 };
	int i = 0;
	while (1)
	{
		printf("请输入密码:");
		scanf("%s", password);
		if (strcmp(password, "1633326794") == 0)
		{
			goto exit;
		}
		else
		{
			printf("\n密码错误,请重新输入\n");
			i++;
			Sleep(1000);
			system("cls");
		}
		if (3 == i)
		{
			printf("\n超过3次,退出程序");
			return 0;
		}
	}
	printf("被跳过的部分");
exit:
	printf("密码正确\n");
	Sleep(2000);
	system("cls");
	mue();

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值