printf()和scanf()函数的滴滴点点

        最近在看一本书----《C语言解惑》,这篇博客相当于我做的笔记的其中一个,内容如下:

printf()函数和scanf()一对冤家

      1.printf()输出

        1.1.空格到底在哪

       

        不难发现,“hello\n"之后有一个空格,而这个空格出现在了下一行,因为这个空格本身也在printf函数的打印范围之内,输出换行之后,就会继续打印空格了。而且有多少个空格,第二行就会出现多少个。

       

        printf函数的格式-————

        printf(格式控制,输出量表);

        格式控制其实就是一个字符串,包括格式说明和普通字符串。格式说明就是如%d之类的(%+格式符),他的作用就是把数据转换成指定格式输出。而普通字符串就如同上边的”hello\n ",原样输出,遇到转义字符后做出相应的反应即可。

        插一句题外话,如果想要在屏幕上打印一个%,需要使用%%才能打印出来一个%。

        但是如果pintf()输出的时候,如果对于转移字符也是用%%,则达不到预期的目的。

1.2.别再傻傻分不清        

话说回来,很多初学者甚至老手在书写代码,都会有傻傻分不清楚时候。

        比如数字1和小写字母l,看着就很像。其实下边这个编译器(小熊猫)还好,比较明显。但是分不清楚这件事确确实实是存在的,这就需要我们去格外的注意。

     

        除此之外,错用格式符相信 是每位学者都会犯的错误吧。

                

        所以,在我们运行遇到类似这种问题的时候,不妨看看是不是格式符的错用。

         2.printf()输出字符或整数

       2.1.格式要配对

        谈到字符和整数,就不由自主地会想到ASCII码表。一个0到255之间的整数,都可以被看作一个字符,可以用 %c 输出一个整数的字符,也可以用 %d 输出一个字符的整数。

        还是那句话,不要错用格式符,否则达不到预期结果。就像下边这个输入的格式配对错误。

        有人认为是%g的错误,其实不然。g是输出实数,它会根据数值自动选择 或者 e 。而且double类型输出是不必非要是%f,排除一次,我们发现还是scanf这里的问题。

        scanf()中 f 是输入浮点数,输入时可以使用小数或者指数形式,因此认为是,没有使用%lf的原因。

        “l”说明这是一个“长”,对应“long”。

        2.2.丢弃,长度和空格

        再来看一下下边的代码:

        可以思考一下,输入123456789,会输出什么?

        

        答案是12,6789,

        这里的“*”号是表示输入项读取之后不赋值给相应的变量,而是丢弃。%2d是说明宽度是2,比如输入123456789,%2d会将12读取,%3d就把345吸收丢弃,剩下的全部给b,而换行则被%c吸收,因为换行是不可见字符。所以是这样的。

        那如果输入123 456 789,又会怎么样呢?

        直接公布答案吧,输出:12,456,

        将12赋值给a,丢弃3,但3之后是一个空格,表示一个字符串的结束,于是456会被赋值给b,虽然有789,但是456之后有一个空格,这个空格被%c吸收。

        所以结果是:

        那输入1 2 3456 789,又怎么样呢?

        被舍弃的空格是空格区分的,如果数量不够,也只是舍弃的空格而已。如果数量足够,就舍弃相应的位数,剩下的赋值给变量。

        由此可见,空格是不是有点意思啊。

        那么请你看看下边的例子————

        (这里的a,b,c都是int类型)

       1. scanf("%d%d%d", &a,&b,&c);

        2.scanf("%d%d%d ",&a,&b,&c);//注意看,最后一个%d后边跟了一个空格

        3.scanf(" %d%d%d",&a,&b,&c);//第一个%d前边有一个空格

        实验可以发现,第一个和第三个可以正常运行,但是第二个却要输入4个数据才能进行下一步

        也就是说,最后一个%d与双引号之间不能有空格。

        2.3.回车一敲,脑子发烧

        请看下边这个代码。

        假如输入12 34 56

                       abc

        会是什么样的景色呢?

        你一猜就知道,这里必定有坑。

        是的,没错,但有时候我们就是会跳

        第一行输入结束之后,我们按下enter键,而这个换行就被被付给第一个%c,也就是c1,换行不可见,所以打印不了,于是就是下边这个:

        解决办法也很简单,只需要加一个getchar()吸收掉换行就行了。

        现在来看一种输入字符是比较有意义的一个方式。

        这样写的话,既可以连续输入,也可以用空白符分割,甚至可以先打一个换行,再输入数据

        2.4.字符数组和字符

        请你先来看这样的一段代码:

        第三个打印之所以到不到目的,是因为str[5]仅仅代表的是y这个字母而已,如果想要达到目的,该怎么样修改呢?

        很简单,改为&str[5]即可:

        不过瘾?再来!!!

        

        在这里,我们本来是想要把you and me装到str中,但是由于scanf遇到空白符会停止读取。所以只是把you装进去了。那如何达到目的呢?我们找来了scanf的弟弟———gets()。        

        有请gets()登场:

        是不是手到擒来啊?

2.5.特殊对待一维数组

        数组名是数组首元素的地址,想要打印出来整个数组的内容,这是远远不够的。可以使用循环单个输出数组的元素,就像这样:

        那么如果是为数组赋值,又该怎么做呢?

        首先想到的肯定就是循环了——

        我们都知道&arr[i]表示数组arr的各个元素的地址,这些地址储存这相应的数组元素,对其进行操作,也可以输出于元素。

        

        来分析以下,下面这段代码的错误——

        #include <stdio.h>

        int main()

        {

        int a = 25;

        int addr;

        addr = &a;

        printf("分配给变量a的地址是0x%d\n",&a);

        printf("addr的地址值=0x%p\n",addr);

        printf("addr的地址的内容=%d\n",*addr);

        }

        编译会给出一个错误信息和一个警告信息。

        因为addr是一个整型变量,&arr是一个地址,数据类型不匹配。可以使用强制类型转换,addr = (int)&arr;

        直接对&a使用 * ,对addr出错很明显也是数据类型不配对的原因。

        再次给出强制类型转换

        printf("addr的地址的内容=%d\n", *(int*)addr);

2.6.主角上场——指针

相信以上的代码对你来说,毫无压力,那我们我们一块来看看下边这个吧———

//代码的目的是模拟strcpy函数,复制一个字符串

        没达到预期结果是因为,本身you and me就没有被t给接受。不难想到我们之前提到的函数gets

        

        如果使用指针来输入字符串,需要保证指针指向的足够大的字符数组,以便储存输入的字符串和结尾的空字符。

        本次笔记,就到这里吧,感谢~

        

        

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值