读入一组数据,文件中每行第一个数代表要读的数目n,后面的n个数就是要读入的数
#include<iostream>
#include<fstream>
using namespace std;
int main(){
ifstream cin("pr1030F.txt");
cout.precision(3);
int n;
while(cin>>n){//读入n
float sum=0;
for(int i=1,a;i<=n&&cin>>a;i++){//读入n个数字
sum+=a;
}
cout<<fixed<<sum/n<<endl;
}
}
设置精确到小数点后三位
int sum;
cout.precision(3);
cout<<fixed<<sum<<endl;
计算精度控制
#include<cmath>
abs(x)>1e-6;
补码, 以及输出整数内部32位二进制内码
求负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1。
for(int i=31;i>=0;i--){ //method 1
cout<<(n>>i&1)? 1:0;
}
//方法一:将二进制首位移到最低位与1比较。
for(int i=0;i<=31;i++){ //method 2
cout<<(n<<i <0);
}
//方法二:将二进制要输出的位移到首位与0比较,如果是1则首位会是负的(补码性质),0则这个数是正的。
注:有符号数右移会补充最高位,左移会补零。
右对齐输出setw()
setw()是给紧跟着后面的数据预定一个空间,如果该数据小于这个空间,在左边用0补齐;setw()只对紧跟在他后面的数据有效
cout<<setw(11)<<n<<(n<0? "-->-":"-->")+s+"\n";
十二转换
//用string 除二取余
string s;
for(int a=n;a;a/=2){
s+=(a%2)? '1':'0';
}
reverse(s.begin(),s.end());
cout<<setw(11)<<n<<(n<0? "-->-":"-->")+s+"\n";
//方法同上,改用vector实现
//可以看出来麻烦很多
vector<int> s_rev(0);
//vector<int> s(0);
int i=0;
for(int a=n;a;a/=2){
s_rev.push_back((a%2)? 1:0);
//cout<<s_rev[i];
i++;
}
i=i-1;//用容器的时候定义的容器个数与下标会差1,debug发现的
int j;
vector<int> s(s_rev);
for(j=i;j>=0;j--){
s[i-j]=s_rev[j];
}
j+=1;//用容器的时候定义的容器个数与下标会差1
cout<<setw(11)<<n<<(n<0? "-->-":"-->");
for(j;j<=i;j++){
cout<<s[j];
}
cout<<endl;
//采用整数内码特性
int i=31;
while(!(n & 1<<i)) i--;//i定位到从左到右第一个非0位置
利用getline()来一次性输入
一般用cin>>s来读取的时候总是将前面的空格滤掉;
用getline读取可以一次性输入。
getline()的原型是istream& getline ( istream &is , string &str , char delim );
其中 istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为’\n’,也就是回车换行符(遇到回车停止读入)。给大家举个例子:
string line;
cout<<"please cin a line:"
getline(cin,line,'#');
cout<<endl<<"The line you give is:"line;
那么当我输入”You are the #best!” 的时候,输入流实际上只读入了”You are the “,#后面的并没有存放到line中(应该是在缓冲区里吧)。然后程序运行结果应该是这样的:
please cin a line:You are the #best!
The line you give is:You are the
而且这里把终止符设为#,你输入的时候就算输入几个回车换行也没关系,输入流照样会读入,譬如:
please cin a line:You are the best!
//这里输入了一个回车换行
Thank you!
# //终止读入
The line you give is:You are the best!
//换行照样读入并且输出
Thank you!
引用作为函数参数
作为函数参数时引用有两种原因:
1、在函数内部会对此参数进行修改
2、提高函数调用和运行效率
关于第一点,都知道C++里提到函数就会提到形参和实参。如果函数的参数实质就是形参,不过这个形参的作用域只是在函数体内部,也就是说实参和形参是两个不同的东西,要想形参代替实参,肯定有一个值的传递。函数调用时,值的传递机制是通过“形参=实参”来对形参赋值达到传值目的,产生了一个实参的副本。即使函数内部有对参数的修改,也只是针对形参,也就是那个副本,实参不会有任何更改。函数一旦结束,形参生命也宣告终结,做出的修改一样没对任何变量产生影响。
例如:
void swap(int p1, int p2) //对两个变量进行交换处理。此处函数的形参为p1, p2,没有引用
{
int p;
p = p1;
p1 = p2;
p2 = p;
}
void main( )
{
int a,b;
cin >> a >> b; //输入a,b两变量的值
swap(a,b); //直接以变量a和b作为实参调用swap函数
cout << a << ' ' << b; //输出结果
你会发现输出的a和b还是你输入的值,没有交换。
如果我们改为:
void swap(int &p1, int &p2) //对两个变量进行交换处理。此处函数的形参为p1, p2都是引用
{
int p;
p = p1;
p1 = p2;
p2 = p;
}
再次执行,就会发现值交换了。
原理就在于采用&p1和&p2时,p1和p2是实参的别名而已,像一个指针指向实参。改变p1和p2就是改变实参的值。
关于第二点,可以结合第一点分析,p1和p2是实参的引用,不用经过值的传递机制,已经有了实参值的信息。所以没有了传值和生成副本的时间和空间消耗。当程序对效率要求比较高时,这是非常必要的.
引用作为函数返回值
说明:
(1)以引用返回函数值,定义函数时需要在函数名前加&
(2)用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。
例如:
#include <iostream.h>
float temp; //定义全局变量temp
float fn1(float r); //声明函数fn1
float &fn2(float r); //声明函数fn2
float fn1(float r) //定义函数fn1,它以返回值的方法返回函数值
{
temp=(float)(r*r*3.14);
return temp;
}
float &fn2(float r) //定义函数fn2,它以引用方式返回函数值
{
temp=(float)(r*r*3.14);
return temp;
}
void main() //主函数
{
float a=fn1(10.0); //第1种情况,系统生成要返回值的副本(即临时变量)
float &b=fn1(10.0); //第2种情况,可能会出错(不同 C++系统有不同规定)
//不能从被调函数中返回一个临时变量或局部变量的引用
float c=fn2(10.0); //第3种情况,系统不生成返回值的副本
//可以从被调函数中返回一个全局变量的引用
float &d=fn2(10.0); //第4种情况,系统不生成返回值的副本
//可以从被调函数中返回一个全局变量的引用
cout<<a<<c<<d;
}
引用作为返回值,必须遵守以下规则:
(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,程序会进入未知状态。
(2)不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一 个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak。
(3)可以返回类成员的引用,但最好是const。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常 量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。
这里推荐几本书,有兴趣的朋友去看看里面关于引用的说明和注意事项:
《Effective C++》
《Thinking in C++》
计算程序运行时间
clock() 捕捉程序运行到被调用所耗费的时间,单位是 clock tick,即时钟打点。
常数CLK_TCK/CLOCKS_PER_SEC代表及其时钟每秒走的时钟打点数。
#include<time.h>
clock_t start stop;//clock_t是clock()函数返回的变量类型
double duration;
int main(){
start = clock();//开始计时
MyFunction();//要计时的函数
stop = clock();//停止计时
duration = ((double)(stop-start))/CLK_TCK;//计算运行时间
return 0;
}
输入数据加上scanf(“\n”)避免segmentation fault
输入数据时候,测试数据如果有换行输入,那就加上scanf(“\n”),避免把\n当做下一次输入造成segmentation fault
很重要!!!
VS2013 消除_CRT_SECURE_NO_WARNINGS
Warning 1 warning C4996: ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
在编程过程中难免会用到一些过时,或者曾经不安全的函数,如上,这是编译器会出现warning提示用某某新函数,如果不想使用新的函数可以使用一下方法:
1. 使用VS提供的 编译器选择性提供warning功能 link: http://msdn.microsoft.com/en-us/library/2c8f766e.aspx 例:上面的错误使用 #pragma warning( disable : 4996) 即可消除。
2. 使用提示中的_CRT_SECURE_NO_WARNINGS,以下是使用方法:
a. Project properties->Configuration Properties->C/C++->Preprocessor->Preprocessor
Definitions
b. 点击按钮 (…)
c. 输入:_CRT_SECURE_NO_WARNINGS。 注:使用 “\n” 相隔
3.#define _CRT_SECURE_NO_WARNINGS
#include