C/C++重要知识点总结

一、程序的在内存中的存储空间

(1)代码区:存放二进制代码的区域;

(2)文本常量区:a、字符串;b、const全局变量,而const局部变量存放在栈中;

(3)全局变量区(静态变量区):a、data(初始化区):存放已经初始化的的全局变量,static变量;

                                                      b、bbs(未初始化区):未初始化的全局变量,static变量,bbs段中数据默认初始化为0;

(4)栈:函数的参数,局部变量,返回值,向下生长;

(5)堆:由程序员控制的内存区域,向上生长。


二、字符串、数组、指针、引用

1、字符串与指针

             涉及到strcpy(),memcpy()函数原型的实现。参见:字符串的实现及代码

             函数的设计原则下面会具体谈到。


2、数组与指针

       静态数组:存放在全局变量区,栈区;而指针可以指向任何区域;运算优先级:[]、->、()、*依次递减。

   (1)数组指针   int  (*p)[10]       含义:一个指向数组的指针,也被称为行指针

   (2)指针数组   int   *p[10]         含义:一个存放指针变量的数组


3、二维数组与行指针

     例如:

      array[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
      int * p=array[0];

      二维数组array有四个行指针,分别为array[0],array[1],array[2],array[3],每个指针指向一个有3个元素的一维数组,如array[0]的3个元素为 array[0][0],array[0][1],array[0][2]。

      元素array[2][2]对应指针为:array+2*3+2,指针表示法为:*(array+2*3+2) , 下标表示法为:array[2*3+2] 。


4、指针与引用

       引用的使用要注意:

          (1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化);

(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL);

(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。


三、函数

1、函数与指针

     (1)指针函数: int  *fun(int , int)

     (2)函数指针: int  (*fun)(int,int)   

                                函数指针指向某个特定的函数类型,函数类型由其返回值以及形参表决定。

                例如:

char (*pFun)(int); 
char glFun(int a){ return 0;} 
void main() 
{ 
    pFun = glFun; 
    (*pFun)(2); 
}

             使用typedef

typedef char (*PTRFUN)(int); 
PTRFUN pFun; 
char glFun(int a){ return 0;} 
void main() 
{ 
    pFun = glFun; 
    (*pFun)(2); 
} 
 
  

2、函数的设计

      (1)函数形参:

                        const:防止形参改变

                       指针传递、引用传递、值传递、地址传递

     (2)返回值:不能返回栈内存的指针和引用

                       指针:链式表达式

                       引用:某些情况下高效

     (3)assert宏进行错误判断

四、内存管理

1、管理方式:

   (1)全局变量区:data、bbs

   (2)栈:静态分配、动态分配

             堆:动态分配

2、野指针,free()后的指针,要及时的赋值为NULL;

3、数组:

          静态数组:存放在全局变量区,栈区

          动态数组:堆区

4、用指针分配内存的方式:

    (1)要用二级指针

void GetMemory2(char **p, int num)
{
    *p = (char *)malloc(sizeof(char) * num);
}
void Test2(void)
{
    char *str = NULL;
    GetMemory2(&str, 100);  // 注意参数是 &str,而不是str
    strcpy(str, "hello");  
    cout<< str << endl;
    free(str); 
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>

     (2)指针函数

char *GetMemory3(int num)
{
    char *p = (char *)malloc(sizeof(char) * num);
    return p;
}
void Test3(void)
{
    char *str = NULL;
    str = GetMemory3(100); 
    strcpy(str, "hello");
    cout<< str << endl;
    free(str); 
}


五、class、struct

     首先要区分出声明、初始化、复制的区别。

1、类的成员:成员函数;成员变量

     sizeof一个类,只计算成员变量,而不计算成员函数,所有函数存放在独立于对象的存储空间

     对象调用成员函数时,直接调用静态成员函数对普通成员函数的调用,需要把自己的this指针传给函数以指明以哪个对象调用;

     所以用未初始化的指针调用静态成员函数、或者调用未使用任何成员变量的成员函数(即未用到this指针)

     另外,还要注意:

   (1)空类大小为1;

   (2)如果有虚函数,还要加上虚表指针。

2、访问控制

3、const、static、inline

      (1)const除了修饰变量、函数参数、返回值外,在C++中还可以用来修饰函数,称为const成员函数,它表示:常成员函数, 不改变对象的成员变量;在类内定义的成员函数默认是inlin型。

      (2)编译阶段进行类型检查。

4、构造函数:

        构造函数:a、函数名为类名,

                          b、可以有参数,也可以无参数,无返回值,

                          c、函数体可以为空,可以完成对栈、堆得初始化

                          d、只有给对象分配内存才调用构造函数

      (1)初始化列表:

            a、如果类存在继承关系,派生类必须在其初始化表里调用基类的构造函数;子对象只能在初始化表里被初始化;

            b、类的const常量只能在初始化表里被初始化,因为它不能在函数体内用赋值的方式来初始化;

            c、类中的引用成员变量只能在初始化表里被初始化。

             类的数据成员的初始化可以采用初始化表函数体内赋值两种方式,这两种方式的效率不完全相同。

       (2)不能为虚函数、不能包含虚函数

       (3)可以重载

       (4)默认构造函数:无参数、空函数体的构造函数,可以自己定义,也可以是编译系统自动生成的。

                在程序中声明一个没有使用初始值的对象时,系统自动调用默认构造函数创建该对象,当该对象为全局变量或static变量时,被初始化为0,           当该对象时局部变量时,值无意义。

       (5)拷贝构造函数:

         在以下三种情况下都会被自动调用:

               a、当用一个类对象去初始化该类的另一个对象时;

               b、当函数形参是类的对象,进行实参和形参结合时;

               c、当函数返回值为类的对象,函数执行完,返回对象时,调用拷贝构造函数,创建一个临时对象。

        默认拷贝构造函数

               如果一个类中没有定义拷贝构造函数,则系统自动生成一个默认拷贝构造函数。

5、析构函数:

        (1)可以声明、不能包含虚函数

        (2)无形参,无返回值,函数体内完成对象的清理:

                 A、栈对象,编译器自动清理。在函数执行结束时,自动调用

                 B、堆对象,new产生,必须手动清理,通常在析构函数中使用delete实现其析构

                 C、全局对象,构造时先调用构造函数,析构时也会调用析构函数,但是程序中看不到调用析构函数

对类的介绍分为这5个大部分,const、static用法请参考:类的说明


六、继承

1、sizeof

2、访问控制

3、const、static、inline

4、构造函数

5、析构函数


七、多态

1、重载:在同一个类中,要求函数的参数不同返回值可同可不同virtual可有可无

      注意与覆盖、隐藏的区别:

          覆盖:覆盖是虚函数实现的条件

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual关键字。

         隐藏:

(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数不能有virtual关键字。
或者:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数不同相同;
(4)基类函数可有、可不有virtual关键字。

2、虚函数

   1)实现机制

     a、类之间满足赋值兼容,public继承

     b、声明为虚函数

     c、成员函数调用、或者指针和引用访问虚函数

   2)纯虚函数、抽象类

     包含纯虚函数的类为抽象类,抽象类只能作为基类来派生新类,而不能说明抽象类的对象

  详细参考:一个例子说明虚函数


八、模板

       模板(Template)是一种强大的C++软件复用特性,通常有两种形式:函数模板和类模板。使用模板的好处在于,可以使程序员编写与类型无关的代码。

       函数模板和类模板可以是程序员只需制定一个单独的代码段,就可表示一整套称为函数模板特化的相关(重载)函数或是表示一整套称为类模板特化的相关的类。这种技术称为泛型程序设计(generic programming)。

     (1)函数模板针对仅参数类型不同的函数;类模板针对仅数据成员和成员函数类型不同的类。
       
       模板是一个类家族的抽象,它只是对类的描述,编译程序不为类模板(包括成员函数定义)创建程序代码,但是通过对类模板的实例化可以生成一个具体的类以及该具体类的对象。
     (2)函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定

     (3)编译时检查数据类型,保证了类型安全。



注:

static:(限定作用范围)

1、函数内:本函数内使用,值为上次函数内调用的值

2、模块内:本模块内使用,值为上次模块内的值


const:目的:阻止一个变量值改变(限定变量的值改变)

1、只读变量

2、定义时必须初始化

【类外const】

             const变量,也称为只读变量,定义时,必须初始化。编译阶段做到只读。C的范畴

             const对象, 只读对象,只能调用const型的成员,那么如何对这些成员进行初始化呢,答案是:初始化列表。C++范畴

【类内const】

             const成员变量:在类中其实只是声明这个变量为const型,初始化工作在构造函数的初始化列表中进行。

                                       不能再构造函数的函数体里对const变量进行赋值。

             const成员函数:只读成员函数,该函数不能修改该对象的成员变量

                              构造函数、析构函数中不能使用const成员函

【const与函数】

    const修饰形参,表示这个形参在改函数中不能进行修改。

    const修饰返回值,表示这个反回值不能修改。


sizeof:计算一个类型的大小



http://www.niftyadmin.cn/n/1568667.html

相关文章

fork,vfork和clone底层实现

fork,vfork,clone都是linux用来创建子进程的&#xff08;确切说vfork创造出来的是线程&#xff09;。 1.fork 创造的子进程复制了父亲进程的资源&#xff0c;包括内存的内容task_struct内容&#xff08;2个进程的pid不同&#xff09;。 int sys_fork(struct pt_regs *regs) {…

C库文件操作函数详解

C库文件操作标准库函数汇总&#xff1a;    文件的打开操作 fopen 打开一个文件    文件的关闭操作 fclose 关闭一个文件    文件的读写操作 fgetc 从文件中读取一个字符 fputc 写一个字符到文件中去    …

Source Insight与github的使用

最近在使用Source Insight查看一些源代码&#xff0c;使用github进行版本控制&#xff0c;在进行中文注释的时候&#xff0c;上传到github后&#xff0c;中午注释部分是乱码。原因是Source Insight一直没有对uft8有正面的支持&#xff0c;其默认编码方式为ANSI码。这算是SI的硬…

MFC+OpenCV打开摄像头

MFC中有两类线程&#xff0c;分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环&#xff0c;而用户界面线程有自己的消息队列和消息循环。 工作者线程没有消息机制&#xff0c;通常用来执行后台计算和维护任务&#xff0c;如冗长的计算过程&#…

如何修改调试OpenCV源码

有时候&#xff0c;直接调用OpenCV的接口并不能满足我们的需求&#xff0c;需要我们对源码及其算法进行修改。这里就介绍一下如何修改OpenCV的源码。首先&#xff0c;要用cmake编译一下OpenCV&#xff1b;然后&#xff0c;就是修改源码了&#xff1b;接着&#xff0c;配置新生成…

opencv中VideoCapture的使用——打开网络摄像头/图像序列

OpenCV中的VideoCapture不仅可以打开视频、usb摄像头&#xff0c;还可以做很多事&#xff0c;例如读取流媒体文件&#xff0c;网络摄像头&#xff0c;图像序列等。OpenCV如何读取usb摄像头可以参考本人的另外一篇&#xff0c;地址如下&#xff1a;点击打开链接 。本文介绍如何读…

光流法( Optical Flow Method)

在计算机视觉中&#xff0c;光流法即可用于运动目标检测&#xff0c;也可以用于目标跟踪。本文主要介绍光流法在运动目标检测和目标跟踪中的区别与联系。 1、光流与光流场 光流的概念最初是由 Gibson 于 1950 年首先提出来的。当人的眼睛观察运动物体时&#xff0c;物体的景象…

TCP/IP各层协议介绍

本文是对TCP/IP协议各层协议进行一个宏观的介绍&#xff0c;以及简单阐述了各层协议的功能。如下表所示。 一、网络层 1、IP协议&#xff1a;提供网络结点之间的报文传送服务&#xff1b; 2、ARP协议&#xff1a;实现IP地址向物理地址的映射&#xff1b; RARP协议&#xff1a;实…