Bootstrap

C语言之旅3--(你很了解printf函数和scanf函数吗?)--分支和循环【0】

printf函数和scanf函数介绍!!!

  • printf函数:这个函数,我们在之前的文章里见过了。那在本章中,我们进行详细的讲解。printf的全名是:print—formate—打印格式。在屏幕上进行信息的打印(输出信息)。
    • printf的打印: 我们在之前有见过它的打印格式。比如,printf("Hello,World");printf("%d ", 5);。前面一种的方式,是进行字符串的打印。当打印字符串的时候,直接用" "括起来或者用%s这个占位符进行打印都一样(只限于字符串打印)。那么,什么是占位符呢?别急,现在介绍。
    • 占位符的介绍:这玩意儿,从表面就能理解其意思——就是给人家提前占个位置。比如,printf("Hello World");==printf("%s","Hello World");前面,咱们已经讲过了字符' '和字符串" "的打印(忘了的同学,回前面补习去)。%s就是一个占位符,是专门用来打印字符串的占位符。 打印不同的信息时,就用对应着不同的占位符。用占位符进行打印的格式printf("占位符",要打印的信息)当打印字符串的时候,不用占位符直接打印和用占位符进行打印是一样的(就像上面举的例子)。只有字符串才可以这样,别的可不行。 进行代码展示:
printf("%d" , 5);			//整数占位符,打印整数的
printf("%c" ,' c');			//字符占位符,打印字符的
printf("%c" , '5');
printf("%f" , 5.6);			//小数占位符,打印小数的
  • C语言中的占位符(黑色加重为常用的)在这里插入图片描述在这里插入图片描述
    这里不需要都要记住,目前只需要记住黑色加重的部分,至于其它部分,用的时候查一下就OK。
  • 占位符的使用: 我们想打印几个数据就用多少个占位符,还可以混用占位符进行打印信息。如代码所示:
printf("%d %d\n ",5,6);
printf("%d %c\n",5,'a');
printf("%d %s\n",5,"hello world");    //printf函数不会自动换行,所以为了美观,需要我们手动添加换行--\n

运行结果图;在这里插入图片描述
从上面的代码中,我们可以看出来,printf函数的参数个数比所使用的占位符个数多一。(参数:函数内,每一个逗号就代表一个参数。)。不知道各位有没有看出来,我们在两个占位符之间加了空格,结果输出就有空格。我们在"占位符"内,无论样输入空格,结果就跟我们所输入的一模一样,如代码所示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	/*printf("%d %d\n ", 5, 6);
	printf("%d %c\n", 5, 'a');
	printf("%d %s\n", 5, "hello world");*/
	printf("%d%d\n ", 5, 6);
	printf("%d             %d\n ", 5, 6);

	return 0;
}

运行结果图:在这里插入图片描述

  • printf函数输出数据的宽度限制:不同的占位符限制宽度大同小异
  • %d%s的数据宽度限制%d之间加上数字,%s之间加上点和数字就进行了限制,比如,%5d ,%.5s.对于整数和字符串的作用效果不同。对于整数而言,不会限制其输出位数,因为整数本身就是一个整体,限制不了,它的数字代表它的最少位,当数据位数,超过你所写的数字位数时,就啥事没有,正常输出,但当数据位数少于你所写的数字位数时,会对其位数进行补充,直至满足你所写的位数。而字符串就恰恰相反,当字符串超出你所写的数字宽度时,它就输出宽度范围内的,当字符串少于你所写的数字宽度时,它就全部输出。总结:对于整数而言,数字宽度是它的下限。对于字符串而言,数字宽度是它的上限 进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	printf("-----\n");
	printf("%5d\n", 5);
	printf("%.3s\n", "-----");
	return 0;
}

结果运行图:在这里插入图片描述
不知道大家从结果运行图中有没有看出来,%5d中,由于咱们的位数不够,所以它就进行补位,但我们能发现,它补的位偏左(从右边对齐,向左进行补位)。这就要讲到一个新的知识点了——那就是在%d之间加上+-,会影响最后,是向左对齐开始补位,还是向右对齐开始补位。加+或者不加(不加的话,系统默认就是右对齐),就是右对齐,向左开始补齐。反之,加-就是左对齐,向右开始补齐。如代码所示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	printf("%s\n", "------");
	printf("%6d\n", 5 );		//右对齐
	printf("%-6d\n", 5);		//左对齐
	return 0;
}

结果运行图:在这里插入图片描述

  • %d的符号:我们前面都见过,我们进行打印正整数时,都是打印5,6,7这些数字。当然,在我们日常生活中,我们写正整数的时候,也不带+号(省略不写了),C语言中也是省略不写,我们为了想带个正号时,就可以在%d之间加个+这里加不加+对负数没有影响。 如代码所示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	printf("%d\n", 5);		// 默认不带+号
	printf("%+d\n", 5);		// 带了+号
	printf("%+d\n", -5);	//对负数没有影响
	return 0;
}

结果运行图:在这里插入图片描述

  • %f的数据宽度控制:有时候我们不需要输出太多的小数位,这个时候就需要进行限位。%f之间加上.数字就可以限制小数点后面的位数,然后会四舍五入。比如,%.3f就是限制小数点后三位,满足四舍五入就近一,不满足就舍弃。如代码所示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	printf("%f\n", 5.789);       //可以看出来,有限制小数位的作用
	printf("%.2f\n", 5.789);
	return 0;
}

运行结果图:在这里插入图片描述
我们还可以限制整个小数的位数(这里小数点也算进去),比如,%5.3f点前面的数字表示限制整个小数的位数(小数点也算哟),点后面就是限制小数点后面的位数。限制小数整体的位数跟%d的原理一样的(可以参考)-----不够就给你补齐,超了就全部输出。如代码所示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	printf("%f\n", 5.789);       //可以看出来,有限制小数位的作用
	printf("%.2f\n", 5.789);
	printf("%10.2f\n", 5.789);     //总共10位数据,不够就给你补齐。
	return 0;
}

结果运行图:在这里插入图片描述
前面咱们所写的%5d,%.5s,%.6f,%5.6f,中的数字可以用*来替代,比如,printf("%5d\n", 5)等价于printf("%*d\n", 5, 5)每个*代表一个数字(参数),所以要在后面补上,即:*===5。如代码所示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	printf("%5d\n",  5);
	printf("%*d\n", 5, 5);

	printf("%.5s\n", "abcdefgh");
	printf("%.*s\n", 5, "abcdefgh");	//每写一个*,就在后面补一个对应的数据(参数)

	printf("%.3f\n", 5.4789);
	printf("%.*f\n", 3, 5.4789);

	printf("%12.3f\n", 5.4789);
	printf("%*.*f\n",12, 3, 5.4789);
	return 0;
}

运行结果图:在这里插入图片描述
我个人感觉,这样写挺麻烦,不太建议这样写。(根据个人习惯来)

  • scanf输入函数 :printf函数是用来输出数据的,有时候我们需要输入数据,就需要用到scanf输入函数。格式:scanf(" 占位符",数据)它的输入格式与printf输出格式很类似。
  • scanf函数基本用法: 它就是用来给用户输入信息用的,用标准设备进行输入(键盘),标准设备输出(带有屏幕的显示器)。对于scanf函数的理解可以如图所示:在这里插入图片描述
    当程序运行到这个函数的时候,程序会在这里停止,当用户输入数据并且按下回车键后scanf函数就开始读取用户输入的数据,然后程序才继续往下执行
  • scanf函数读取数据原理scanf函数读取数据的本质不是数据,而是这个数据的地址,然后再通过地址找到数据所在的空间,然后进行输入数据。前面,咱们写过这样的代码:int a =10 ;scanf("%d ",&a);。其中就用了&取地址操作符除了数组(数组名就是首地址,所以不需要&)和指针(指针本身就是地址,所以不需要&,以后我们会详解的)不需要&,其它变量(数据)输入就要加&,进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	int a = 10;
	char arr[20] = "ab";
	scanf("%d", &a);		//输入整数
	scanf("%s", arr);		//输入字符串
	printf("%d\n ", a);
	printf("%s\n ", arr);
	return 0;
}

结果运行图:在这里插入图片描述

  • scanf函数数据输入的形象化理解:其时,当我们输入数据的时候,scanf函数是不会立即读取的,所输入的数据会暂时先放入缓存,当我们按下回车键后,scanf函数就会根据占位符,对所输入的数据进行解读(输入)。当我们有多个scanf函数时,第一个scanf函数会先找符合占位符的数据,然后其它scanf函数会依次找符合的数据。形象比喻:缓存就像个有序号格子的大盒子,每次拿就只能按序号来一个一个拿,数据就是放入这个盒子的东西,scanf函数就是对这些东西有不同需求的人(因为占位符不同),scanf函数就要从第一个格子开始拿数据,符合的就拿走,不符合的就空手,到下一个scanf函数时,上一个函数如果符合拿走数据的化,那么本函数就拿走剩下符合的数据,如果上一个函数不符合,那么它就从第一个格子开始拿,去找合适的数据,以此类推。进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{								//输入aaaa20
	int a = 10;
	char arr[20] = "ab";
	scanf("%d", &a);		//输入整数
	scanf("%s", arr);		//输入字符串
	printf("%d\n ", a);
	printf("%s\n ", arr);
	return 0;
}

运行结果图:
在这里插入图片描述
当我们输入aaa 20时,第一个scanf函数就会按照格子顺序来解读,由于第一个scanf的占位符是"%d",但我们第一个格子放的数据是字符串,所以这个盒子里的东西会原封不动,所以,a的值就不会改变。当第二个scanf函数时,它也要从第一个格子开始读取,由于第一个格子时aaaa。所以,成功读取。所以就会出现这样的结果图。

  • scanf函数中常用的占位符;如图所示:在这里插入图片描述
  • %d, %f,%lf,%Lf的讲解:这些都是数值占位符。在输入数据时,数值占位符会自动过滤空白字符比如,空格,制表符(tab键空出的格子),换行符。进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{	
	int a = 0;
	float b = 0;
	scanf("%d %f",&a ,&b);
	printf("%d\n%f", a, b);
	return 0;
}

结果运行图:在这里插入图片描述

  • %s占位符它会从非空格开始读取数据,遇到空白字符就会结束读取,所以,%s不适合用来输入句子,书名,歌词等(因为它们会涉及到空白符)。scanf函数会在成功读取的字符串后面加上\0 进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
(
	char arr[20];
	scanf("%s", arr);
	printf("%s ", arr);   
	return 0;
}

结果运行图:在这里插入图片描述
会发现输入的数据有空格,结果输出就不完善。

  • scanf函数具有不安全性:当我们在scanf函数里面输入字符串的时候,它不知道你输入的字符串长度会不会超出你所起初设置的范围,比如,代码所示:
char arr [20];       			//我们限制了字符串的长度
scanf("%s" ,arr);			//假如,我们输入的字符串长度超出了范围,它也会给你全部输出,这就超出了你原本的意愿。
printf("%s ",arr);			//所以,scanf函数不安全

进行代码展示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{								
	char arr[20];				//输入30个a时
	scanf("%s", arr);
	printf("%s ", arr);
	return 0;
}

运行结果图:在这里插入图片描述
它会报错,但也能输出全部数据。为了防止这种情况发生(为了限制输入位数),我们有一个写法——%[数字]s,在其中间加上数字。比如,%5s无论你输入多长的字符串,到最后它就只读取5位,比如,代码展示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{								//输入30个a
	char arr[20];
	scanf("%5s", arr);
	printf("%s ", arr);
	return 0;
}

结果运行图:在这里插入图片描述

  • %c的介绍:前面,我们讲过数值占位符会过滤掉空白符。%c不会,因为空白符它本身也是字符,而%c恰恰也就是输入字符的,所以开头你给空白符它也会读取的,进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{								
	char arr =0;
	scanf("%c", &arr);
	printf("%c", arr);
	return 0;
}

结果运行图:在这里插入图片描述
为了跳过前面的空白字符,我们可以在%c之前加上空格,它就会跳过起首空白字符,比如, " %c",如代码所示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{								
	char arr =0;
	scanf(" %c", &arr);			//加了空格
	printf("%c", arr);
	return 0;
}

结果运行图:在这里插入图片描述

  • %*c赋值忽略符:有时候,我们的用户输入的信息可能不与格式相同,从而导致结果输出不准确,比如代码所示:
//以本次输入年,月,日信息的代码为例子。
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
(
	int year = 0;					
	int month = 0;
	int day = 0;
	int c =scanf("%d-%d-%d", &year, &month, &day);
	printf("%d %d %d\n", year, month, day);
	return 0;
}

scanf函数输入特殊信息时(比如2024/1/24,2024-1-24这样的信息格式),那么我们在在占位符中就要写成相应的格式,比如代码所示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{				
	int year = 0;
	int month = 0;
	int day = 0;
	int c =scanf("%d-%d-%d", &year, &month, &day);		//输入2024-1-24
	printf("%d-%d-%d\n", year, month, day); 	//为了让输出格式好看,我们也要加上
	return 0;
}

结果运行图:在这里插入图片描述
对于其它输入格式,大家可自行试试。我们想让用户按照咱们的格式输入,但有时候就事与愿违。为了这种情况的发生,我们用赋值忽略符,它会忽略我们所输入的字符格式,如代码所示;

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{	
	int year = 0;
	int month = 0;
	int day = 0;
	int c =scanf("%d%*c%d%*c%d", &year, &month, &day);
	printf("%d-%d-%d\n", year, month, day);
	//printf("scanf函数的返回值:%d",c);
	return 0;
}

结果运行图:在这里插入图片描述
在这里插入图片描述

  • scanf函数的返回值scanf函数是有返回值的而且返回值类型为整数。它返回的是成功读取数据的个数,进行代码展示:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{							
	int year = 0;
	int month = 0;
	int day = 0;
	int c =scanf("%d%d%d", &year, &month, &day);
	printf("%d %d %d\n", year, month, day);
	printf("scanf函数的返回值:%d",c);
	return 0;
}

结果运行图:在这里插入图片描述
scanf函数在成功读取数据前,如果发生读取数据错误或者读取到文件末尾,它就会返回EOF(数值为-1)EOF=end of file(文件结束标志)。在VS2022进行演示这个现象,需要输入3次ctrl+Z,这是VS2022中的一个bug。但在其它编译器其中(比如,DEVc++),输入一次ctrl+z就OK了。进行代码展示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{								/
	int year = 0;
	int month = 0;
	int day = 0;
	int c =scanf("%d%d%d", &year, &month, &day);
	printf("%d %d %d\n", year, month, day);
	printf("scanf函数的返回值:%d",c);
	return 0;
}

结果运行图:在这里插入图片描述

彩蛋放松一下!!!

听会儿音乐放松一下吧!!!
https://www.bilibili.com/video/BV1mN4y1Y7Ve/?spm_id_from=333.337.search-card.all.click&vd_source=7d0d6d43e38f977d947fffdf92c1dfad在这里插入图片描述
每章一句“纵有疾风起,人生不言弃。风乍起,合当奋意向此生。”感谢你能看到这里,点赞+关注+收藏是对我最大的鼓励,咱们下期见!!!

;