C语言学习3

一.printf和scanf介绍

1.printf

1.1printf的基本用法

作用:将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以定制输出⽂本的格式。

#include<stdio.h>
int main()
{
	printf("hello,\nworld\n");
	return 0;
}

printf() 不会在⾏尾⾃动添加换⾏符,运⾏结束后,光标就停留在输出结束的地⽅,不会⾃动换⾏。
可添加\n使光标移到下一行,位于文本中间可使两侧换行;
在这里插入图片描述
printf() 是在标准库的头⽂件 stdio.h 定义的。使⽤这个函数之前,必须在源码⽂件头部引⼊这个头⽂件。

1.2占位符

printf() 可以在输出⽂本中指定占位符。
所谓 “占位符”,就是这个位置可以⽤其他值代⼊。

#include<stdio.h>
int main()
{
	printf("%d\n", 666);
	return 0;
}

%d即为占位符,其替666占位,在运行使将666代入
占位符的第⼀个字符⼀律为百分号 % ,第⼆个字符表⽰占位符的类型, %d 表⽰这⾥代⼊的值必须是⼀个整数。
printf() 的第⼆个参数就是替换占位符的值
输出⽂本⾥⾯可以使⽤多个占位符。

#include<stdio.h>
int main()
{
	printf("%s don't love %s\n","your lover","you");
	return 0;
}

在这里插入图片描述
%s 表⽰代⼊的是⼀个字符串

printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符, printf() 的参数就应该有 n + 1 个。
上面”your lover“和”you“以及”%s don’t love %s\n“为参数。其对应两个占位符即两个%s。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。

在这里插入图片描述

1.3占位符列举

• %a :⼗六进制浮点数,字⺟输出为⼩写。
• %A :⼗六进制浮点数,字⺟输出为⼤写。
• %c :字符。
• %d :⼗进制整数。// int

• %e :使⽤科学计数法的浮点数,指数部分的 e 为⼩写。
• %E :使⽤科学计数法的浮点数,指数部分的 E 为⼤写。
• %i :整数,基本等同于 %d 。
• %f :⼩数(包含 float 类型和 double 类型)。//float %f double - %lf
• %g :6个有效数字的浮点数。整数部分⼀旦超过6位,就会⾃动转为科学计数法,指数部分的 e
为⼩写。
• %G :等同于 %g ,唯⼀的区别是指数部分的 E 为⼤写。
• %hd :⼗进制 short int 类型。
• %ho :⼋进制 short int 类型。
• %hx :⼗六进制 short int 类型。
• %hu :unsigned short int 类型。
• %ld :⼗进制 long int 类型。
• %lo :⼋进制 long int 类型。
• %lx :⼗六进制 long int 类型。
• %lu :unsigned long int 类型。
• %lld :⼗进制 long long int 类型。
• %llo :⼋进制 long long int 类型。
• %llx :⼗六进制 long long int 类型。
• %llu :unsigned long long int 类型。
• %Le :科学计数法表⽰的 long double 类型浮点数。
• %Lf :long double 类型浮点数。
• %n :已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。
• %o :⼋进制整数。
• %p :指针(⽤来打印地址)。
• %s :字符串。
• %u :⽆符号整数(unsigned int)。
• %x :⼗六进制整数。
• %zd : size_t 类型。

• %% :输出⼀个百分号。

注:%f和%lf在打印的时候,小数点后默认是打印6位。

1.4输出格式

1.4.1限制宽度

printf() 允许限定占位符的最⼩宽度。
上⾯⽰例中, %5d 表⽰这个占位符的宽度⾄少为5位。如果不满5位,对应的值的前⾯会添加空格。输出的值默认是右对⻬,即输出内容前⾯会有空格;如果希望改成左对⻬,在输出内容后⾯添加空格,可以在占位符的 % 的后⾯插⼊⼀个 - 号。在这里插入图片描述
在这里插入图片描述
对于⼩数,限定符%xlf会限制所有数字的最⼩显⽰宽度。x为整数

1.4.2总是显示正负号

默认情况下, printf() 不对正数显⽰ + 号,只对负数显⽰ - 号。如果想让正数也输出 + 号,可以在占位符的 % 后⾯加⼀个 + 。

1.4.3限定小数位数

输出⼩数时,有时希望限定⼩数的位数。举例来说,希望⼩数点后⾯只保留*位,占位符可以写成 %.*f
这种写法可以与限定宽度占位符,结合使⽤。
在这里插入图片描述
最⼩宽度和⼩数位数这两个限定值,都可以⽤ * 代替,通过 printf() 的参数传⼊。
在这里插入图片描述

1.4.4输出部分字符串

%s 占位符⽤来输出字符串,默认是全部输出。如果只想输出开头的部分,可以⽤ %.[m]s 指定输出的⻓度,其中 [m] 代表⼀个数字,表⽰所要输出的⻓度。
在这里插入图片描述

2.scanf

即给变量输⼊值

#include <stdio.h>
int main()
{
	int score = 0;
	printf("请输入成绩:");
	scanf("%d", &score);//输入操作
	//scanf函数中占位符的后边的参数需要的是地址
	//&  取地址操作符。&score-取出score的地址
	printf("成绩是%d\n", score);
	return 0;
}

2.1基本用法

scanf() 函数⽤于读取⽤⼾的键盘输⼊。
程序运⾏到这个语句时,会停下来,等待⽤⼾从键盘输⼊。
⽤⼾输⼊数据、按下回⻋键后, scanf() 就会处理⽤⼾的输⼊,将其存⼊变量。
它的原型定义在头⽂件 stdio.h 。
scanf() 的语法跟 printf() 类似。

scanf(“%d”,&i)
的第⼀个参数 %d ,表⽰⽤⼾输⼊的应该是⼀个整数。 %d 就是⼀个占位符, % 是占位符的标志, d 表⽰整数。第⼆个参数 &i 表⽰,将⽤⼾从键盘输⼊的`#include <stdio.h>
int main()

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	float c = 0.0;
	float d = 0.0;
	scanf("%d,%d,%f,%f", &a, &b, &c, &d);
	printf("%d,%d,%f,%f",a,b,c,d);
	return 0;
}

2.2scanf的返回值

scanf() 的返回值是⼀个整数,表⽰成功读取的变量个数。
如果没有读取任何项,或者匹配失败,则返回 0 。
如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量 EOF (-1)。

2.3占位符

scanf() 常⽤的占位符如下,与 printf() 的占位符基本⼀致。

• %c :字符。
• %d :整数。
• %f : float 类型浮点数。
• %lf : double 类型浮点数。
• %Lf :long double 类型浮点数。
• %s :字符串。
• %[]:在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9]),遇到不在集合之中的字符,匹配将会停⽌。

上⾯所有占位符之中,除了 %c 以外,都会⾃动忽略起⾸的空⽩字符。 %c 不忽略空⽩字符,总是返
回当前第⼀个字符,⽆论该字符是否为空格。
如果要强制跳过字符前的空⽩字符,可以写成 scanf(" %c", &ch) ,即 %c 前加上⼀个空格,表⽰跳过零个或多个空⽩字符。

二.分⽀和循环

C语⾔是结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构。
C中用if 、 switch 实现分⽀结构,使⽤ for 、 while 、 do while 实现循环结构

1. if语句

1.1语法格式

if(表达式)
… 语句

表达式成⽴(为真),则语句执⾏,表达式不成⽴(为假),则语句不执⾏。在C语⾔中,0为假,⾮0表⽰真,也就是表达式的结果如果是0,则语句不执⾏,表达式的结果如果为非0,则语句执⾏。
在这里插入图片描述
在这里插入图片描述
判断是否为奇数

int main()
{
	int num = 0;
	printf("请输入\n");
	scanf("%d", &num);
	if (num % 2 == 1)
		printf("%d 为奇数", num);


	return 0;
}

1.2.else

1.2.1if…else… 语句

语法形式:

if(表达式)
语句1
else
语句

int main()
{
	int num = 0;
	printf("请输入\n");
	scanf("%d", &num);
	if (num % 2 == 1)
		printf("%d 为奇数", num);
	else
		printf("tban");

	return 0;
}

1.3.分⽀中包含多条语句

默认在 if 和 else 语句中默认都只控制⼀条语句。
如果要if语句同时控制2条语句,就要使⽤ {} 将代码括起来,else 后也可以跟上⼤括号。

int main()
{
	int age = 0;
	printf("请输入年龄:\n");
	scanf("%d", &age);
	if (age >= 18)
	{
		printf("你已经成年,可以恋爱!!!\n");
		printf("狗屎\n");
	}
	else
		printf("去学习吧");
	return 0;
}

1.4.嵌套if

在 if else 语句中, else 可以与另⼀个 if 语句连⽤,构成多重判断。

#include <stdio.h>
int main()
{
 int num = 0;
 scanf("%d", &num);
 if(num == 0)
 printf("输⼊的数字是0\n");
 else if(num > 0) //这⾥的if 相当于嵌套在else语句中,形成了嵌套结构
 printf("输⼊的数字是正数\n");
 else
 printf("输⼊的数字是负数\n");
 
 return 0;
}

注:如果有多个 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近的 if 匹配

2.逻辑操作符

&& , || , !三种逻辑运算符提供逻辑判断功能,⽤于构建更复杂的表达式。
• ! :逻辑取反运算符(改变单个表达式的真假)。
• && :逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
• || :逻辑或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。

3.短路

C语⾔逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值。如果左边的表达式满⾜逻辑运算符的条件,就不再对右边的表达式求值。

if(month >= 3 && month <= 5)
表达式中&& 的左操作数是 month >= 3 ,右操作数是 month <= 5 ,当左操作数 month >= 3 的结果是0的时候,即使不判断 month <= 5 ,整个表达式的结果也是0,所以,对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执⾏。

4.switch语句

switch 语句是⼀种特殊形式的 if…else 结构,⽤于判断条件有多个结果的情况。它把多重的 else if 改成更易⽤、可读性更好的形式。

switch (expression) {
case value1: statement
case value2: statement
default: statement
}

switch 后的 expression 必须是整型表达式
case 后的值,必须是整形常量表达式

但要在每个case语句结束后写上break

int main()
{
	int a = 0;
	scanf("%d", &a);
	switch (a % 3)
	{
	case 0:
		printf("余数为0\n");
		break;
	case 1:
		printf("1\n");
		break;
	case 2:
		printf("2\n");
		break;
	}
	return 0;
}

只有在 switch 语句中使⽤ break 才能在跳出 switch 语句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续往下执⾏,有可能执⾏其他 case语句中的代码,直到遇到 break 语句或者 switch 语句结束。就⽐如上⾯的代码就执⾏了 case。
在使⽤ switch 语句的时候,switch 后的表达式中的值⽆法匹配代码中的 case 语句的时候可以不做处理,也在 switch 语句中加⼊default ⼦句。

switch (expression) {
case value1: statement
case value2: statement
default: statement
}

switch 后边的 expression 的结果不是 value1 ,也不是 value2 的时候,就会执⾏default ⼦句。

5.while语句

语法格式:

while(表达式)
语句;//如果循环体想包含更多的语句,可以加上⼤括号

int main()
{
	int n = 0;
	scanf("%d", &n);
	while (n) {
		printf("%d", n % 10);
		n = n / 10;
	}
	return 0;
}

6.for循环

语法格式

for(表达式1; 表达式2; 表达式3)
语句;//如果循环体想包含更多的语句,可以加上⼤括号
表达式1 ⽤于循环变量的初始化
表达式2 ⽤于循环结束条件的判断
表达式3 ⽤于循环变量的调整

int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++) {
		printf("%d", i);
	}
	return 0;
}

7.while和for语句的对比

for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分⾮常集中,便于代码的维护,⽽如果代码较多的时候 while 循环的三个部分就⽐较分散,所以从形式上 for 循环要更优⼀些。

8.do…while语句

语法格式:

do
语句;
while(表达式);

int main()
{
	int i = 0;
	do
	{
		printf("%d", i);
		i++;
	} while (i <= 10);
	return 0;
}

在 do while 语句中循环体是⾄少执⾏⼀次的,这是 do while 循环⽐较特殊的地⽅。
注:while 和 for 这两种循环都是先判断,条件如果满⾜就进⼊循环,执⾏循环语句,如果不满⾜就跳出循环;⽽ do while 循环则是先直接进⼊循环体,执⾏循环语句,然后再执⾏ while 后的判断表达式,表达式为真,就会进⾏下⼀次,表达式为假,则不再继续循环

9.break和continue

在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环。而C语⾔中提供了 break 和 continue 两个关键字来处理。
• break 的作⽤是⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,继续往后执⾏。
• continue 的作⽤是跳过本次循环中 continue 后边的代码,在 for 循环和 while 循环中有所差异的。
.

9.1break

int main()
{
	int a = 0;
	while (a <= 10)
	{
		if (a == 5)
			break;
		printf("%d\n", a);
		a++;
	}
	return 0;
}

打印了1,2,3,4后,当a等于5的时候,循环在 break 的地⽅终⽌,不再打印,不再循环。所以在循环中,想在某种条件下终⽌循环,则可以使⽤ break 来完成我们想要的效果。

9.2continue

9.2.1while中的continue

在这里插入图片描述
continue 可以帮助我们跳过某⼀次循环 continue 后边的代码,直接
到循环的判断部分,进⾏下⼀次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。
调换位置后结果也不同。
在这里插入图片描述

9.2.2for中的break和continue

和 while 循环中的 break ⼀样, for 循环中的 break 也是⽤于终⽌循环的,不管循环还需要循环多少次,只要执⾏到了 break ,循环就彻底终⽌
在这里插入图片描述
在 for 循环中 continue 的作⽤是跳过本次循环中 continue 后的代码,直接去到循环的调整部分。未来当某个条件发⽣的时候,本次循环⽆需再执⾏后续某些操作的时候,就可以使⽤continue 来实现。
在这里插入图片描述

9.2.3do…while的break和continue

do.while 语句中的 break 和 continue 的作⽤和 while 循环中⼏乎⼀模⼀样

#include <stdio.h>
int main()
{
 int i = 1;
 do
 {
 if(i == 5)
 break;
 printf("%d ", i);
 i = i + 1;
 }while(i<=10);
  return 0;
}
`

```c
#include <stdio.h>
int main()
{
 int i = 1;
 do
 {
 if(i == 5)
 continue;
 printf("%d ", i);
 i = i + 1;
 }while(i<=10);
  return 0;
}

10.循环的嵌套

找出100~200之间的素数,并打印在屏幕上。
注:素数⼜称质数,只能被1和本⾝整除的数字。

#include<math.h>
int main()
{
	int i = 0;
	int count = 0;
	for (i = 100; i <= 200; i++)
	{
		int flag = 1;
		int n = 0;
		for (n = 2; n <= sqrt(i); n++)
		{
			if (i % n == 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag == 1)
		{
			count++;
			printf("%d ", i);
		}
	}
	printf("\n %d \n", count);
	return 0;
}

11.goto语句

goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。

int main()
{
	printf("haha\n");
	if (1)
		goto end;
	printf("hehe\n");
end:
	printf("eawn");
	return 0;
}

goto 语句
缺点:如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程
优点:本来 for 循环想提前退出得使⽤ break ,⼀个 break 只能跳出⼀层 for 循环,如果3层循环嵌套得使⽤3个 break 才能跳出循环,所以在这种情况下我们使⽤ goto 语句就会更加的快捷。

三.实践

猜数字游戏
1.电脑自动生成1-100的随机数。
2.玩家猜数字,猜数字的过程中,根据猜测数据的大小给出大了或者小了的反馈,直到猜对,游戏结束。

1.rand函数

C语⾔提供了⼀个函数叫 rand,这函数是可以⽣成随机数的,函数原型如下所⽰:

int rand (void);

但运行几次后发现,结果是相同的。
在这里插入图片描述

原因是:

  1. rand函数会返回⼀个伪随机数,这个随机数的范围是0~RAND_MAX之间,这个RAND_MAX的⼤⼩是依赖编译器上实现的,但是⼤部分编译器上是32767。

  2. rand函数的使⽤需要包含⼀个头⽂件是:stdlib.h

  3. .rand函数⽣成的随机数是伪随机的,伪随机数不是真正的随机数,是通过某种算法⽣成的随机数。真正的随机数的是⽆法预测下⼀个值是多少的。⽽rand函数是对⼀个叫“种⼦”的基准值进⾏运算⽣成的随机数。

2.srand

C语⾔中⼜提供了⼀个函数叫 srand,⽤来初始化随机数的⽣成器的,srand的原型如下:

void srand (unsigned int seed);

在这里插入图片描述

在这里插入图片描述
所以得让给srand的种子随机,rand的就能生成随机数

3.time

在程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的。 在C语⾔中有⼀个函数叫 time ,就可以获得这个时间,time函数原型如下:

time_t time (time_t* timer)

time 函数会返回当前的⽇历时间,其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的
差值,单位是秒。返回的类型是time_t类型的,time_t 类型本质上其实就是32位或者64位的整型类
型。
time函数的参数 timer 如果是⾮NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存
中带回去。
如果 timer 是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳
time函数的时候需要包含头⽂件:time.h

4.实现

#include<stdlib.h>
#include<stdio.h>
#include<time.h>
`void menu()
{
	printf("***********************");
	printf("*********   1.play   *********");
	printf("*********   0.exit   ********");
	printf("***********************");
}
void game()
{
	
	int r = rand() % 100 + 1;

	
	int guess = 0;
	while (1)
	{
		printf("请猜数字:");
		scanf("%d", &guess);
		if (guess > r)
		{
			printf("da\n");
		}
	
		else if (guess < r)
		{
			printf("xioale\n");
		}
		else
		{
			printf("duile\n");
			break;

		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
	
		menu();

	
		printf("请选择:");
	
        scanf("%d", &input);
		switch (input)
		{
		case 1:
			
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误,重新选择");
			break;
		}
	} while (input);

	return 0;
}

结果是
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值