C++Primer读书笔记(二)

10.无符号数不会小于0
   注意不能将带符号类型和无符号类型混合使用。

11.变量声明与定义的关系
   extern int i;//声明i而非定义i(只声明不定义用extern)
   int j;//声明并定义j
   extern int i=1;//定义(赋值操作抵消了extern的作用,任何包含了显示初始化的声明即为定义)
   在函数体内部初始化一个extern关键字标记的变量,将引发错误。
   变量能且仅能被定义一次,但可多次声明;若在多个文件中使用同一变量,就必须将声明(用到的文件中)与定义(只能出现在一个文件中)分离。

12.约定俗成的标识符命名规范
   标识符要能体现实际含义
   变量名一般用小写字母
   用户自定义的类名一般以大写字母开头
   如果标识符由多个单词组成,则单词间应该有明显的区分。student_loan或studentLoan.

13.建议在第一次使用变量时再定义它。有助于找到变量的定义,并且当定义与第一次使用的地方很近时,方便赋给它一个合理的初始值   
   若函数有可能用到某全局变量,则不宜再定义一个同名的局部变量。

14.引用
  引用并非对象。它只是为一个已经存在的对象所起的另外一个名字。
  int ival=1024;
  int &refVal=ival;//refVal是ival的另一个名字
  引用必须初始化,一旦初始化完成,引用将与它的初始值(必须是一个对象,而不是常量)一直绑定在一起,无法令引用再绑定到另外的变量。不能再定义引用的引用。

14.建议初始化所有指针
   void*是一种特殊的指针类型,可以用于存放任意对象的地址,对该地址中到底是什么类型的对象并不了解
   double obj=3.14;
   void* p=&obj;//ok

   int* p1,p2;//p1是指针,p2是int
   int *p1,*p2;//ok
   引用指针不是一个对象,所以不能定义指向引用的指针。
   但指针是对象,所以存在对指针的引用。int *p;int *&r=p;
 面对一条比较复杂的指针或引用的声明语句时,从右向左阅读有助于弄清楚它的真实含义。

15.只在一个文件中定义const,而在其他多个文件中声明并使用它: 对于const常量无论是声明还是定义(必须的)都添加extern关键字,这样只需定义一次就可以。

16.常量引用是对const的引用
 引用的对象是常量还是非常量可以决定其所能参加的操作,却无论如何不会影响到引用和对象的绑定关系本身。
 对常量的引用不能被用作修改它所绑定的的对象。
  初始化常量引用时允许用任意表达式作为初始值。  
  int i=2;
  const int &r=i;//ok
  const int &r1=2;//ok
  const int &r2=r1*2;//ok
   int &r3=r1*2;//error,常量引用的值不允许赋给非常量引用

17.constexpr关键字
  如果认定变量是一个常量表达式,就把它声明为constexp类型
  constexp int mf=20;//20是常量表达式
  constexp ing limit=mf+1;//mf+1是常量表达式
   
18.auto类型说明符
  分析表达式所属的类型,通过初始值来推算变量的类型。
  auto item=val1+val2;//item初始化为val1+val2的结果
  auto sz=0,pi=3.14;//error,一条声明语句只能有一个基本类型

19.decltype类型指示符
  decltype选择并返回操作数的数据类型。编译器分析表达式并得到它的类型,却不实际计算表达式的值。
  decltype(f()) sum=x;//编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为sum的类型。
  引用从来都作为其所指对象的同义词出现,只有用在decltype处是一个例外
  decltype和引用    P63

20.头文件
   头文件通常包含制备定义一次的实体,如类、const、和constexpr变量
   头文件一旦改变,相关的源文件必须重新编译以获取更新过的声明
   头文件保护符:使用预处理变量头防止重复包含的发生。
   #ifndef 头文件名
   #define 头文件名
    //头文件内容
   #endif

21.命名空间的using声明
  eg:    using namespace::std;
   注意头文件不应包含using声明,因为头文件的内容会被拷贝到所有引用它的文件中去,如果头文件使用了某个using声明,会导致每个使用了该头文件的文件都会有这个声明,易产生名字冲突。

22.string类型[可变长的字符序列]
   使用时需要
   #include <string.h>
   using namespace::string;  
   初始化: string s3("xxx");//直接初始化,s3是字面值xxx的副本
            string s3="xxx";//拷贝初始化,s3是字面值xxx的副本
            string s4(10,'c');//,直接初始化,s4的内容是cccccccccc
            string s1=string(10,'c');//拷贝初始化,s1的内容是cccccccccc
            string s2(s1);//s2是s1的副本,等价于string s2=s1;
   string对象s的操作:
            s.empty();//返回值bool
            s.size();//返回一个无符号的size_type类型的值,所以不要和有符号的值混用,所以表达式中有size()函数就不要再用int了
                     //允许编译器通过auto和decltype来推断变量类型auto len=word.size();
            s[n];//s[0]是第一个字符,以此类推...
            s1+s2;//可以两个对象s1+=s2;
            字面值相加s3=s1+","+s2;//当把string对象和字符字面值及字符串混在一条语句中使用时,
                                        //必须确保每个+[注意是每个+]的两侧的运算对象至少有一个是string,
                                       //注意c++中的字符串面值与string并不是同一个类型
            s1=s2;s1==s2;s1!=s2;<,<=,>,>=//对大小写敏感
            cin>>s;cout<<s;//输入输出,说明:在执行读取操作是string对象会自动忽略开头的空白(空格/换行/制表符),
                                             并从第一个真正的字符开始读起,直到遇见下一处空白为止。
            cin>>s1>>s2;多个对象可连结
            读入未知数量的string对象:string word;
                                      while(cin>>word){...}//未遇到结束标记或非法输入
            用getline替换cin中的>>,可以保留输入时的空白符,换行符触发getline函数返回后被丢弃
                                      while(getline(cin,word)){...}
  范围for语句
        for(declaration:excepression)
            statement
         eg:string str("some string")
            for(auto c:str)//对于str中的每个字符
                cout<<c<<endl;每行输出一个字符
    注:在访问指定字符前,要检查string类型是否为空if(s.empty()){...}
23.建议使用cname的头文件而不使用name.h的头文件,标准库中的名字总能在命名空间std中找到,而后者程序员需要牢记那些是从c继承的,哪些是c++独有的

猜你喜欢

转载自blog.csdn.net/qq_36616692/article/details/80642158