#C02L06P01. C02.L06.实型变量与格式化输入输出.语法知识1.格式化输入输出函数
C02.L06.实型变量与格式化输入输出.语法知识1.格式化输入输出函数
1. 从 cin/cout 到 scanf/printf
我们学习过的 cin、cout,一般情况下,用来输入、输出数据已经足够了。但这种方法电脑的运行效率比较低,尤其是数据量达到 10 万个以上时会非常明显,很容易就会超时。
为了能够更快输入、输出较多的数据,需要使用格式化输入(scanf)和输出函数(printf)。
格式化输入(scanf)和输出函数(printf)的格式如下:
scanf(格式控制符,地址列表);
printf(格式控制符,输出列表);
例如:输入一个整数并将这个数输出。
scanf("%d",&a);
printf("%d",a);
说明:
(1)使用scanf 和printf,需要调用头文件。
(2)“%d”叫做格式控制符,格式控制符代表了输入或输出的“格式说明”,%d表示输入的数据是整数。scanf和printf的使用方法是一样的,只不过前者比后者在变量前多了个“&”号,这些变量跟前面的格式控制符是一一顺序对应的。
一些常用格式控制符说明见下表:
格式控制符 | 说明 |
---|---|
%d | 整型(-2147483648 ~2147483647) |
%lld | 长整型(-9223372036854775808 ~ 9223372036854775807) |
%f | 单精度浮点数 |
%lf | 双精度浮点数 |
%c | 单字符 |
程序改进:
#include<bits/stdc++.h>
using namespace std;
int n,r,a,s;
int main()
{
cin>>n>>r;
for (int i=1; i<=n; i++)
{
scanf("%d",&a);//cin>>a;
if (a<=r) s++;
}
cout<<s;
return 0;
}
2. 提升和拔高
scanf 命令的第二个参数是变量的地址,这个地址讲的是 内存地址。变量其实就是存储单元,变量的值是以某种格式存放到计算机的内存当中的。物理上的内存条其实由很多很多更细更小的单元组成。
在上一节课讲计算 空间复杂度 的时候讲过变量的存储空间的时候讲过:一个 int 变量对应是 4 个 byte, 一个 long long 变量对应的是 8 个 byte......讲的就是变量在内存中占用的空间。内存都是有地址的,类似我们各人的家,都是有门牌号一样。我们定义一个变量的时候,就会给这个变量分配一个地址,这个地址对应的内存空间就是属于这个变量的,以后我们要给这个变量赋值,就是去到这个变量对应的内存地址去修改里面的数值。
上面讲到的 & 运算符,如果它是单目运算符(就是 & 前面没有参数),那么它表示的就是获得内存地址的意思,例如 &a 就是获得变量 a 的内存地址的开始位置。
int a;
scanf("%d",&a); //&a 就是获得变量 a 的内存地址
对于数组来说,单单引用数组名称而不带下标,得到就是这个数组第一个元素的内存地址
int a[100];
scanf("%d",a); // a 就是数组第一个元素的地址,所以写 a 相当于写 &a[0];
scanf("%d",a+1); // a+1 是数组元素的第二个元素的地址,所以写 a+1 相当于写 &a[1];
因此,对一个数组赋值,可以这样写:
int a[100];
for(int i=0;i<n;i++)
scanf("%d",a+i); //相当于 scanf("%d",&a[i])
3. 常见错误
3.1 漏了写&,会出现 runtime 错误
错误代码例子
int a;
scanf("%d",a);
上面这段代码,会出现内存越界的错误(一般会提示 runtime error)。因为执行 scanf 的时候,输入的数据会送到 a 这个值所指向的内存那里去,注意,不是变量 a 所分配的地址
。
例如,如果 a 在执行scanf之前的值是 0 。那么 scanf 的执行效果是接收一个输入值,把值存放到内存地址为 0 的内存单元那里去。而存放 a 变量的地址可能是 12349876 。 所以,相当于是吧数据写到了错误的地方去了,导致内存越界。
3.2 写错了格式提示符,没有正常赋值
错误代码例子
long long a;
scanf("%d",&a);
变量是 long long 类型,但是 scanf 的第一个参数格式说明说的是 int 类型。scanf 并不会检查这个声明是否正确,它只会傻傻的去按照你提供的格式说明去做。它会从接受一个整数,存放到 a 变量对应的地址那里去,而且是当做 int 来处理。
而我们知道,一个 int 是 4 个 byte,一个 long long 是 8 个 byte,所以上面的 scanf 执行的时候只会改写 a 变量的 4 个 byte,而另外 4 个 byte 是完全没动过。这会出现什么结果呢?如果 a 是一个局部变量,内存里面本身有内容的,那么在 scanf 的时候并没有抹掉之前旧的数据(有 4 个 byte 保持不变,原来是什么就什么),所以你可能输入的是 100 ,但是因为那 4 个 byte 有内容,a 的值最终是 10000000000004 都是有可能的,所以,整个程序的运行结果是错的,而且是不可控的(每次运行的结果都可以不一样,结果飘忽不定)。
相关
在以下作业中: