导图社区 C++程序总结
C++程序语法总结导图笔记,对C++程序的基本概念做了详细记录,供大家参考。
编辑于2020-10-02 13:34:14C++程序
基本概念:
枚举常量: enum
语法格式: enum <类型名> { <枚举值表> }; enum color { red = 1, yello, blue }; enum color c1, c2, c3;
变量的初始化方式: 3 种
① 赋值初始化: int a = 12; int a[ ] = { 1, 2, 3, 4}; ②小括号初始化: int a ( 12 ); // 小括号不能进行数组初始化 ③大括号初始化: int a{ 12 }; int a[ ]{ 13, 56, 37}; //数组初始化
变量的定义:
[<存储类>] <类型名> <变量名> [ = <初值表达式>],... ; <存储类> 四种:auto 、 registerr 、 static 、 extern <类型名> 如: char, int ......
类型说明: typedef
格式: typedef <已有类型名> <新类型名> 如: typedef int integer;
符合常量: const
符合常量语法格式: const <类型名> <符合常量名> = <初值表达式>...... ;
运算符: sizeof ( )
运算符: 31p
goto 语句:
goto 语句: goto <标号>; 在 goto 语句所处的函数中,同时存在一条 <标号> 标记的语句 <标号> : <语句> // 存在 goto 就必须有 <标号> int i=0, sum=0; Loop : sum += i; cout << sum; i++; if (i <= 100) goto Loop;
数组:
数组注意点:
char num[] = { 'a', 'b', 'c', 78, 68, 89 }; // 数组里的数字为对应的 ASCLL 码
数组与指针注意事项:
(一维数组名) 相当于 一个(一级指针) (二维数组名) 相当于 一个(数组指针) (指针数组名) 相当于 一个(二级指针) 数组指针不能用(二维数组的值)来初始化 比如: (*a)[3] ={{10,20,30},40,50} //这是错误的 # 数组的存储地址是连续的 # 数组指针: n[ ][3] = { {10, 20,30}, {40,50,60}, 70, 80, 90 } //二级括号里的数组必须小于等于他的范围 ( *p )[3] = n; 列子: 指针指向 70; p[0][6] == n[0][6] p[1][3] == n[1][3] p[2][0] == n[2][0] *(p+2)[0] == n[2][0] *(*(p+2)+0) == n[2][0] == *(*(p+2)) 指针可以向下兼容: # 二级指针兼容一级指针 //二级指针的用法可以用和一级指针差不多 用法来表示 # 二级指针是可以超标的 // 如: 在a[3][3] 中, a[2][1] 可以表示为 a[1][4] 或 a[0][7]
常用的字符串函数:
strcpy-s
函数原型: char * strcpy (char *s1, char *s2) 作用: 把 s2 拷贝到 s1
strcat-s
函数原型: char * strcat (char * s1, char * s2) 作用: 把 s2 的内容添加到 s1 的末尾
strcmp
函数原型: int strcmp(char * s1, char * s2) 作用: s1 小于 s2 , 返回 负数 s1 大于 s2 , 返回 正数 s1 等于 s2 , 返回 0
strlen
函数原型: int strlen(char * s) 作用: 返回 s 的长度,末尾的 空字符 不计入内。
strstr
函数原型: char * strstr (char * s1, char * s2) 作用: 在 s1 中 查找 s2, 查找成功,返回 s2 在 s1 中的 首位置,否则返回 NULL
指针:
指针数组:
数组指针:
指针函数:
函数指针:
引用:&
int i; //创建引用时必须马上初始化, 初始化后就不能在赋值了 int & p = i; // p 为 i 引用数据的另一个接口, p 和 i 用的是同一个地址,改变了 p 值 就相当于 改变了 i 值。
动态存储分配:
new
<指针> = new <类型> ; 列如: int * pi = new int ; 初始化: int * pi = new int(256); 数组动态分配: <指针> = new <类型>[<元素个数>]; //动态分配的数组可以是一个变量 列如: int * pi = new int[10]; 或 int * pi = new int[n]; n = 5; 动态存储操作失败: int * pi = new int[1024]; if ( pi == NULL) //内存分配失败返回 NULL { cout<<"exit the program! \n"; exit(1); //内存分配失败退出程序 }
delete
释放动态存储空间: delete <指针>; 列如: delete pi; //释放 pi 指向的单个变量 动态数组: delete [ ]<指针>; 列如: delete [ ] pi; //释放 pi 指向的数组
进阶:
类:
类的定义:
定义: class <类名> { public: <成员函数和数据成员说明> //公有成员,外部接口 protected: <成员函数和数据成员说明> // 保护成员 peivate: <成员函数和数据成员说明> //私有成员 }; //类后面要有分号 //类的实现部分 <各个成员函数的实现>
类的说明:
1、访问权限修饰符 说明: 访问权限修饰符 可以 (以任意顺序出现!) 最好将权限归类,同意权限的放在一起。 2、类成员默认权限是私有的: //没有给定 权限的成员 就是默认成员 3、类的数据成员 (1) 类中的数据成员可以是任意类型 (2) 在类体中,不允许对定义的类成员进行初始化 (3) 成员函数除了可以定义 内联函数外,还可以进行 重载。 4、类的别名 定义: <类名> <类变量>,<类变量>; // 定义了类变量后,就可以把它当成类的别名来使用
类的函数:
一、类外部定义的成员函数 格式: <返回类型> <类名> ::<成员函数名> (<参数表>) { <函数体> } 二、作用域运算符 使用格式: <类名>::<成员函数名>(<参数表>) 或 <类名>::<成员函数名>
构造函数 和 析构函数:
构造函数
性质: (1) 构造函数 的名字必须与类名相同。 (2) 构造函数 不知道返回值,由系统内部使用。 (3) 构造函数 可以是一个或多个参数, 因此可以重载。 (4) 在创建对象时,系统会自动调用构造函数。 列子: class Date { public: Date(int y ) : year(){ <函数体> }; Date(int y, int m, int d ) private: int year, month, day; // 变量定义可以不用赋值 } Date : : Date() : year(y), month(m), day(d) { <函数体> };
析构函数
特性: (1) 析构函数 是在 类名前 加 求反(取反)符号 ~ ; (2) 析构函数 不指定返回类型,它不能有返回值; (3) 析构函数 没有参数,因此 不能重载,一个类中只能定义一个; (4) 在撤销对象时, 系统会自动调用 析构函数; class Date { public: Date(int y ) : year(){ <函数体> }; Date(int y, int m, int d ); ~Date() { <函数体> }; private: int year, month, day; // 变量定义可以不用赋值 } Date : : Date() : year(y), month(m), day(d) { <函数体> };
复制构造函数
格式: <类名>: :<类名> ( const <类名> & <引用对象名>) { <函数体> } 特点: (1) 也是一种构造函数,函数名与类名相同,不能指定返回值; (2) 可以有多个参数; (3) 每个类中 必须有一个 复制构造函数,如果没有 编译器会自动生成; 在以下三种情况下会被调用: (1) 用类的一个一直对象去初始化另一个对象; (2) 采用传值方式调用时,对象作为函数实参传递给 函数形参; (3) 对象作为函数返回值;
this 指针
定义: 它是成员函数所属的对象的指针,它指向类对象的地址。成员函数通过这个指针可以知道自己属于哪一个类。 作用: 成员函数 每次要调用类的成员时 都会使用 this 指针。
静态成员
静态成员表示整个类范围的信息,声明以 static 开头。 包括 静态数据成员 和 静态成员函数。 列如: class MyClass { privat: int a,b,c; static int sum; //私有静态数据成员 }; MyClass a, h, i, z; 静态数据成员 是 所有对象 公有的。(意味着:一个对象改变它,在所有对象中 它的值 都会随着改变)
静态成员函数
注意: 在类外定义时,不能使用 static 作为函数前缀。 限制: (1) 静态成员函数 可以直接访问 静态成员。 (2) 静态成员函数 不可以直接访问 非静态成员。 (3) 要访问必须通过参数传递的方式获得某个对象,再通过对象进行访问。 (注:第三条说的意思是:因为非静态成员在不同对象值是不同的,所有要指定对象来访问)
常成员
常对象
格式: <类名> const <对象名> const <类名> <对象名> (1)常对象在定义时必须进行初始化。 (2)常对象只能调用常成员函数。
常函数
格式: <返回类型> <成员函数名>(<参数>) const; 注意: (1) 常成员函数不能更新对象的数据成员。 (2) 常对象只能调用它的常成员函数,不能调用其他成员函数。 因此,如果成员函数不修改对象时,最好将其声明为 const 成员函数 const 可以参与重载函数的区分: 如: void Print( ) const; void Print( ) ; //两函数可以同时存在 对象对它的调用: 如果 两个同名函数同时存在时: (1) 常对象 调用 常成员函数。 (2) 一般对象 调用 一般成员函数。
常数据成员
格式: const <类型> <数据成员>; 常数据成员 必须进行 初始化,并且不能被更新; 初始化过程和一般数据成员初始化一样,只是不能再次赋值。
友元函数
友元函数
格式: friend <类型> <函数名>(参数); 要点: (1) 在类外部定义友元函数时,不需要加 “类名 : : ”。 友元函数访问类成员 和 一般函数访问 类成员 是 一样的(直接调用)
友元成员
简介: 将一个类的成员函数 声明为 另一个类的友元函数. 在另一个类中声明成友元函数 格式: friend <类型> <类名>::<函数名>(参数) friend Date : : time( const Time& d) // 参数处 要输入什么类型的 就要声明声明类型的 这函数是声明在 Date 类中的 一般函数。 注意: (1) 使用该类中的友元成员时,要通过相应的类和对象进行访问。 如: 在 Time 中访问 Time 的成员要用: d.day //d为类对象,day为 Time 中的类成员 警告:友元成员就像是一个接口,只能从上一个类(早一点声明的类)插到下一个类(晚一点声明的类),上一个为原函数,下一个为友元函数。
友元类
定义: friend <类名>; 注意: 友元类的 接口 存放是没有顺序的,可以随意放(自上而下,自下而上)都行。
对象数组
定义: <类名> <数组名> [ <大小> ]; 例如: Date date[5] ; 使用对象数组成员格式: <数组名> [<下标>] . <成员名> 例如: date[0] . year 定义方式: Date date[5] = { Date(10, 1, 2002), Date(10,2,2002),Date(10, 3, 2002) ....... } date[3] = Date(10, 4, 2002) date[4] = Date(10, 5, 2002)
成员对象
定义: 当一个类的成员 是 另一个类的对象 时, 该对象就称为 成员对象。 初始化格式: <类名>: :<类名>(<总形参表>) : <成员对象1>(<形参表1>),<成员对象2>(<形参表2>) { 。。。。。。 } 注意: 成员对象构造函数的执行顺序 仅与 成员对象在类中的声明有关。
继承和派生:
格式:
class <派生类名> : <继承方式1> <基类名1>, <继承方式2> <基类名2> { 派生类新定义的成员; }
公有 保护 私有 继承的区别:
公有继承: 1、公有继承 时,通过类的对象可以访问 类的公有成员。 2、但是不能访问 保护成员。 3、public 以 public 身份 出现,protected 以 protected 身份 出现。 保护继承: 1、public 和 protected 以 protected 的身份出现 在派生类中。 2、不管 公有成员 还是 保护成员 都(不能)通过类对象访问。 3、公有 和 私有 成员,可以被类 成员函数访问。 私有继承: 1、基类的 public 和 protected 成员:都以 private 身份出现在 派生类 中。 2、基类的 private 成员:不可直接访问。 3、不能通过 派生类对象 访问基类继承的任何成员。
多继承的二义性问题:
二义性问题,要通过限定访问权限的方式来解决。
虚基类:
为解决 二义性问题而提出: 格式: class <派生类> : virtual <继承方式> <基类> 作用:使重复的变量只初始化一次。
虚析构 与 纯虚析构
虚析构: // 解决 子类 堆区中 不能释放空间的问题(子类没有东西放在堆区就可以不写 虚析构) 1.当继承时刻,父类会先调用自己的构造函数,然后在调用子类的构造函数。 2.继承后,父类会调用自己的析构函数,然而子类的构造就不会调用这样会造成内存泄露。 一、析构函数 // 虚析构 virtual ~Person(){} // 加 虚析构 后,析构函数就会先调用子类的,虚构函数,然后在调用父类的虚析构函数完成程序! // 纯虚析构 virtual ~Person( ) = 0; //有 纯虚析构后 这个类就是 抽象类了(纯虚析构必须实现)
运算符重载:
格式: 返回值 operator+ 运算符 (参数)
分为: 1、友元重载(参数等于操作数) 2、类重载 (参数等于操作数 -1 )
规则和限制:
限制: = ( ) [ ] -> 只能以类成员函数重载
规则: 单目运算符: (采用 类重载) 双目运算符: (采用 友元重载)
文件流:
1、文件流的建立:
头文件: include< ifstream >
建立即打开:
建立打开: ifstream fin( "d:\\ sav \\ date.dat" , model ); // model表示打开模式
建立再打开: ifstream fin; //默认模式: in fin. open( "d:\\ sav\\ date.dat", model );
输出: ofstream fin( "文件名" ) // 默认: out 输入输出: fstream("文件名", model ); //一定要写模式,没有默认
打开模式:
列表: ios_base : : app //添加数据,文件尾开始写 ios_base : : binary //作为二进制文件打开 ios_base : : in //为输入而打开 ios_base : : out // 为输出而打开 ios_base : : trunc //若文件存在,截为空文件 ios_base : : ate //指针定在文件尾
对于 写入头( ifstream ) 输出的模式是没用的
文件关闭:
close( )
文件流判别:
文件流当前状态: is_open ( ) //判断流对象是否与一个打开的文件相联系: 是 true 否 false good( ) // 刚进行的操作成功时,返回ture ,失败:false fail ( ) //与 good( ) 相反 bad( ) //进行非法操作返回 true ,正常返回:false eof( ) //进行输入操作时,指针达到文件尾,返回 ture,否则:false
文件流的定位:
文件流的位置:
输入位置(get ) 输出位置(put )
位置:
ios_base : : beg //相对文件首 ios_base : : cur //相对于当前文件位置(负数表示当前位置之前) ios_base : : end //相对于文件尾
输入定位:
有关函数: istream_type& seekg ( off_type& off, ios_base : : seek_dir dir ) // 示列:input . seekg( -100, ios : : cur ) //将指针定位于 off 处
pos_type tellg( ); //返回当前的输入位置(即指针位置,从流开始处记)
bool eof( ) const; //判断文件流是否结束,结束ture ,否则 false
输出定位:
ostream_type& seekp ( pos_type pos); // 将输出流定位于绝对位置 pos (绝对定位) ostream_type& seekp (off_type off, ios_base : : seekdir dir ); // 按方式 dir 将输出流 定位于定位于相对位置 off 处(相对定位) pos_type tellp ( ); //返回当前输出位置
无格式输入输出:
无格式输入:
int_type get( ); //提取当前位置的字符
istream_type& get( char_type& c ) ; //提取当前字符存入 c 中
istream_type& getline( char_type *s , streamsize n, char_type delim ) // 存入 s, 读取 n 个字符, 结束标志: delim
istream_type& getline( char_type& * s, streamsize n ) // 此函数调用 getline( s, n, widen('\n')) // 以换行符为结束标志
istream_type& ignore( streamsize n=1, int_type delim = traits : : eof( ) ) //提取并舍弃(起移动指针的作用)
int_type peek( ); //返回当前位置的字符,指针位置不变(如果已到最后,无字符读取,返回 -1 (EOF)
istream_type& putback( char_type c ); //把字符 c 退回输入流中,使之成为下一个字符!
istream_type& read ( char_type * s, streamsize n ); // 从当前读取,存入 s 指向的 具有 n 个字符的空间中! (此函数要求 文件要以 ios_base :: binary 格式打开!)
无格式输出:
ostream_type& put ( char c ); // 输出 c
ostream_type& write( const char * s, streamsize n ); // 输出 s 所指向的数据空间中的 n 个字符(要求用 ios_base :: binary 模式打开)
// >> 和 << 不能作为二进制文件的输入输出