高级程序设计语言复习

高级程序设计语言复习

本文主要用于高级程序设计语言课程的复习,本课主要对C & C ++中的重要特性以及其编程思想部分进行学习,对于其中语法部分并未进行详细介绍。

C语言

typedef

typedef与define区别

typedef char* pStr1;
#define pStr2 char* 
pStr1 s1, s2;// ------->char *s3, *s4;
pStr2 s3, s4; //------->char* s3, s4;

typedef与const同时出现的一些问题

typedef char *pStr;
char string[5]="test";
const char *p1=string;
const pStr p2=string;
p1++;
p2++;// error ,p2为只读变量
int mystrcmp(const pstr, const pstr); 
typedef char * pstr;int mystrcmp(pstr, pstr);// 错误的,这里const pstr会被解释为char * const 
typedef const char * cpstr; int mystrcmp(cpstr, cpstr); // 现在是正确的

不管什么时候,只要为指针声明 typedef,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身是常量,而不是对象。

typedef 掩饰符合类型

typedef char Line[81]; Line text, secondline;getline(text)
typedef char * pstr;int mystrcmp(pstr, pstr);

C/C++ typedef用法详解(真的很详细)_键盘tops舞者的博客-CSDN博客_c++ typedef

static & extern

static

变量

普通局部变量,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。

普通局部变量存储于进程栈空间,使用完毕会立即释放。

静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

变量在全局数据区分配内存空间;编译器自动对其初始化
其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束

函数

函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。其特性如下:

  • 静态函数只能在声明它的文件中可见,其他文件不能引用该函数
  • 不同的文件可以使用相同名字的静态函数,互不影响

非静态函数可以在另一个文件中直接引用,甚至不必使用extern声明

函数外部的static变量及static函数只对文件内部可见

extern

利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数

此变量必须是全局变量。另外,extern关键字只需要指明类型和变量名就行了,不能再重新赋值,初始化需要在原文件所在处进行,如果不进行初始化的话,全局变量会被编译器自动初始化为0。但是在声明之后就可以使用变量名进行修改了。

#include <stdio.h> 
int i = 3; 
int p(void) { 
    printf("%d\n",i);     
    return 0;      
}
//--------------------------//
#include <stdlib.h> 
extern int p(void); 
extern int i; 
int main() { 
    p(); 
    i++;
    p();    
    return 0;      
}
//-------------------------//
输出
3 
4

虽然static类型不能被extern引用,但可以通过函数去访问。

#include <stdio.h> 
static int i = 3; 
int p(void) { 
    printf("%d\n",i);     
    return 0;    
}
// ---------------------------//
#include <stdlib.h> 
extern int p(void); 
int main() { 
    p();    
    return 0;      
}

对C语言中的static关键字的深入理解_on_1y的博客-CSDN博客

C语言中的static 详细分析_keyeagle的博客-CSDN博客_c语言static

c语言中static关键字用法详解_guotianqing的博客-CSDN博客_static

c/c++中static详解_lwbeyond的博客-CSDN博客_c++ static

c语言中static和extern的用法详细解析_C 语言_脚本之家 (jb51.net)

指针

数组指针

形如 int (*p)[];

指针数组

形如 int *p[];

int arr[8];/*一个有八个元素的整型数组*/
int* parr1[6];/*parr1是一个由6各元素的数组,每个元素类型是int*,是指针数组。*/
int(*parr2)[5];/*parr2是一个指针,指向一个数组,数组有5个元素,每个元素类型是是int.*/
int(*parr3[10])[5]; /*parr1是一个10个元素的数组,每个元素类型是int*,
是指针数组,该数组指针有5个元素,每个元素类型是int。*/

一维数组传参

void test (int arr[]);
void test (int * arr);
void test (int arr[size]);

一维指针数组传参

void test (int * arr[]);
void test (int * arr[size]);
void test (int ** arr);

二维数组传参

void test (int arr[][]);
void test (int (*arr)[]);
#include <stdio.h>

int main()
{
    int num1 = 10;
    double num2 = 10.5;
    num1 = 20;

    typedef int* INTPNT;
    int* pN1 = &num1;
    double* pN2 = &num2;
    INTPNT pN3 = &num1;

    printf("size of int: %d\n", sizeof(int));
    printf("size of int*: %d\n", sizeof(int*));
    printf("size of double*: %d\n", sizeof(double*));

    printf("pN1: %x\n", pN1);
    int* pN4 = (int*)0x61fdfc;
    *pN4 = 200;
    printf("num1: %d\n", num1);
    return 0;
}
//----------------------------------------//
输出:
size of int: 4
size of int*: 8
size of double*: 8
pN1: 62fdfc
num1: 200
void swap(int i, int j)
{
    int temp = i;
    i = j;
    j = temp;
    printf("i: %d, j: %d\n", i,j);
}
int main()
{
    int a = 10, b = 20;
    swap(a, b);
    printf("a: %d, b: %d\n", a,b);
    return 0;
}
//-----------------------------------//
void swap(int* i, int* j)
{
    int* temp = i;
    i = j;
    j = temp;
    printf("i: %d, j: %d\n", *i,*j);
}
int main()
{
    int a = 10, b = 20;
    swap(&a,&b);
    printf("a: %d, b: %d\n", a,b);
    return 0;
}
//-----------------------------------//
void swap(int* i, int* j)
{
    int temp = *i;
    *i = *j;
    *j = temp;
    printf("i: %d, j: %d\n", *i,*j);
}
int main()
{
    int a = 10, b = 20;
    swap(&a,&b);
    printf("a: %d, b: %d\n", a,b);
    return 0;
}
#include <stdio.h>

int main()
{
    int arr[5] = {10,20,30,40,50};
    //连续存放的相同数据类型的数
    //数组名,数组名是一个变量
    // []是一个运算符
    int* pArr = &arr[0];

    printf("arr[3] is: %d\n", arr[3]);
    printf("*(pArr+3) is: %d\n", *(pArr+3));

    printf("arr[3] is: %d\n", *(arr+3));

    printf("pArr[3] is: %d\n", pArr[3]);

    pArr = &arr[3];
    printf("*(pArr+1) is: %d\n", *(pArr+1));
    printf("*(pArr-1) is: %d\n", *(pArr-1));
    printf("pArr[1] is: %d\n", pArr[1]);
    printf("pArr[-1] is: %d\n", pArr[-1]);

    printf("arr[-1] is: %d\n", arr[-1]);
    //-----------------------//
    int* pArr1;
    pArr1 = (int*) malloc(5*sizeof(int));

    pArr[3] = 210;
    printf("pArr[3] is: %d\n", *(pArr1+3));

    *(pArr1+0) = 450;
    printf("*pArr is: %d\n", *pArr1);

    free(pArr1);
    return 0;
}
//--------------------------------------//
输出:
arr[3] is: 40
*(pArr+3) is: 40
arr[3] is: 40
pArr[3] is: 40
*(pArr+1) is: 50
*(pArr-1) is: 30
pArr[1] is: 50
pArr[-1] is: 30
arr[-1] is: 0
pArr[3] is: 0
*pArr is: 450
#include <stdio.h>
void func1(int arr[])
{
    //
    arr[3] = 2000;
    printf("1: arr[3] is: %d\n", arr[3]);
}
void func2(int* pArr)
{
    pArr[3] = 200;
    printf("2: pArr[3] is: %d\n", pArr[3]);
}int main()
{
    int arr[5] = {10,20,30,40,50};
    //连续存放的相同数据类型的数
    //数组名,数组名是一个变量
    // []是一个运算符
    func2(arr);
    printf("main1: arr[3] is: %d\n", *(arr+3));

    func1(arr);
    printf("main2: arr[3] is: %d\n", *(arr+3));

    int* pArr;
    pArr = (int*) malloc(5*sizeof(int));

    pArr[3] = 210; //按索引取值运算符

    printf("pArr[3] is: %d\n", *(pArr+3));

    *(pArr+0) = 450;
    *pArr = 1450;
    printf("*pArr is: %d\n", *pArr);

    free(pArr);

    int a = 500;
    int* p = &a;
    int** p2 = &p; //char**
    *p = 5000;
    return 0;
}

//------------------------------//
输出:
2: pArr[3] is: 200
main1: arr[3] is: 200
1: arr[3] is: 2000
main2: arr[3] is: 2000
pArr[3] is: 210
*pArr is: 1450
#include <stdio.h>

void func3(int (*p3)[3])
{
    printf("11 is: %x\n",p3);
    printf("12 is: %x\n",&p3);

}


void func4(int arr[][3])
{
    printf("13 is: %x\n",arr);
    printf("14 is: %x\n",&arr);
}
int main()
{
    int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}};
    int arr2[4][3]={{1,2,3},
                    {4,5,6},
                    {7,8,9},
                    {10,11,12}};

    int* pArr = &arr[0][0];
    printf("1: pArr[7] is: %d\n", pArr[7]);

    int (*pArr2)[3];
    pArr2 = arr;
    printf("2: pArr2[1][1] is: %d\n", pArr2[1][1]);
    printf("3: *((pArr2+1)+1) is: %d\n", *(*(pArr2+1)+1));

    int (*pArr3)[4];
    pArr3 = arr;
    printf("4: pArr3[1][1] is: %d\n", pArr3[1][1]);
    printf("5: *((pArr3+1)+1) is: %d\n", *(*(pArr3+1)+1));

    int* pArr4[3];

    int a = 10, b = 20, c = 30;
    pArr4[0]=&a;
    pArr4[1]=&b;
    pArr4[2]=&c;

    printf("6: *(pArr4[1]) is: %d\n", *(pArr4[1]));
    printf("7: *(pArr4[1]) is: %d\n", *(*(pArr4+1)));

    int** ppArr = malloc(3*sizeof(int*));

    ppArr[0]=pArr2;
    ppArr[1]=pArr2+1;
    ppArr[2]=pArr2+2;

    printf("8: ppArr[1][1] is: %d\n", ppArr[1][1]);

    free(ppArr);
    func3(arr);
    func4(arr);

    return 0;
}
//-------------------------------------------------//
输出:
1: pArr[7] is: 8
2: pArr2[1][1] is: 5
3: *((pArr2+1)+1) is: 5
4: pArr3[1][1] is: 6
5: *((pArr3+1)+1) is: 6
6: *(pArr4[1]) is: 20
7: *(pArr4[1]) is: 20
8: ppArr[1][1] is: 5
11 is: 62fdd0
12 is: 62fd50
13 is: 62fdd0
14 is: 62fd50

(12条消息) C语言——指针_小浩终会上岸的博客-CSDN博客

字符串

strlen

原型:strlen( const char string[] );

原理:由char数组的头指针扫到第一个'\0'的位置。

strcpy

原型:strcpy(char destination[], const char source[]);

strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*

strncpy

原型:strncpy(char destination[], const char source[], int numchars);
功能:将字符串source中前numchars个字符拷贝到字符串destination中,但依然只取到第一个'\0'的位置。

strcat

原型:strcat(char target[], const char source[]);
功能:将字符串source接到字符串target的后面

strncat

原型:strncat(char target[], const char source[], int numchars);
功能:将字符串source的前numchars个字符接到字符串target的后面,但依然只取到第一个'\0'的位置。

#include<stdio.h>
#include <string.h>
int main()
{
    char s1[10] = "111111111";
    char s2[10] = "222222";
    int n = strlen(s1);
    strcpy(s1,s2);
    int i;
    for(i = 0;i < n;i ++)printf("%c",s1[i]); 
     return 0;
}
    char chArr3[] = {'h', 'e', 'l ', 'l', 'o', '\0'}; //"hello"
    char chArr4[] =   "hello";  //strlen();
    char* pArr12 = "hello";
    printf("11: chArr4 is: %c\n", chArr4[3]);
    printf("12: chArr3 is: %c\n", chArr3[3]);

    int arr10[] = {10,20,30,40,50};
    printf("13: arr10[3] is: %d\n", arr10[3]);
    arr10[10]=175;
    printf("14: arr10[10] is: %d\n", arr10[10]);
    //---------------------------------//
    输出:
    11: chArr4 is: l
    12: chArr3 is: l
    13: arr10[3] is: 40
    14: arr10[10] is: 175

C语言字符串操作总结大全(超详细)_C 语言_脚本之家

函数指针

#include <stdio.h>

int addition(int a, int b)
{
    return (a+b);
}
int sub(int a, int b)
{
    return (a-b);
}
int mult(int a, int b)
{
    return (a*b);
}

void printHello(void)
{
    printf("Hello World\n");
}

int main(int argc, char** args)
{


    int (*pAdd)(int, int) = &addition;

    printf("0:pAdd is %x\n", pAdd);

    int d = (*pAdd)(5, 10);

    int (*pAdd2)(int, int);
    pAdd2 = 0x401530;
    int c = pAdd2(5, 10);

    void (*p4)(void) = printHello;
    p4();

    void* pAdd3;

    pAdd3 = 0x401530;
    int e = ((int (*)(int,int))pAdd3)(5, 10);

    printf("1:c is %d\n", c);
    printf("2:d is %d\n", d);
    printf("3:e is %d\n", e);

    pAdd3 = p4;
    ((void (*)(void))pAdd3)();

//       int (*pAdd)(int, int) = &addition;

    //menu 菜单
    int (*pArr[3])(int, int);

    pArr[0] = addition;
    pArr[1] = sub;
    pArr[2] = mult;

    printf("4:result is %d\n", (pArr[2])(10,5));

    return 0;
}
//---------------------------------------------------//
输出:
0:pAdd is 401530
Hello World
1:c is 15
2:d is 15
3:e is 15
Hello World
4:result is 50

https://mp.weixin.qq.com/s?__biz=Mzg5MjAxNzEyMg==&mid=2247484349&idx=1&sn=624a71a0daf277e53367783145c9735b&chksm=cfc5c330f8b24a26e31daff659e53ed28d151d35e888d4376ec0b2083c414ced3432b8f51b91&token=1556295401&lang=zh_CN#rd

struct & union

struct

对于位段结构,编译器会自动进行存储空间的优化,主要有这几条原则:

1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。(在VC中位段存储单元的大小是4字节).

2)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;

内存对齐:

int 4byte , char 1byte , double 8 byte , float 4 byte , short 2byte , long 4byte,

long long 8byte(win32或64位机器下),(win64位机器下指针为8byte,32位机器下为4byte)

以结构体下最大成员长度进行对齐。如果结构体内部的数据成员也是一个结构体,这种情况下内部的结构体不会被看作一个整体,而是以内部结构体当中最大元素的大小作为判断依据

#include <stdio.h>

struct DATE
{
    int year;
    int month;
    int day;
} *dp;


typedef struct
{
    int year;
    int month;
    int day;
} MDATE;


struct
{
    int year;
    int month;
    int day;
} d0 = {2022, 4, 25};

struct
{
    int year;
    int month;
    int day;
} *dp2;

struct DATE2
{
    char year;
    char month;
    int day;
} d2;

struct DATE3
{
    char year;
    int month;
    char day;

} d3;


int main(int argc, char** args)
{

    struct DATE d1 = {2022, 4, 25};
    MDATE d5 = {2022, 4, 25};
    dp = &d1;
    dp2 = &d0;

    printf("0:month is %d\n", dp2->month);
    printf("1:year is %d\n", dp->year);
    printf("2:sizeof(d2) is %d\n", sizeof(d2));
    printf("3:sizeof(d3) is %d\n", sizeof(d3));
    return 0;
}
//------------------------------------//
输出:
0:month is 4
1:year is 2022
2:sizeof(d2) is 8
3:sizeof(d3) is 12

union

union大小为最大成员长度。

#include<stdio.h>  
union var{  
        char c[4];  
        int i;  
};  

int main(){  
        union var data;  
        data.c[0] = 0x04;//因为是char类型,数字不要太大,算算ascii的范围~  
        data.c[1] = 0x03;//写成16进制为了方便直接打印内存中的值对比  
        data.c[2] = 0x02;  
        data.c[3] = 0x11;  
//数组中下标低的,地址也低,按地址从低到高,内存内容依次为:04,03,02,11。总共四字节!  
//而把四个字节作为一个整体(不分类型,直接打印十六进制),应该从内存高地址到低地址看,0x11020304,低位04放在低地址上。  
        printf("%x\n",data.i);  
}
//------------------------------//
11020304  
static union { 
    char c[4]; 
    unsigned long l; 
}endian_test = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.l)

C语言结构体详解

C语言结构体指针(指向结构体的指针)详解

指向结构体数组的指针_ahyo的博客-CSDN博客_指向结构体数组的指针

C语言柔性数组讲解 - veis - 博客园

C语言联合体(union)的使用方法及其本质-union_si_zhou_qun_84342712的博客-CSDN博客

C语言 位段的详细介绍_C 语言_脚本之家

什么是大小端?如何确定大小端?_wwwlyj123321的博客-CSDN博客_大小端

内存管理

malloc

如果分配成功:则返回指向被分配内存空间的指针;
不然返回指针NULL。

malloc需要我们自己计算字节数,并且返回的时候要强转成指定类型的指针。

int *p;
p = (int *)malloc(sizeof(int));

new

new返回指定类型的指针,并且可以自动计算所需要的大小。

int *p;
p = new int;//返回类型为int* ,分配的大小是sizeof(int)
p = new int[100];//返回类型是int*类型,分配的大小为sizeof(int)*100

内存分配函数及使用注意事项,C语言内存分配函数完全攻略

【c语言】malloc函数详解_Billy12138的博客-CSDN博客_malloc函数

malloc函数实现原理!_YEDITABA的博客-CSDN博客_malloc 的实现原理

如何实现一个malloc函数 - amanlikethis - 博客园

File

C语言文件操作详解 - 扫驴 - 博客园

c语言_文件操作_FILE结构体解释_涉及对操作系统文件FCB操作的解释_ - 二郎那个三郎 - 博客园

define

## 连接操作符

int n = Conn(123,456);
     ==> int n=123456;
char* str = Conn("asdf", "adf");
     ==> char* str = "asdfadf";

#@ 字符化操作符

char a = ToChar(1);
     ==> char a='1';
char a = ToChar(123);
     ==> char a='3';

但是如果参数超过四个字符,编译器就给报错了。

# 字符串化操作符

#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)
     ==> "foo"
xstr (foo)
     ==> xstr (4)
     ==> str (4)
     ==> "4"

\ 行继续操作

VA_ARGS

__VA_ARGS__宏用来接受不定数量的参数。

#define eprintf(...) fprintf (stderr, __VA_ARGS__)

eprintf ("%s:%d: ", input_file, lineno)
    ==>  fprintf (stderr, "%s:%d: ", input_file, lineno)

当__VA_ARGS__宏前面##时,可以省略参数输入。

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

eprintf ("success!\n")
    ==> fprintf(stderr, "success!\n");

【C基础】#define宏定义中的#,##,@#,\ 这些符号的神奇用法_freeWayWalker的博客-CSDN博客_宏定义中##

C语言的宏总结_RoyKuang07的博客-CSDN博客

C语言预处理命令总结大全 :宏定义 - 西贝了爷 - 博客园

C语言中宏定义(#define)时do{}while(0)的价值 - 老码农 - 博客园

以下部分为C语言中的一些小知识点就不再过多阐述。

do{…}while(0)的意义和用法

do{...}while(0)的妙用 - 简书

Linux makefile 教程 非常详细,且易懂_liang13664759的博客-CSDN博客_linux makefile

Automake简介_ignorantshr的博客-CSDN博客_automake介绍

linux --> Autoconf和Automake使用 - 蚂蚁吃大象、 - 博客园

C语言位操作详解(全网最全)_小熊coder的博客-CSDN博客_c语言位操作

C语言基础 - 位操作用法总结_yunfan188的博客-CSDN博客_c语言中置位作用

C++

引用 &

在c++中 &不再是地址运算符,而是类型标识符的一部分。

C++中引用(&)的用法和应用实例_qingkongyeyue的博客-CSDN博客

C++:引用作为返回值_duhengqi的博客-CSDN博客_返回值引用

const

常量指针和指向常量的指针

int * const p = 1;
const int *p = 1;
const int* const p = 1;

(一)表示p本身是一个const,所以p所指的地址不会变,但是地址里的值是可以修改的。

(二)则是地址的值是不可修改的,而p是可以变的。

(三)则是两者都不可变。

类相关const

const修饰成员函数,则该成员函数不能修改类中任何非const成员函数。const成员函数不被允许修改它所在对象的任何一个数据成员。const成员函数能够访问对象的const成员,而其他成员函数不可以。

class A{
    void function() const;
}

const修饰类对象/对象指针/对象引用, const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。

constexper

const 和 constexpr 变量之间的主要区别在于:const 变量的初始化可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化。所有 constexpr 变量均为常量,因此必须使用常量表达式初始化。所以constexper的运行效率也会更高一些。

关于C++ const 的全面总结_Eric_Jo的博客-CSDN博客_c++const

C++中const和引用修饰变量和函数的总结_哈乐笑的博客-CSDN博客

friend & operator

C++ 中重载运算符 “<” 及 friend属性 - 时光回眸 - 博客园 (cnblogs.com)

C++中友元详解-zhm_sunboy-ChinaUnix博客

C++中友元类使用场合_江荣波的博客-CSDN博客

C++ 重载运算符和重载函数 | 菜鸟教程

C++ 仿函数_恋喵大鲤鱼的博客-CSDN博客_c++ 仿函数

逗号运算符的重载_肖火柴的博客-CSDN博客

【C++】 深入探究 new 和 delete_codedoctor的博客-CSDN博客

关于c++ new操作符的重载_selfsongs的博客-CSDN博客_c++ 重载new

class

构造函数 & 析构函数

此处注意是引用还是拷贝,具体例子可以见下列博客。

继承

多继承

虚拟继承

多态

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定

纯虚函数 形如virtual function() = 0 。以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。

接口(抽象类)

C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。

如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的。

设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。

因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。

C++:类的构造函数和析构函数_陈小默cxm的博客-CSDN博客

C++ 构造函数、析构函数、拷贝构造、赋值运算符 - 冷豪 - 博客园

C++子类的构造、析构和拷贝函数_m0_37622246的博客-CSDN博客_子类的拷贝构造函数

C++ 中的嵌套类和局部类_liyuanbhu的博客-CSDN博客_c++ 嵌套类

C++之enum枚举量声明、定义、使用与枚举类详解_Bruce_0712的博客-CSDN博客_c++ enum 定义

C++嵌套类与局部类详细解析_C 语言_脚本之家

C++ 多态 | 菜鸟教程 (runoob.com)

namespace

C++ 命名空间namespace_touzani的博客-CSDN博客_c++名称必须是命名空间名

C++ 名字空间详解_恋喵大鲤鱼的博客-CSDN博客

template

C++模板(c++ primer)_ZenZenZ的博客-CSDN博客

C++模板总结_Dream_yz的博客-CSDN博客_c++模板

c++模板类(一)理解编译器的编译模板过程_look01的博客-CSDN博客

C++模板template用法总结_清城无雪的博客-CSDN博客_c template

C++类模板(模板类)与友元详解

STL

STL教程:C++ STL快速入门(非常详细)

C++:STL标准入门汇总 - 施杨 - 博客园

C++ STL中容器的使用全面总结_jimofanhua0000的博客-CSDN博客_容器c++

深入解析C++ STL中的常用容器_渴望可及的博客-CSDN博客_c++ 容器

Boost C++ 库 中文教程(全) - DoubleLi - 博客园

https://www.boost.org/

C++ STL之vector用法总结 - 清水汪汪 - 博客园

c++ STL的list用法总结_小拳头的博客-CSDN博客_stl的list

C++中的STL中map用法详解 - Boblim - 博客园

STL中的Pair方法详解_LzyRapX的博客-CSDN博客_pair构造函数

C++ STL set容器常用用法_CerberuX的博客-CSDN博客_c++ set容器

C++标准模板库(STL)迭代器的原理与实现_wutao02的博客-CSDN博客_stl迭代器

【C++ STL】算法 <algorithm>中各种算法解析_小田的博客-CSDN博客

C++_STL_algorithm(算法)_wanghairong2015的博客-CSDN博客

【C++】智能指针详解_Billy12138的博客-CSDN博客_智能指针

C++ string的用法和例子_红鲤鱼遇绿鲤鱼的博客-CSDN博客_stringc++

【C++】STL常用容器总结之十二:string类_长相忆兮长相忆的博客-CSDN博客_string容器

C++11新特性--Unicode支持 - 简书

STL之仿函数实现详解_有时需要偏执狂的博客-CSDN博客_stl 仿函数

异常

throw

throw .....;//抛出一个异常
throw ;//重抛出异常

catch

如果执行try语句抛出异常,则在catch子句中搜索相应的异常处理代码,异常类型的匹配规则为:

  • 被抛出异常的类型与catch子句声明的类型相同。
  • 被抛出异常的类型是catch子句声明的类型子类型。(public dereived)

引用类型的异常只会在最后一次引用处析构结束。

C++ 异常处理 | 菜鸟教程

深入理解C++异常_waponx的博客-CSDN博客

[C++]详解异常处理(Exception Handling) 及标准库异常处理类_stary_yan的博客-CSDN博客

C++异常机制的实现方式和开销分析_leonardWang的博客-CSDN博客

posted @ 2022-06-14 10:44  wtz2333  阅读(223)  评论(0)    收藏  举报