大家好,又见面了,我是你们的朋友全栈君。
目录:
- 0.前言【精简版】:
- 时间少的看这里:
- 1.【绅士淑女止步!!!!】
- 0.必备入门小知识:
- 1.正题1:scanf
- (1) %*d 被枪毙了:
- (2) 【%.*d 】的队友被枪毙了:
- 2.正题2:printf就不讲了,前面的【前言】似乎讲得很明白了吧。
0.前言【精简版】:
其实网上也有很多关于这方面的解释,但是总会让新手甚至小老手有些迷茫,比如网上有一种解释就说:忽略…… 你忽略啥啊你…
时间少的看这里:
%*和*.*的形式,一般只有整数%和字符串%s的情况下才比较有用,但是为了方便大家理解,这里我列出全部的基础情况:
请注意:scanf和printf中的情况是不一样的!
<1>
scanf:
注意:在scanf里只有%*d和%.*d有意义, 其他的%*f,%*lf,%*c和%*s等等都是没有意义的,编译器会报错。所以千万别乱写。
(1) %*d
(仅它有意义:忽略掉它本身,并重新匹配:)
int a=0,b=0,c=0;
scanf("%*d%d%d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
输入:12 34 56
输出:a=34,b=56,c=0
相当于:忽略掉第一个输入12(它本身),
并将a与第二个数匹配,b与第三个数,
所以c没有匹配的输入,故c还是原来的值0.
下面的2种情况给你参考:
代码语言:javascript复制/****************************************/
scanf("%d%*d%d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
输入:12 34 56
输出:a=12,b=56,c=0
相当于:忽略掉第二个输入34(它本身)
scanf("%d%d%*d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
输入:12 34 56
输出:a=12,b=34,c=0
相当于:忽略掉第三个输入56(它本身)
(2) %.*d
(仅它有意义:忽略%*d的下一个输入,并重新匹配)
scanf("%.*d%d%d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
输入:12 34 56
输出:a=12,b=56,c=0
相当于:忽略掉第二个输入34(它的下一个)
所以a和第一个输入匹配,b和第三个输入匹配,
中间那个输入被忽略了,所以c也就没有匹配上。
下面的2种情况给你参考:
代码语言:javascript复制/****************************************/
scanf("%d%.*d%d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
输入:12 34 56
输出:a=12,b=34,c=0
相当于:忽略掉第三个输入56(它的下一个)
scanf("%d%d%.*d",&a,&b,&c);
printf("a=%d,b=%d,c=%d",a,b,c);
输入:12 34 56
输出:a=12,b=34,c=56
相当于:忽略掉第四个输入(它的下一个:空气)
所以最后这种没有意义!和没有加.*一样。
<2>
printf:
注意:在printf里没有限制,%c,%d,%s,%f,%lf都可以加*或.*,都有意义。 但是,他们的意义却不相同:
(1) %*d
(意义:肯定会输出全部,根据实际情况补空格)
int a=123;
printf("a=%*d",2,a);
输出:a=123
(输出全部123,长度>2,不需要补空格)
跟没指定一样!
printf("a=%*d",10,a);
输出:a=空格空格空格空格空格空格空格123
(往前补7个空格,补够总共10个位)
(2) %.*d
(意义:肯定会输出结果,根据实际在前面补0)
printf("a=%.*d",2,a);
输出:a=123
(输出全部123,长度>2,不需要补0)
跟没指定一样!
printf("a=%.*d",10,a);
输出:a=0000000123
(往前补7个0,补够总共10个位)
很显然这种情况意义不大,因为我们很少需要补0.
所以基本不用这种写法。
(3) %*f
(意义:肯定会输出全部,根据实际补空格)
注意,%f默认小数点后面6位数:小数点也算一位!
float a=12;
printf("a=%*f",3,a);
输出:a=123.000000
默认小数点后面6位。而且肯定会输出全部,
所以10位>指定的3位,跟没指定一样!
printf("a=%*f",13,a);
输出:a=空格空格空格123.000000
默认小数点后面6位。而且肯定会输出全部10位,
剩下3位,所以在前面填3个空格(小数点也算一位)
(4) %.*f
(意义:指定小数点后面几位,跟%.nf是一样的)
你懂的
(5)%*s
(意义:也是根据实际情况在前面加空格)
char *a="123456";
printf("a=%*s",5,a);
输出:a=123456;因为5<6,所以跟没指定的一样
printf("a=%*s",10,a);
输出:a=空格空格空格空格123456
(6)%.*s
(意义:指定截取前面几位数)
char *a="123456";
printf("a=%.*s",4,a);
输出:a=1234;
截取前面4位数
printf("a=%.*s",10,a);
输出:a=123456
截取前面10位数,因为只有6位,
所以跟没指定的一样!
1.【绅士淑女止步!!!!】
时间充裕的可以看我下面的啰嗦:
0.必备入门小知识:
为方面您食用后面我所讲的理论,请你先阅读下面这个你可能从未思考过的小知识: 
这是什么意思呢? 意思就是:你需要吧scanf的将部分参数拆分成两部分看! 很多初学者都会忘记添加寻址符&, 因为没人告诉过他第二部分的参数用的是地址
例子1:
scanf("%d%d%d");
这样其实是可以的。 表示:你可以输入三个值, 但是因为第二部分的参数为空,即没有地址,(如&,指针), 所以输入的值并不会被保存到内存中
例子2:
int a,b,c;
scanf("",&a,&b,&c);
这样也是可以的。 表示:你可以输入0个数,因为第一部分的参数没有%, 所以连输入的机会都没有,怎么存? 所以后面都是写了个寂寞。
例子3:1 2
上面两个例子加起来才真正有用。 所以你就经常看到这样的形式: int a,b,c;
scanf("%d%d%d",&a,&b,&c);
这样的形式你实在是太熟悉了! 表示:从左到右: 第一个%d输入的数存放在内存地址a 第二个%d输入的数存放在内存地址b 第三个%d输入的数存放在内存地址c
1.正题1:scanf
用例子讲道理:
(1) %*d 被枪毙了:

如图所示,如果出现了%*,就会拉拢后面一个%跟她非法组队,然后跟&a匹配。
但是《国家婚姻法》规定,一人只能要一个。所以,这里规定:非法组队的发起者%*d被举报拉出去枪毙了,最后留下第二个与&a匹配(因为是从左往右匹配)。所以c就没了对象了。
代码语言:javascript复制也就是说:原来是a的老婆被枪毙了 所以: 原来是b的老婆就嫁给了a 原来是c的老婆就嫁给了b 最终导致c没了老婆,c哭了。 所以,你输入 12 34 56 然后输出a,b,c,结果: a=34,b=56,c=0(默认值0)
请问:下面这种形式,是哪个和哪个非法组队?
int a=0,b=0,c=0;
① ② ③
scanf("%d%*d%d",&a,&b,&c);
答案:②③非法组队,因为*出现以后 才拉拢她的后一个组队!
(2) 【%.*d 】的队友被枪毙了:
承上:上面的例子讲解了%*d的情况,我们知道了他们内部秘密的非法组队。即:
代码语言:javascript复制int a=0,b=0,c=0;
① ② ③
scanf("%*d%d%d"):①②组队,①被枪毙
scanf("%d%*d%d"):②③组队,②被枪毙
scanf("%d%d%*d"):③和空气组队,③被枪毙
启下:这种情况:%.*d又是怎么回事? 其实道理还是一样的,都是非法组队,但是这次这个.*不简单,所以它不会被枪毙,而是她的队友被枪毙了:
代码语言:javascript复制int a=0,b=0,c=0;
① ② ③
scanf("%.*d%d%d"):①②组队,②被枪毙
scanf("%d%.*d%d"):②③组队,③被枪毙
scanf("%d%d%.*d"):③和空气组队,空气被枪毙
所以第三种就是相当于没加.*,完全等价于: scanf(“%d%d%d”); 这两种随便你用哪种咯。 但是明智的你,应该会选择最简便的第二种。
2.正题2:printf就不讲了,前面的【前言】似乎讲得很明白了吧。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/128285.html原文链接:https://javaforall.cn