NDK学习之路之 c++ 知识归纳

1.c++ 引用

其实就是四驱模型的拷贝,引用其实是地址赋值,可以看成同一块内存的另外一个变量
以两个变量值交换为例

#include<stdio.h>
void swap(int &number1, int &number2) {
    // &number 此处相当于同一块内存 取了另一个别名
    int temp = number1;
    number1 = number2;
    number2 = temp;
}
void main() {
    int number1 = 10;
    int number2 = 20;
    swap(number1, number2);
    printf("%d  %d\n", number1, number2); // 结果 20 10
    getchar();
}

2.常量指针和指针常量

常量变量:被常量修饰的变量,不能再次被赋值 (Java)

常量指针:const 在 * 之前,指针的地址是可以被再次赋值的(可以修改的),指针地址上面的值(变量)是不能被修改的,常量指针的常量是不能被改变的。

指针常量:const 在 * 之后,指针的地址是不可以被再次赋值的(不可以修改的),指针地址上面的值(变量)能被修改的,指针常量的指针地址是不能被改变的。

// 常量,不能去修改
    const int number = 100;
    // number = 200;   // error

    int number1 = 100;
    int number2 = 200;

    // 常量指针
    // int const * n_p = &number2;
    // n_p = &number1;
    // printf("n_p = %p",n_p); // 地址是可以重新被赋值的 
    // *n_p = 300; // 值是不能改的 error

    // 指针常量
    int * const n_p = &number2;
    // n_p = &number1; // 地址是不能被重新赋值
    *n_p = 300;
    printf("number2 = %d", number2);// 值可以被修改,结果:300

3.malloc,free,new,delete 区别

malloc/free 一对,new/delete 是一对

malloc/free 不会去调用构造函数和析构函数

new/delete 会去调用构造函数和析构函数
如果用了new,一定要记得 delete 释放内存

4.构造函数、析构函数和拷贝构造函数

直接上代码说明

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

using namespace std;

class Student
{
public:
    // 构造函数
    Student(){// 空参数构造函数
        cout << "空参数构造函数"<< endl;
    }

    // Student(char* name):age(0){// 一个参数构造函数, 相当于 this->age = 0
    //  cout << "一个参数构造函数" << endl;
    //  this->name = name;
    // }

    Student(char* name) :Student(name,0){
     // 调用两个参数的构造函数
     // 注意:先会调用两个参数的构造函数,然后才会执行当前构造函数
     cout << "一个参数构造函数" << endl;
    }

    Student(char* name, int age){// 两个参数构造函数
        cout << "两个参数构造函数" << endl;
        this->name = (char*)malloc(sizeof(char)*100);
        strcpy(this->name,name);
        this->age = age;
    }

    // 2. 析构函数,如果有在对象内部开辟堆内存,可以在析构函数中释放内存
    ~Student(){
        cout << "析构函数" << endl;
        // 对象被回收的时候会被调用
        // 释放内存
        free(this->name);
        this->name = NULL;
    }

    /*
    4.拷贝构造函数,在 java 中如果 Student stu2 = stu1,那么我们一般会认为 stu2 对象和 stu1 对象是同一个对象,
    但是在 c++ 中这种认为就是错误的,我们可以分别打印 stu1 和 stu2 的地址发现并不相等,
    所以 stu1 和 stu2 并不是同一个对象,而是会调用拷贝构造函数。*/
    // 对象会有一个默认的拷贝构造函数,用来对象之间的赋值
    Student(const Student& stu){// 常量的引用
        cout << "拷贝构造函数" << endl;
        // this->name = stu.name;// 浅拷贝
        // 如果动态开辟内存,一定要采用深拷贝
        this->name = (char*)malloc(sizeof(char)* 100);
        strcpy(this->name, stu.name);
        this->age = stu.age;
    }
    
    Student getStudent(char* name){
    Student stu(name);// 栈 ,方法执行完,这个对象会被回收,但是发现调用了拷贝构造函数
    cout << &stu << endl;
    return stu;// 会返回一个新的 Student 对象,而栈内开辟的 stu 是会被回收
}


void printStudent(Student stu){// stu 是该方法栈中一个新的对象,拷贝构造函数赋值,方法执行完会调用析构函数
    cout << stu.getName() << " , " << stu.getAge() << endl;
}

void main(){
    // 1. = 会调用拷贝构造函数
    // Student stu1("Darren", 24);
    // Student stu2 = stu1; // = 是赋值,把里面所有定义的属性赋值,c/c++ 编译器帮我们做的,其实会调用对象的拷贝构造

    // Student stu2;// 声明变量,开辟变量内存
    // stu2 = stu1; // 这个不会去调用拷贝构造函数,但是会赋值 c 的类似

    // 2. 第二种场景 作为参数返回的时候会调用拷贝构造函数
    // Student stu = getStudent("Jack");
    // cout << &stu << endl;

    // 3. 第三种场景 作为参数传递的时候会调用拷贝构造函数
    // Student stu("Darren", 24);
    // printStudent(stu);

    // 知识的补充
    Student stu = getStudent("Jack");

    // cout << stu.getName() << " , " << stu.getAge() << endl;

    printStudent(stu);

    getchar();
}

private:
    int age;
    char* name;
 
public:
    int getAge(){
        return this->age;
    }

    char* getName(){
        return this->name;
    }

    void setAge(int age){
        this->age = age;
    }

    void setName(char* name){
        this->name = name;
    }
};

5.内存四驱模型

在 c/c++ 中我们将运行时数据,分为四个区域分别是:栈区,堆区,数据区,代码区。我们详细来介绍下:

  • 栈区:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
  • 堆区:一般由程序员分配释放, 若程序员不释放,程序结束时可能由 OS 回收。
  • 数据区:存放全局变量、静态变量和常量字符串等等。 程序结束后由系统释放。
  • 存放函数体的二进制代码。

6.可变参数

#include <iostream>
#include <stdarg.h>
using namespace std;

int sum(int count, ...) {  // 格式:count代表参数个数, ...代表n个参数
    va_list ap;  // 声明一个va_list变量
    va_start(ap, count);  // 第二个参数表示形参的个数

    int sum = 0;
    for (int i = 0; i < count; i++) {
        sum += va_arg(ap, int);   // 第二个参数表示形参类型
    }
    va_end(ap);  // 用于清理
    return sum;

}
void main(){
    int sumValue = sum(3,8,10,9);
    cout << sumValue << endl;   // 输出结果:27
    getchar();
}

步骤:

  1. 定义头文件 stdarg.h

  2. 定义参数:参数格式 (int count, ...)

  3. 函数定义中创建一个 va_list 变量

  4. 初始化: va_start(ap, count);

  5. 循环将各个参数进行相加

  6. 清理:调用清理 va_end(va_list); 清理内容,最后调用

7.static 关键字

  1. 静态属性在 c++ 中必须要初始化
class Test {
    public static int tag;
}
int test = Test::tag = 1;   // 或在定义 tag 的时候赋值初始化

8.C++程序在内存中的分布

  1. 栈(Stack):局部变量,函数参数等存储在该区,由编译器自动分配和释放.栈属于计算机系统的数据结构,进栈出栈有相应的计算机指令支持,而且分配专门的寄存器存储栈的地址,效率很高,内存空间是连续的,但栈的内存空间有限。
  2. 堆(Heap):需要程序员手动分配和释放(malloc,free),属于动态分配方式。内存空间几乎没有限制,内存空间不连续,因此会产生内存碎片。操作系统有一个记录空间内存的链表,当收到内存申请时遍历链表,找到第一个空间大于申请空间的堆节点,将该节点分配给程序,并将该节点从链表中删除。一般,系统会在该内存空间的首地址处记录本次分配的内存大小,用于 free 释放该内存空间。
  3. 全局/静态存储区:全局变量,静态变量分配到该区,到程序结束时自动释放,包括 DATA 段(全局初始化段)与 BBS 段(全局未初始化段)。其中,初始化的全局变量和静态变量存放在 DATA 段,未初始化的全局变量和静态变量存放在 BBS 段。BBS 段特点:在程序执行前 BBS 段自动清零,所以未初始化的全局变量和静态变量在程序执行前已经成为 0.
  4. 文字常量区:存放常量,而且不允许修改。程序结束后由系统释放。
  5. 程序代码区:存放程序的二进制代码
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 几种语言的特性 汇编程序:将汇编语言源程序翻译成目标程序编译程序:将高级语言源程序翻译成目标程序解释程序:将高级语...
    囊萤映雪的萤阅读 2,840评论 1 5
  • 第一天 一.内联函数(inline) 函数调用的时候需要建立栈内存环境,进行参数传递,并产生程序执行转移,这些工作...
    陈果123阅读 1,112评论 0 1
  • 内存分类 在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈:在执行函数...
    码哥说阅读 497评论 0 3
  • 这几天有朋友反映给小编说让多发点关于面试的文章,小编深知从事IT行业的难处,跳槽多,加班多,薪资不乐观,大多数朋友...
    诸葛青云999阅读 9,972评论 0 6
  • 1.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”? 答:首先,extern是C/C...
    曾令伟阅读 912评论 0 4