C++学习笔记(重温计划之一)

1、C++新特点

 这里所说的新特点,是相较于C语言而言的.本笔记旨在加强记忆和理解,本身内容并未超出教材的范围.我们仍将沿用《面向对象程序设计c++版》(刘振安,机械工业出版)和《c++程序设计教程第二版》(钱能,清华大学出版社)的基本思路,开始都是最基本的东西。

 C++与C语言的关系,向来是众说纷纭的。但在我结束首轮学习之后发现,C++与C的关系,仅表明C++包含了C,C++完全可以当作一门新语言来学习,有C基础的人也未必比没有基础而开始学习C++的占多大优势。以下是C++一则例示:

/功能:将结构的两个域值相加,乘以2再减去50/

include<iostream>

//————hanyi.name 1.1—————

using namespace std;

int result(int,int);

const int k = 2;

struct Point{    int x,y;

};

int main(){

 int z(0),b(50);    Point a;    cout  <<“输入两个整数(以空格区分):”;

    cin  >>a.x>>a.y;

    z = (a.x + a.y)*k;

    z = result(z,b);

    cout  <<“计算结果如下:”<<endl;

    cout  <<“((”<<a.x<<“+”<<a.y<<“)*”<<k<<“)-”<<b<<“=”<<z<<endl;

    return 0;

}

int result(int a,int b){

 a = a - b;    return a;

}

 下面对以上内容作一说明:

 1、c++源程序以.cpp作为文件扩展名,其中main()主函数只能有一个。由于main()是过程化语言的标志,c++也被称为混合型语言。

 2、注释符号基本以/ /和左起开头//为主。

 3、引入“流”的概念,例如cin和cout分别是c++标准输入输出库iostream的一员,这类库总称为STL(standard library标准函数库)。endl类似于转义字符\n,功能均为换行。

 4、头文件中iostream.h的.h可以省略,但必须新标准类库的使用头文件载入的方法:using namespace std;

 5、对象定义和初始化,新引入了int z(0);定义的方法,此方法功能与int z = 0相同。

 6、函数必须有类型声明,例如int main(),且必须有返回值return。当然void类型也是被允许的,但不和return同时使用。

 7、const修饰符。

       在c语言中,我们使用宏定义#define定义常量,这里推荐使用const。以下文章摘自csdn: 

====================================================================================     

对于基本声明

1.       const int r=100; //标准const变量声明加初始化,因为默认内部连接所以必须被初始化,其作用域为此文件,编译器经过类型检查后直接用100在编译时替换

2.       extend const int r=100; //const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义

3.       const int r[ ]={1,2,3,4};struct S {int a,b;}; const S s[ ]={(1,2),(3.4)}; //以上两种都是常量集合,编译器会为其分配内存,所以不能在编译期间使用其中的值,例如:int temp[r[2]];这样的编译器会报告不能找到常量表达式

对于指针

1.       const int *r=&x; //声明r为一个指向常量的x的指针,r指向的对象不能被修改,但他可以指向任何地址的常量

2.       int const *r=&x; //与用法1完全等价,没有任何区别

3.       int * const r=&x; //声明r为一个常量指针,他指向xr这个指针的指向不能被修改,但他指向的地址的内容可以修改

4.       const int * const r=&x; //综合13用法,r是一个指向常量的常量型指针

对于类型检查

可以把一个非const对象赋给一个指向const的指针,因为有时候我们不想从这个指针来修改其对象的值;但是不可以把一个const对象赋值给一个非const指针,因为这样可能会通过这个指针改变指向对象的值,但也存在使这种操作通过的合法化写法,使用类型强制转换可以通过指针改变const对象: const int r=100; int * ptr = const_cast<int>(&r);  //C++标准,C语言使用:int * ptr =(int)&r;

对于字符数组

char * name = “china”; 这样的语句,在编译时是能够通过的,但是”china”是常量字符数组,任何想修改他的操作也能通过编译但会引起运行时错误,如果我们想修改字符数组的话就要使用char name[ ] = “china”; 这种形式。

对于函数

1.       void Fuction1 ( const int r ); //此处为参数传递const值,意义是变量初值不能被函数改变

2.       const int Fuction1 (int); //此处返回const值,意思指返回的原函数里的变量的初值不能被修改,但是函数按值返回的这个变量被制成副本,能不能被修改就没有了意义,它可以被赋给任何的const或非const类型变量,完全不需要加上这个const关键字。但这只对于内部类型而言(因为内部类型返回的肯定是一个值,而不会返回一个变量,不会作为左值使用),对于用户自定义类型,返回值是常量是非常重要的,见下面条款3

3.       Class CX; //内部有构造函数,声明如CX(int r =0) CX  Fuction1 () { return CX(); } const CX Fuction2 () { return CX(); } 如有上面的自定义类CX,和函数Fuction1()Fuction2(),我们进行如下操作时: Fuction1() = CX(1); //没有问题,可以作为左值调用 Fuction2() = CX(1); //编译错误,const返回值禁止作为左值调用。因为左值把返回值作为变量会修改其返回值,const声明禁止这种修改。

4.       函数中指针的const传递和返回: int F1 (const char * pstr); //作为传递的时候使用const修饰可以保证不会通过这个指针来修改传递参数的初值,这里在函数内部任何修改*pstr的企图都会引起编译错误。 const char * F2 (); //意义是函数返回的指针指向的对象是一个const对象,它必须赋给一个同样是指向const对象的指针。 const char * const F3(); //比上面多了一个const,这个const的意义只是在他被用作左值时有效,它表明了这个指针除了指向const对象外,它本身也不能被修改,所以就不能当作左值来处理。

5.       函数中引用的const传递: void F1 ( const X& px); //这样的一个const引用传递和最普通的函数按值传递的效果是一模一样的,他禁止对引用的对象的一切修改,唯一不同的是按值传递会先建立一个类对象的副本,然后传递过去,而它直接传递地址,所以这种传递比按值传递更有效。 **另外只有引用的const传递可以传递一个临时对象,因为临时对象都是const属性,且是不可见的,他短时间存在一个局部域中,所以不能使用指针,只有引用的const传递能够捕捉到这个家伙。

对于类

1.       首先,对于const的成员变量,只能在构造函数里使用初始化成员列表来初始化,试图在构造函数体内进行初始化const成员变量会引起编译错误。初始化成员列表形如: X:: X ( int ir ): r(ir) {} //假设r是类Xconst成员变量

2.       const成员函数。提到这个概念首先要谈到const对象,正象内置类型能够定义const对象一样(const int r=10;),用户自定义类型也可以定义const对象(const X px(10);),编译器要保证这个对象在其生命周期内不能够被改变。如果你定义了这样的一个const对象,那么对于这个对象的一切非const成员函数的调用,编译器为了保证对象的const特性,都会禁止并在编译期间报错。所以如果你想让你的成员函数能够在const对象上进行操作的话,就要把这个函数声明为const成员函数。假如f( )是类中的成员函数的话,它的声明形如: int f( ) const; //const放在函数的最后,编译器会对这个函数进行检查,在这个函数中的任何试图改变成员变量和调用非const成员函数的操作都被视为非法 **类的构造和析构函数都不能是const函数。

3.       建立了一个const成员函数,但仍然想用这个函数改变对象内部的数据。这样的一个要求也会经常遇到,尤其是在一个苛刻的面试考官那里。首先我们要弄清楚考官的要求,因为有两种方法可以实现,如果这位考官要求不改变原来类的任何东西,只让你从当前这个const成员函数入手,那么你只有使用前面提到的类型强制转换方法。实例如下: //假如有一个叫做X的类,它有一个int成员变量r,我们需要通过一个const成员函数f( )来对这个r进行++r操作,代码如下 void X::f( ) const {  (const_cast<X*>(this)) -> ++r;  } //通过this指针进行类型强制转换实现另外一种方法就是使用关键字:mutable如果你的成员变量在定义时是这个样子的: mutable int r ; 那么它就告诉编译器这个成员变量可以通过const成员函数改变。编译器就不会再理会对他的检查了。=========================================================================================================== 

8、变量对象命名以及初始化

 c++本身区别字母的大小写语言,以开头的标识符一般为系统使用,应当尽量避免。同时宏定义标识符需用大写字母标

识。另外,名字的第1个字母不能是数字或运算符,也不能包含运算符。为标识符命名时可遵循如下规律:

   1)使用能代表数据类型的前缀;

   2)名称与变量的作用尽量接近;

   3)如果名称由多个英文单词组成,每个英文单词首字母大写;

   4)在库函数中尽量不要使用以开头的名字,以免与系统命名冲突;

   5)局部变量名称较短,尤其是循环控制变量;

   6)外部变量应使用较长的名字,并能与其代表的变量含义接近;

 9、程序的书写格式:

  

   1)括号需紧跟在函数名的后面,但在for和while后面,应用一个空格和左括号隔开以增加可读性;

   2)数学运算符的左右两边各留一个空格,与表达式区别;

   3)在表示参数时括号后面留一个空格;

   4)在for、do…while、while中,应合理使用缩进、一对话括号和空行;