C++ 入门

读入一组数据,文件中每行第一个数代表要读的数目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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值