zoukankan      html  css  js  c++  java
  • [C/C++] C++ Primer学习笔记

    记录下自己掌握不清楚的概念和用法...

    Day 1

    endl:具有输出换行的效果,并刷新与设备相关联的缓冲区。
    	注:在调试程序过程中插入的输出语句都应刷新输出流,否则可能会造成程序崩溃,将会导致程序出错位置的错误判断。
    		
    buffer(缓冲区):输出缓冲区通常必须显式刷新以强制输出缓冲区内容。默认情况下,读cin会刷新cout;当程序正常结束时,cout也被刷新。
    		
    cerr:默认情况下,输出cerr不缓冲。通常用于不是程序正常逻辑部分的错误信息或其他输出。
    
    clog:默认情况下,写到clog时是带缓冲的。通常用于将程序执行信息写入到日志文件中。
    
    >>, << :都返回其做操作数,从而连续读入或输出。
    
    while(std::cin >> x):在遇到文件结束符时停止读入。
    	注:Windows系统下--"Ctrl+z"		Unix系统下--"Ctrl+d"
    
    在C++中,把负数赋给unsigned对象是完全合法的,其结果是该负数对该类型的取值个数求模后的值。
    
    通用转义字符:
    	ooo:ooo表示3个八进制数字,这三个数字表示字符的数字值。
    	xddd:十六进制转义字符,由一个反斜线符、一个x和一个或多个十六进制数字组成。
    
    字符串字面值的连接:两个相邻的仅由空格、制表符或换行符分开的字符串字面值(或宽字符串字面值),可连接成一个新字符串字面值。
    
    两种初始化变量的形式:
    	(1)直接初始化(更灵活且效率更高):int ival(1024);	(2)复制初始化:int ival = 1024;
    
    在C++中初始化不是赋值!!!
    
    内置类型变量的初始化:在函数体外定义的变量都初始化成0,在函数体内定义的内置类型变量不进行自动初始化。
    
    C++string类型==比较:若是字符串常量比较则直接比较地址。(编译器优化:相同的常量都引用同一处内存减少内存消耗)
    	例:"abc" == "abc"返回true,"" == "" 返回false
    
    extren声明变量,已初始化的extern声明被当做定义。
    	约束:变量只在从其定义处开始到该声明所在的作用域结束处才可以访问。必须在使用该变量的最外层作用域里面或之前定义变量。
    
    const对象默认为文件的局部变量,非const变量默认为extern。要使const变量能在其他文件中访问,要显式指定它为extern。
    
    const引用:指向const对象的引用。规定将普通的引用绑定到const对象是不合法的。
    
    非const引用只能绑定到与该引用同类型的对象。
    const引用则可以绑定到不同但相关的类型的对象或绑定到右值。
    
    用class和struct关键字定义类的唯一差别在于默认访问级别:默认情况下,struct的成员为public,而class的成员为private。
    

    Day 2

    头文件用于声明而不是定义。因为头文件包含在多个原文件中,所以不应该含有变量或函数的定义。
    	3个例外:头文件可以定义类、值在编译时就已知的const对象和inline函数。原因是编译器需要它们的定义(不只是声明)来生成代码。
    
    字符串字面值与string类型不是同一种类型。
    
    getline(cin,str):返回时丢弃换行符,换行符不会存储在str中。
    
    string::size_type类型:string.size()返回值类型是size_type。
    	注:不能把size的返回值赋给一个int变量,因为size_type是unsigned的,赋值过程有可能会溢出。
    	
    安全的泛型编程:
    	·C++程序员习惯于优先选用 != 而不是 < 来编写循环判断条件。
    	·调用size成员函数而不保存它返回的值是一种良好的编程习惯。
    
    vector<int>::const_iterator //它自身的值可以改变,但不能用来改变其所指元素的值。
    const vector<int>::iterator //它自身的值不能改变,但可以改变其所指元素的值。
    
    任何改变vector长度的操作都会使已存在的迭代器失效。例如,在调用push_back之后,就不能再信赖指向vector的迭代器的值了。
    
    用unsigned值初始化bitset对象:若bitset类型长度大于unsigned对象位数,则其余高位置0;否则,超出bitset类型长度的高阶位将被丢弃。
    用string对象初始化bitset对象:从string对象读入位集的顺序是从右向左。
    
    bitset.size()返回值是size_t。
    
    void*指针:可以保存任何类型对象的地址。仅支持几种有限的操作:
    	(1)与另一指针进行比较	(2)向函数传递void*指针或从函数返回void*指针	 (3)给另一void*指针赋值
    
    不能使用void*指针保存const对象的地址,而必须使用const void*类型的指针保存const对象的地址。
    
    允许把非const对象的地址赋给指向const对象的指针,但不能通过该指针改变它指向的非const对象的值。
    

    Day 3

    允许动态创建空数组,返回的是有效的非零指针,不能进行解引用。
    
    string.c_str():返回的是const char*
    
    使用数组初始化vector:vector<int> ivec(int_arr, int_arr + arr_size); //两个参数分别指数组首位置和数组末位置的后一个位置
    
    严格说,C++中没有多维数组,通常所指的多维数组其实就是数组的数组。
    
    除法或求模:
    	(1)两个数都为正数:除法(/)和求模(%)的结果也为正数(或零)。
    	(2)两个数都为负数:除法(/)操作的结果为正数(或零);而求模(%)操作的结果为负数(或零)。
    	(3)只有一个数为负数:除法 --- C++除法向零取整,即 a/b = (-a)/b = a/(-b);
    						 求模 --- 根据公式:余数 = 被除数 - 商×除数
    						 
    对于位操作符,由于系统不能确保如何处理其操作数的符号位,所以强烈建议使用unsigned整形操作数。
    
    移位操作的右操作数不可以是负数,而且必须是严格小于左操作数位数的值。否则,操作未定义。
    
    *iter++等效于*(iter++)
    
    (*p).func()等效于p->func()
    
    对数组做sizeof操作等效于将对其元素类型做sizeof操作的结果乘上数组元素的个数。
    	例:int a[5]; sizeof(a)为20;
    
    逗号表达式的结果是其最右边表达式的值。
    	例:输入一个整数,0结束	while(scanf("%d",&n),n);
    
    if(ia[index++] < ia[index]):C++未定义此行为,不能确定是先计算左操作数还是右操作数。
    
    值初始化语法必须置于类型名后面,而不是变量后。
    	例:int *p = new int();	/*正确*/	int x(); /*错误*/
    
    C++保证:删除0值的指针是安全的。

    Day 4

    switch语句:如果没有匹配的case标号(并且也没有default标号),则程序跳出switch语句。
    
    两个case含有相同的值会报错。
    
    若要匹配的case在default后面:default是最后执行的,只有所有的case都不匹配时才会执行,与位置无关。
    
    在循环中定义的变量在每次循环里都要经历创建和撤销的过程。

    Day 5

    每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参。
     
    在C语言中,具有const形参或非const形参的函数并无区别:
        例:void fcn(const int i){...}    void fcn(int i){...}    //两函数不能重载,会发生redefine error
         
    如果使用引用形参的唯一目的是避免复制实参,则应将形参定义为const引用。
     
    非const引用形参只能与完全同类型的非const对象关联。
     
    应该将不需要修改的引用形参定义为const引用。普通的非const引用形参在使用时不太灵活。
    这样的形参既不能用const对象初始化,也不能用字面值或产生右值的表达式实参初始化。
     
    C++内置数学运算符表达式就是右值。
        如:int x = 3,y = 4; fcn(x + y); //传入函数的实参是const
     
    当编译器检查数组形参关联的实参时,它只会检查实参是不是指针、指针的类型和数组元素的类型是否匹配,而不会检查数组的长度。
     
    多维数组的传递:
        void f(int (*matrix)[10], int rowSize); //将matrix声明为指向含有10个int型元素的数组的指针。
        void f(int matrix[][10], int rowSize);  //用数组语法定义多维数组。 

    Day 6

    函数调用的实参按位置解析,默认实参只能用来替换函数调用缺少的尾部实参。
    
    在一个文件中,只能为一个实参指定默认实参一次。通常,应在函数声明中指定默认实参,并将该声明放在合适的头文件中。
    因为,如果在函数定义的形参表中提供默认是残,那么在只有在包含该函数定义的源文件中调用该函数时,默认实参才是有效的。
    
    编译器隐式地将在类内定义的成员函数当作内联函数。
    
    在成员函数声明的形参表后面有const:称为常量成员函数。不允许修改类的数据成员。
    
    函数前有const,则说明函数返回值不可更改。
    
    const对象、指向const对象的指针或引用只能用于调用其const成员函数,否则会报错。
    
    构造函数的初始化列表(优先使用,效率较高):在冒号和花括号之间的代码称为构造函数的初始化列表。
    	优势:省去了临时对象的存在。在函数体内初始化相当于在构造函数当中做赋值的操作,而初始化列表是做纯粹的初始化操作。
    		  我们都知道,C++的赋值操作是会产生临时对象的。临时对象的出现会降低程序的效率。
    	特殊场景:1. 类中存在const成员,那么该成员必须在初始化列表中做初始化。
    			  2. 类中含有其它类B作为成员,而B类禁止掉赋值操作的情况下,那么对B的对象也只能通过初始化列表来实现。
    
    构造函数重载与重复声明:
    	重载:	  int A(int &x); 和 int A(const int &x);
    	重复声明:int A(int x); 和 int A(const int x); (原因:非引用形参传递的只是副本,不能区分实参是否为const)
    
    为了确定最佳匹配,编译器将实参类型到相应形参类型的转换划分等级。转换等级以降序排列如下:
    	(1)精确匹配(exact match)。实参与形参类型相同。
    	(2)通过类型提升(promotion)实现的匹配。
    	(3)通过标准转换(standard conversion)实现的匹配。
    	(4)通过类类型转换(class-type conversion)实现的匹配。
    	
    对于任意整形的实参值,int型优于short型匹配,即使short型的匹配较佳。
    
    bool (*pf)(const string&, const string&);	//声明一个指向函数的指针pf
    bool *pf(const string&, const string&);		//声明一个函数pf(...),返回值为bool*
    	
    函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。
    
    允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。
    

      

  • 相关阅读:
    Python-24-Django(Model Form、Ajax、上传文件、KindEditor)
    P23-Django-model、Form补充 & 序列化
    P22-Django-Session、CSRF、Form、信号
    21-Python-Django进阶补充篇
    Python-Django进阶
    Python-18-Django 基础篇
    17-前端开发之jQuery
    15-前端开发之JavaScript
    14-前端开发之CSS
    14-前端开发之HTML
  • 原文地址:https://www.cnblogs.com/lca1826/p/6826902.html
Copyright © 2011-2022 走看看