其他
C++编程中的核心知识点
来源 :https://blog.csdn.net/qq_34620589/article/details/70258242
尊重函数接口,尽量不作内部改动
C++代码语句分为:内置类型,名字,变量,操作符,标量,字符串,预处理指示(如#include)等
在 C++ 语言中,变量必须且仅能定义一次,而且在使用变量之前必须定义或声明变量,声明变量不分配内存,因此声名不初始化,若声明同时初始化则视为定义。
#ifndef SALESITEM_H
#define SALESITEM_H
// Definition of Sales_itemclass and related functions goes here
#endif1234
C++ primer第三章介绍了几个常用的标准库类:vector,string,iterator和bitset。
C++ 语言提供了两种类似于 vector 和迭代器类型的低级复合类型——数组和指针。现代 C++ 程序应尽量使用 vector 和迭代器类型,而避免使用低级的数组和指针。设计良好的程序只有在强调速度时才在类实现的内部使用数组和指针。
数组定义的类型名可以是任意内置数据类型或类类型,数组元素可以是除了引用之外的任意复合类型。数组的维数必须用值大于等于1的常量表达式定义。此常量表达式只能包含整型字面值常量、枚举常量或者用常量表达式初始化的整型 const 对象。非 const 变量以及要到运行阶段才知道其值的 const 变量都不能用于定义数组的维数。
与vector不同,数组不允许用另一个数组赋值和初始化,数组一经定义就不允许再添加新元素。
指针的定义:int *p;从右往左读,定义p为一个指向int类型对象的指针变量。一个有效的指针必然是以下三种状态之一:保存一个对象的地址;指向某个对象后面的另一个对象;0值。避免使用未初始化的指针。
指针的算术操作:加减整型数值。与迭代器的算术操作实现方式相同。对指针解引用,可得到它所指向的对象的值:*p。在表达式中使用数组名时,实际上是使用了指向该数组第一个元素的指针,注意数组名与指针变量的等价性。
C++ 允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用操作。如:
const size_t arr_size = 5;
int arr[arr_size] = {0,1,2,3,4};
int *p = arr;
int *p2 = p + arr_size;1234
指向const的指针理解为:“自以为指向const的指针”,当一个指针定义时指向const对象,它就会认为自己是一直指向const对象的指针,即使它后来指向一个非const对象,也不能通过引用修改该对象的值。但可以通过重新定义一个指向该对象的指针修改值。在实际的程序中,指向 const 的指针常用作函数的形参。
另外还有const指针,如int *const p = &val;const指针若指向const对象,则限制一切改动的行为。
位操作符<<和>>分别代表二进制数各位整体左移或右移右操作数位数。如int 12>>1;表示1100变为0110(6)。
j = i++与j = ++i的区别,前者自增操作符返回初值,后者返回自增后的值。尽量使用前置自增。
C++语言为包含点操作符和解引用操作符的表达式提供了一个同义词:->箭头操作符。
如:sales_item *sp = &item1; (*sp).same_isbn(item2);等效于sp->same_isbn(item2);
运用new和delete语句创建和撤销动态内存,即可创建和释放动态数组也可创建和释放单个对象,如:int *pi = new int; 表示在自由存储区(堆)分配了一个整型对象,并返回该对象的地址,并用该地址初始化指针pi。
又如:int *pi = new int(20); 同时初始化该整型对象为20。string *ps = new string; string的默认构造函数将其初始化为一个空字符串。若要显式初始化非默认初始化的对象,可写为:
int *pi = new int();在类型名后面加圆括号表示初始化为空值,这样做可以避免因未初始化带来的错误。
delete pi; 表示释放pi所指向内存,但pi中保存的地址仍存在,此时pi成为悬垂指针,易发生错误,应立即将pi置0,以显示它未指向任何对象。使用delete删除非自由存储区的内存是不合法的。
对于const对象,须返回const对象地址,如:const int *pi = new const int(1024);
C风格字符串是一个const char型字符数组:const char *ps = “C style”; 以空字符为结束位;C++标准库用string类型重新定义了字符串,更加简单直观:string ps(“characters string”);
尽量使用string类来定义字符串。
C++编译器在隐式类型转换时会尽可能防止精度损失。强制类型转换的一般格式为:
cast-name(expression) ;其中cast-name是要强制转换的方式,如static_cast;
const_cast 等,type是欲转换为的类型。尽量避免使用强制类型转换。
switch语句每个case后要加break,否则程序只会跳过后续的case标号继续执行case标号内的内容。若要在case中定义变量,则使用花括号限定变量的使用范围。
C++异常处理关键字:throw和try{}catch{}catch{}…;了解一下,throw用于退出代码块,转向异常处理。try一段代码,catch其中的语句,作相应处理。标准库定义的异常处理类都在stdexcept头文件中。
函数形参使用引用修改实参的值安全而方便,尽量不使用指针。
函数中如不需要修改实参的值,则统一使用const形参引用,如:下列程序在s中查找c字符:
string::size_type find_char(string &s,char c){
string::size_type i = 0;
while(i != s.size() && s(i) != c )
++i;
return i;
}123456
区分int *matrix[10 ]; 和int (*matrix) [10];前者表示包含10个指针的指针数组,后者表示指向含有10个int型元素的数组的指针。数组下标优先级大于指针操作符。
int main(int argc, char *argv[]) 中,argv是一个c风格的字符串数组,char *argv[]相当于char **argv,argc保存argv的字符串个数。
左值可出现在赋值语句的右侧或左侧,而右值只能出现在赋值号的右侧。函数返回值用于初始化在调用函数处建立的临时对象。因此,函数可返回引用作为左值:const string &shorterString(const string &s1,const string &s2),形参和返回类型都是引用。但不要返回局部对象的引用,同样,可以返回指针,但不能返回局部对象的指针,否则会成为悬垂指针。
递归函数是直接或间接调用自身的函数,必须要有中止条件,否则会无限循环。如:定义一个递归函数求取1×2×3……100的值:
int f(int val){
if (val > 1) return f (val-1)*val;
return val;
}1234
函数中,每个名字都有作用域,每个对象都有生命期,形参和局部变量的生命期在函数调用过程中,它们的名字作用域限于函数块中从定义到快结束之间。若我们希望一个局部对象在函数调用结束后仍然具有生命,则可以定义静态局部变量:static关键字。
定义inline内联函数是为了编译器在处理函数时按照函数块内语句展开,节省直接处理函数带来的花销。在普通函数前加inline关键字,并只能在头文件中定义。
类的成员函数在类内声明,可以在类外定义,也可以在类内定义。其形参表包含一个隐式形参this指针,初始化为调用该成员函数的对象地址,如:在Sales_item类中定义的成员函数:
bool same_isbn(const Sales_item &rhs) const {
return isbn == rhs.isbn;
}123
return this->isbn == rhs.isbn; 函数体中可以显式地使用后者语句,但没有必要。
构造函数是一种特殊的成员函数,用于初始化类,同名构造函数可以重载,由不同数目或类型的形参表区分。构造函数没有返回类型,和类同名。
每个版本的重载函数应在同一个作用域中声明,局部同名函数会覆盖全局函数而不是重载。
-END-
推荐阅读
【01】手把手教你如何把C++的源程序改写成C语言【02】还在发愁C++中类模板?这文章为你答疑解惑【03】世纪性大问题:C 语言会比 C++ 快吗?【04】C++这么难,该怎么学?【05】C++开发这一步必不可少:C++创建线程的方法