速通C语言——(printf()和scanf()的详细解析和计算机单位的速通)

发布于:2025-03-12 ⋅ 阅读:(134) ⋅ 点赞:(0)

引言

        总结了输入输出函数printf和scanf的一些细节用法,希望对你有帮助

一、二进制的单位速通

在计算机中,字节及其相关单位的换算关系是以2的幂次为基础的,常见的单位换算如下:
 
1. 位(bit)与字节(Byte):1字节等于8位,即1Byte = 8bit。
2. 字节与千字节(KB):1千字节等于1024字节,即1KB = 1024Byte。
3. 千字节与兆字节(MB):1兆字节等于1024千字节,即1MB = 1024KB。
4. 兆字节与吉字节(GB):1吉字节等于1024兆字节,即1GB = 1024MB。
5. 吉字节与太字节(TB):1太字节等于1024吉字节,即1TB = 1024GB。
6. 太字节与拍字节(PB):1拍字节等于1024太字节,即1PB = 1024TB。
7. 拍字节与艾字节(EB):1艾字节等于1024拍字节,即1EB = 1024PB。
8. 艾字节与泽字节(ZB):1泽字节等于1024艾字节,即1ZB = 1024EB。
9. 泽字节与尧字节(YB):1尧字节等于1024泽字节,即1YB = 1024ZB。

1Byte = 8bit。

1KB = 1024Byte。

1MB = 1024KB。

1GB = 1024MB。

1TB = 1024GB。

1PB = 1024TB。

1EB = 1024PB。

1ZB = 1024EB。
 1YB = 1024ZB。
在实际应用中,硬盘、U盘等存储设备的制造商有时会采用1000进制来标注容量,如1GB = 1000MB,这与计算机中的换算有所不同,使用时需注意区分。

二、printf()和scanf()的详解

先给出文档,对英语能力有一定的要求,看不懂,没关系,下面的文章仔细看。

printf()的文档:

printf - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/cstdio/printf/?kw=printfscanf()的文档:

scanf - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/cstdio/scanf/?kw=scanf

1.printf

printf() 的作用是将参数文本输出到屏幕。它名字里面的 f 代表格式化(format)表示可以定制输出文本的格式。

printf()是在标准库的头文件stdio.h定义的。使用这个函数之前,必须在源码文件头部引入这

个头文件

#include<stdio.h>

int main()
{
	printf("hello word");
	return 0;
}

 还是这个经典的程序。

注意:printf() 不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。

        为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符:\n

#include<stdio.h>

int main()
{
	printf("hello word\n");
	return 0;
}

1.1占位符

要讲清楚printf()和scanf()这两个函数。必须先了解占位符

printf() 可以在输出文本中指定占位符。

所谓“占位符”,就是这个位置可以用其他值代入。

#include<stdio.h>

int main()
{
	printf("There are %d people\n",4);
    //这里的4,可以换成其他的整形
	return 0;
}

        上面示例中,There are %d people\n 是输出文本,里面的 %d 就是占位符,表示这个位置要用其他值来替换。占位符的第一个字符一律为百分号 % ,第⼆个字符表示占位符的类型,%d表示这里代入的值必须是⼀个整数。里面的 4,可以换成其他的整形。

#include<stdio.h>

int main()
{
	printf("There are %d people, one of is %s\n", 4,"zhangsan");
	return 0;
}

         这段代码里面的%s,表示代入的是一个字符串,所以这个printf()的第二个参数就必须是字符串


        同时,这段代码中也可以看出,输出文本里面是可以使用多个占位符的,但占位符与后面的对应的值必须一一对应,比如:不能用%d,来接受字符串类型,即其他类型。


       注意: printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符,printf()的参数就应该有n + 1 个。如果参数个数少于对应的占位符, printf() 的参数就应该有 printf() 可能会输出内存中的任意值。

1.2占位符的列举

printf() 的占位符有许多种类,与C语言的数据类型相对应。下面按照字母顺序,列出常用的占位符,方便查找

        占位符————————介绍

        • %a  :⼗六进制浮点数,字母输出为小写。

        • %A :⼗六进制浮点数,字母输出为大写。

        • %c :字符。

        • %d :⼗进制整数。

        • %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 :⽆符号整数(unsignedint)。

        • %x :⼗六进制整数。 • %zd : size_t 类型。

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

1.3输出格式

printf() 可以定制占位符的输出格式。

1.3.1 限制宽度
#include<stdio.h>

int main()
{
	printf("%5d\n", 123); // 输出"     123"
	return 0;
}

上面示例中, %5d 表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。 输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的 % 的后面插入一个 - (负)号。

#include<stdio.h>

int main()
{
	printf("%-5d", 123); 
	printf("456");
	// 输出"123     456"
	return 0;
}

上面示例中,输出内容 123 的后面添加了空格。 

#include<stdio.h>

int main()
{
	printf("%12f\n", 123.45);
	return 0;
}

        上面示例中,%12f 表示输出的浮点数最少要占据12位。由于小数的默认显示精度是小数点后6位, 23.45 输出结果的头部会添加2个空格。

 1.3.2 总是显示正负号
#include<stdio.h>

int main()
{
	pirntf("%+d\n", 10);
	pirntf("%+d\n", -10);
	return 0;
}

默认情况下, printf() 不对正数显示 + 号,只对负数显示号。如果想让正数也输出 + 号,可以在占位符的 % 后⾯加⼀个 + 。 上面示例中, %+d 可以确保输出的数值,总是带有正负号。

1.3.3 限定小数位数
#include<stdio.h>

int main()
{
	printf("num is %.3f\n", 0.5);

	return 0;
}

        输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留三位,占位符可以写成 %.3f。如果希望⼩数点后面输出3位(0.500),占位符就要写成%.3f。

        这种写法可以与限定宽度占位符,结合使用。

#include<stdio.h>

int main()
{
	printf("%6.3f\n", 0.5);

	return 0;
}

        上面示例中, %6.2f 表示输出字符串最小宽度为6,小数位数为3。所以,输出字符串的头部有两个空格。

         最小宽度和小数位数这两个限定值,都可以用 * 代替,通过 printf() 的参数传入
 

#include<stdio.h>

int main()
{
	printf("%*.*f\n",6, 2, 0.5);

	return 0;
}


        上面示例中, %*.*f 的两个星号通过 printf() 的两个参数 6 和3 传⼊。

 1.3.4 输出部分字符串

        %s 占位符用来输出字符串,默认是全部输出。如果只想输出开头的部分,可以用%.[m]s指定输出的长度,其中 [m] 代表⼀个数字,表示所要输出的长度。

#include<stdio.h>

int main()
{
	printf("%.5s\n", "hello world");

	return 0;
}

 上面示例中,占位符 %.5s 表示只输出字符串“hello world”的前5个字符,即“hello”。

 2.scanf

        当我们有了变量(下一节讲),我们需要给变量输入值就可以使用的scanf 函数,可以再用printf函数打印在屏幕上

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int score = 0;
	printf("请输入成绩:");
	scanf("%d", &score);
	printf("成绩是:%d\n", score);

	return 0;
}

        在VS2022上,VS2022认为scanf不安全,让使用scanf_s函数,可以在代码的最上面写上

#define _CRT_SECURE_NO_WARNINGS

来解决这个问题,至于怎么永久解决这个问题,会单独出一章来讲解


        上面这段代码,当我们输入99时,屏幕上会打印出99,一个简单的输入输出程序就被写出来啦。

 2.1 基本用法

scanf() 函数用于读取用户的键盘输入。

程序运行到这个语句时,会停下来,等待用户从键盘输⼊。

用户输入数据、按下回车键后, scanf() 就会处理用户的输入,将其存入变量。

它的原型定义在头文件 stdio.h 。

scanf() 的语法跟 printf() 类似。

 下面详细介绍一下scanf函数

scanf("占位符(个别占位符与printf的占位符有差异)", 变量的地址(&是取地址符号))

如:int score = 0;

score 的地址是 &score,所以要给score变量赋值,就要传入&score

注意:

        scanf中的占位符也要一一对应,在键盘上的输入格式应与scanf()中第一个双引号中的格式保持一样

2.2 scanf的返回值

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

EOF-endoffile 文件结束标志

        可以自己写个代码多试一试,注意:在VS2022中,按三次ctrl + z 才能使程序结束(即遇到文件结尾)使其返回-1;

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int a = 0;
	int b = 0;
	float f = 0.0f;
	int r = scanf("%d %d %f",&a, &b, &f);
	printf("a=%d b=%d f=%f\n", a, b, f);
	printf("r=%d\n", r);

	return 0;
}

自己多测试测试,才可以体会到其中的韵味 。

2.3 占位符

  scanf()常用的占位符如下:

        %c : 字符。

        %d :整形。

        %f : float 类型浮点数。(特记)

         %lf : double 类型浮点数。(特记)

        %Lf : long double 类型浮点数。

         %s :字符串。

         %[] :在方括号中指定⼀组匹配的字符(⽐如 %[0-9]), 遇到不在集合之中的字符,匹配将会停止。
        

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

        下面要特别说⼀下占位符 %s ,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止。

        因为 %s 不会包含空白字符,所以无法用来读取多个单词,除非多个 %s⼀起使用。这也意味着, scanf() 不适合读取可能包含空格的字符串,比如书名或歌曲名。

        另外,scanf()遇到%s占位符,会在字符串变量末尾存储⼀个空字符 \0 。

        scanf() 将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,储存字符串时, 很可能会超过数组的边界,导致预想不到的结果。为了防止这种情况,使用%s读入字符串时,应指定读入字符串的最长长度,即写成 %[m]s ,其中的[m] 是⼀个整数,表示读取字符串的最大长度,后面的字符将被丢弃。

 2.4 赋值忽略符

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	scanf("%d-%d-%d", &year, &month, &day);
	printf("%d %d %d\n", year, month, day);
	return 0;
}

        上面示例中,如果用户输入 格式,比如 2025-03-08 ,就会正确解读出年、月、日。问题是用户可能输入其他 2025/03/08 ,这种情况下, scanf() 解析数据就会失败。 为了避免这种情况, scanf() 提供了⼀个赋值忽略符(assignment  suppression  character) * 。 只要把 * 加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	scanf("%d*%d*%d", &year, &month, &day);
	printf("%d %d %d\n", year, month, day);
	return 0;
}

        上面示例中, %*c 就是在占位符的百分号后面,加入了赋值忽略符 * ,表示这个占位符没有对应的变量,解读后不必返回。


网站公告

今日签到

点亮在社区的每一天
去签到