C++笔记

0.背景

C++的出现主要是为了解决C语言在软件开发中的一些问题,使得程序设计更加高效、灵活和易于维护。以下是一些导致C++出现的背景和问题:
​
    面向对象编程:C语言虽然功能强大,但是在处理大型项目时,结构不够清晰,代码重用性和可维护性有限。C++引入了面向对象的编程思想,使得程序结构更加清晰,代码重用更容易。
    
    数据抽象:C语言中没有提供封装数据和行为的机制,导致数据容易被误用或者修改。C++引入了类和对象的概念,实现了数据抽象,使得数据更加安全。
​
    继承和多态:C语言中没有提供继承和多态的机制,导致代码复用性降低。C++通过继承和多态机制,使得代码结构更加灵活,可扩展性更强。
​
    模板:C语言中没有泛型编程的支持,导致很多算法和数据结构需要重复编写多个版本。C++引入了模板的概念,实现了泛型编程,提高了代码的复用性和效率。
​
总的来说,C++的出现是为了弥补C语言在软件开发中的不足,提高程序设计的效率和质量。

一、C++概述(了解)

C++起初也叫“c with clsss”,c++是对c的扩展,因此c++是C语言的超集。这意味着任何有效的c语言程序都是有效的c++程序。

c语言和c++语言的关系

c++语言是在C语言的基础上添加了 面向对象编程泛型编程 的支持。继承了C语言高效、简洁、快速和可移植的传统

  • C语言代表的过程性语言

  • c++在C语言基础上添加的类的面向对象语言

  • c++魔板支持的泛型编程

二、面向对象的三大特征(了解)

封装、继承、多态

三、命名空间(重点)

3.1.为什么要有命名空间

为了解决 多人合作时取重命名的标识符的 问题

命名空间是一种用来避免命名冲突的机制,它可以将代码划分为不同的作用域,使得相同名称的变量、函数或类可以在不同的命名空间中存在而不会发生冲突。

3.2.什么是命名空间

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
​
// 命名空间(只能定义在全局中)
namespace A{    // A是空间的名字
    int a;
    void func()
    {
​
    }
}
​
int main()
{
    return EXIT_SUCCESS;
}

在使用命名空间时,可以通过::操作符来访问特定命名空间中的变量、函数或类

3.3.命名空间的注意

  • 命名空间只能写在全局中

  • 命名空间可以 嵌套 命名空间

  • 命名空间是开放的,随时可以加入新成员,但是新成员只能在加入后使用

3.4. ::作用域运算符

1)使用::操作符访问全局变量

int a = 10;
int main()
{
    int a = 20;
    cout << "a:" << a << endl;      // 20
    cout << "::a:" << ::a <<endl;   // 10   
}

2)::操作符来访问特定命名空间中的变量、函数或类

A::$variable;
A::function();
A::Myclass myobject;

四、using声明和编译指令(重点)

  • using声明 :可以使命名空间中的指定的 标识符 能直接使用(类似python的from math import pi)。但是在该作用域内,不能重新定义一个相同的标识符

namsespace A
{
    int a = 10;
}
int main()
{
    cout << A::a << endl;   // 每次访问A中a时,都需要::
    // using声明后
    using A::a;
    cout << a << endl;  // 就可以直接使用了
}
  • using编译指令:让某个命名空间中的 所有标识符 可以直接使用(包括不需要的标识符)如果与局部名称冲突,则局部名称将覆盖名称空间中的名称,而编译器并不会发出警告。

namespace A
{
    int a = 10;
    int b = 20;
}
int main()
{
    using namespace A;
    cout << a << endl;  // 10
    cout << b << endl;  // 20
​
    int a = 100;        // 不会冲突
    cout << a << endl;  // 100(局部变量覆盖全局变量)
}

五、struct类型加强(重点)

  • c中定义结构体变量需要加上 struct 关键字,c++不需要。声明的时候一样要加struct,只不过不需要借助typedef来减少struct的书写

struct Make()
{
    int a;
    char str[64];
}
​
void test01()
{
    Make a; // 申请空间给结构体变量。没有加struct,不会报错
}
  • c中的结构体只能定义成员变量,不能定义成员函数,而c++都可以

    struct Make()
    {
        int a;
        void func()
        {
            cout << "func" << endl;
        }
    }

六、更严格的类型转换与三目运算符(了解)

6.1.更严格的类型转换

c++不能进行隐式转换数据类型,比C语言更严格

char *p = malloc(64);   // malloc返回的指针是(void*)隐式转换成char*。c可以运行,c++会报错
​
​
char *p = (char*)malloc(64);    // 都可以运行

6.2.三目运算符

  • 左值 和 右值概念
    ​
    在c++中可以放在赋值操作符左边的是左值,右边的是右值
    有些变量既可以当左值,也可以当右值
    左值为Lvalue,L代表Location,表示内存可以寻址,可以赋值
    右值为Rvalue,R代表Read,就是可以知道它的值
  • C语言的三目运算符 返回的是 三目运算符的结果的右值

int a = 10;
int b = 20;
a > b ? a : b   --> 返回的是20,而不是变量b
  • C++的三目运算符返回的是左值,是空间

int a = 10;
int b = 20;
​
a > b ? a : b = 100;    --> 返回的是变量b
cout << b << endl;      // b:100

七、C/C++的const(重点)

7.1.C语言

1)C语言的const修饰的变量都有空间

2)C语言的const修饰的全局变量具有外部链接属性

// 另一个c文件
const int c = 300;  // 定义一个全局变量c,有内存
​
// c文件
const int a = 10;   // 常量区,一旦初始化,不能修改
​
void test()
{
    // a = 200;     全局变量不能直接修改
    int *p = (int*)&a;
    // *p = 100;    全局变量不能间接(通过指针)修改
}
​
int main()
{
    const b = 20;
    // b = 200;     局部的const不能直接修改
    int *p = (int*)&b;
    *p = 100;       // 局部的const可以间接修改,此时b是100,打印b也是100
    
    extern const int c; //  C语言可以通过全局声明外部链接c
    printf("%d/n", c);  // 300
}

7.2.c++

7.2.1.c++const

1)C语言和c++的编译器不一样

c++编译器,在编译阶段,会把 const修饰的变量 换成 它的值(如果想禁止这种操作,用禁止优化:volatile

2)c++的const修饰的变量有时有空间,有时没有空间(发生常量折叠,且没有对变量进行取址操作)

3)c++的const修饰的全局变量具有内部链接属性

初始定义全局变量的时候加上extern 就变为外部链接属性

const int aa = 10;  // 没有内存
​
void test()
{
    // 发生了常量折叠
    cout << "aa=" << aa << endl;    // 在编译阶段,编译器:cout << "aa" << 10 << endl;(直接打印常量与打印变量时间不一样)
    // 这样做的好处是:节省内存和时间
}
​
int main()
{
    const int bb = 20;  // 栈区
    int *p = (int*)&bb; // 进行取址操作,所以有空间
    *p = 200;
    
    cout << "bb=" << bb << endl;    // 20
    // bb的值被修改成200.打印出20是因为编译器把这串代码改写成:cout << "bb=" << 20 << endl;
    
    cout << "*p=" << *p << endl;    // 200,bb确实被修改了
}
7.2.2.c++编译器不能优化的情况

1)如果用变量给const修饰的局部变量赋值,那么编译器不会优化

2)不能优化自定义数据类型

3)编译器是在编译阶段来优化数据

4)加上禁止优化:volatile

7.3.尽量用const替代#define

const 和 #define区别

1.define没有数据类型,const修饰的变量有数据类型,可以进行数据类型检查
​
2.const修饰的变量有作用域;define不重视作用域,只能在全局,不能限定常量的使用范围
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值